Incorporating community feedback in whetcwithdraw

- Adding Withdrawal Type in all Withdrawal events for ease of auditing
  of all actions taken.

- Reorder arguments so that they are always consistent. Also
  `percentage` is now renamed to `percentageWHG`. It makes more sense to
  ask users what percentage of their funds they would like to donate.

- Do not log events if `send()` fails

// The contract that allows DTH to withdraw funds that the white hat
// group has managed to retrieve.
//
// There are 3 ways to use the contract:
// 1. withdraw()
// 2. proxyWithdraw()
// 3. botWithdraw()
//
// For a description of each method, take a look at the docstrings.
//
// License: BSD3

contract DAOBalanceSnapShot {
    function balanceOf(address _dth) constant returns(uint);
    function totalSupply() constant returns(uint );
}

contract Owned {
    /// Prevents methods from perfoming any value transfer
    modifier noEther() {if (msg.value > 0) throw; _}
    /// Allows only the owner to call a function
    modifier onlyOwner { if (msg.sender != owner) throw; _ }

    address owner;

    function Owned() { owner = msg.sender;}

    function changeOwner(address _newOwner) onlyOwner {
        owner = _newOwner;
    }

    function getOwner() noEther constant returns (address) {
        return owner;
    }
}

contract WhitehatWithdraw is Owned {
    enum WithdrawType {
        DIRECT,
        PROXY,
        BOT,
        MANUAL
    }

    DAOBalanceSnapShot daoBalance;
    mapping (address => uint) paidOut;
    mapping (address => bool) certifiedDepositors;
    uint totalFunds;
    uint deployTime;
    address whg_donation;
    address bot;
    address escape;
    address remainingBeneficary;

    event Withdraw(address indexed dth, address indexed beneficiary, uint256  amount, uint256 percentageWHG, WithdrawType withdrawType);
    event CertifiedDepositorsChanged(address indexed _depositor, bool _allowed);
    event Deposit(uint amount);
    event EscapeCalled(uint amount);
    event RemainingClaimed(uint amount);

    function WhitehatWithdraw(address _whg_donation, address _daoBalanceSnapshotAddress, address _botAddress, address _escapeAddress, address _remainingBeneficiary) {
        whg_donation = _whg_donation;
        daoBalance = DAOBalanceSnapShot(_daoBalanceSnapshotAddress);
        bot = _botAddress;
        escape = _escapeAddress;
        remainingBeneficary = _remainingBeneficiary;

        totalFunds = msg.value;
        deployTime = now;

        // both the owner and the whitehat multisig can perform deposits to this contract
        certifiedDepositors[0x1ac729d2db43103faf213cb9371d6b42ea7a830f] = true;
        certifiedDepositors[msg.sender] = true;
    }

    /// Calculates the remaining funds available for a DTH to withdraw
    ///
    /// @param _dth          The address of the DAO Token Holder for whom
    ///                      to get the funds remaining for withdrawal
    /// @return              The amount of funds remaining for withdrawal
    function calculateWithdraw(address _dth) constant noEther returns(uint) {
        uint tokens = daoBalance.balanceOf(_dth);

        uint acumulatedReward = tokens * totalFunds / daoBalance.totalSupply();
        if (acumulatedReward < paidOut[_dth]) {
            return 0;
        }

        return acumulatedReward - paidOut[_dth];
    }

    /// The core of the withdraw functionality. It is called by all other withdraw functions
    ///
    /// @param _dth           The address of the DAO token holder for whom the
    ///                       withdrawal is going to happen
    /// @param _beneficiary   The address that will receive the _percentage of
    ///                       the funds corresponding to the _dth.
    /// @param _percentageWHG The percentage of the funds that will be donated to the
    ///                       White Hat Group. It should be a number ranging from 0
    ///                       to 100. Anything not claimed by the DTH will be going
    ///                       as a donation to the Whitehat Group.
    /// @param _withdrawType  method used to withdraw (1) Direct (2) Proxy (3) bot (4) owner
    function commonWithdraw(address _dth, address _beneficiary, uint _percentageWHG, WithdrawType _withdrawType) internal {
        if (_percentageWHG > 100) {
            return;
        }

        uint toPay = calculateWithdraw(_dth);
        if (toPay == 0) {
            return;
        }

        if (toPay > this.balance) {
            toPay = this.balance;
        }

        uint portionWhg = toPay * _percentageWHG / 100;
        uint portionDth = toPay - portionWhg;
        paidOut[_dth] += toPay;

        if ( !whg_donation.send(portionWhg) ||  !_beneficiary.send(portionDth) ) {
            throw;
        }

        Withdraw(_dth, _beneficiary,  toPay, _percentageWHG, _withdrawType);
    }

    /// The simple withdraw function, where the message sender is considered as
    /// the DAO token holder whose ratio needs to be retrieved.
    function withdraw(address _beneficiary, uint _percentageWHG ) noEther {
        commonWithdraw(msg.sender, _beneficiary, _percentageWHG, WithdrawType.DIRECT);
    }

    /// The proxy withdraw function. Anyone can call this for someone else as long
    /// as he includes signed data retrieved by using web3.eth.sign(address, hash).
    /// The DAO token holder whose ratio needs to be retrieved is determined by
    /// performing ecrecover on the signed data.
    function proxyWithdraw(address _beneficiary, uint _percentageWHG, uint8 _v, bytes32 _r, bytes32 _s) noEther {
        bytes32 _hash = sha3("Withdraw DAOETC to ", _beneficiary, _percentageWHG);
        address _dth = ecrecover(_hash, _v, _r, _s);
        commonWithdraw(_dth, _beneficiary, _percentageWHG, WithdrawType.PROXY);
    }

    /// The bot withdraw function is a function that only "the bot" can call.
    /// Once a user who does not use the ETC chain has used the bot withdraw the
    /// bot will use this function to perform withdrawal for that user.
    ///
    /// Bot Withdrawal is primarily for users who do not want to synchronize the ETC
    /// chain and would rather prove ownership in the ETH chain and provide a beneciary
    /// ETC address for the bot to withdraw to. This could allow for people to withdraw
    /// directly to an exchange's deposit address without sycnronizing the ETC chain.
    function botWithdraw(address _dth, address _beneficiary, uint _percentageWHG) noEther {
        if (msg.sender != bot) {
            throw;
        }
        commonWithdraw(_dth, _beneficiary, _percentageWHG, WithdrawType.BOT);
    }

    /// This is the only way to send money to the contract, adding to the total
    /// amount of ETH to be refunded.
    ///
    /// Only people who are considered certified depositors like the whitehat ETC multisig
    /// or addresses owned by exchanges should be able to deposit more ETC for withdrals.
    /// If you need to become a certified depositor please contact Bity SA.
    function deposit() returns (bool) {
        if (!certifiedDepositors[msg.sender]) {
            throw;
        }
        totalFunds += msg.value;
        Deposit(msg.value);
        return true;
    }

    /// Last Resort call, to allow for a reaction if something bad happens to
    /// the contract or if some security issue is uncovered.
    function escapeHatch() noEther onlyOwner returns (bool) {
        uint total = this.balance;
        if (!escape.send(total)) {
            throw;
        }
        EscapeCalled(total);
    }

    /// Allows the claiming of the remaining funds after a given amount of time
    /// Amount is set to 6 months for now but may still change in the future.
    function claimRemaining() noEther returns (bool) {
        if (now < deployTime + 24 weeks) {
            throw;
        }
        uint total = this.balance;
        if (!remainingBeneficary.send(total)) {
            throw;
        }
        RemainingClaimed(total);
    }

    function () { //no donations
        throw;
    }

    function getPaidOut(address _account) noEther constant returns (uint) {
        return paidOut[_account];
    }

    function getMyBalance(address _account) noEther constant returns (uint) {
        return daoBalance.balanceOf(_account);
    }

    function getTotalFunds() noEther constant returns (uint) {
        return totalFunds;
    }

    function getWHGDonationAddress() noEther constant returns (address) {
        return whg_donation;
    }

    function getBotAddress() noEther constant returns (address) {
        return bot;
    }

    function isCertifiedDepositor(address _depositor) noEther constant returns (bool) {
        return certifiedDepositors[_depositor];
    }

    function changeCertifiedDepositors(address _depositor, bool _allowed) onlyOwner noEther external returns (bool _success) {
        certifiedDepositors[_depositor] = _allowed;
        CertifiedDepositorsChanged(_depositor, _allowed);
        return true;
    }
}

// The contract that allows DTH to withdraw funds that the white hat
// group has managed to retrieve.
//
// There are 3 ways to use the contract:
// 1. withdraw()
// 2. proxyWithdraw()
// 3. botWithdraw()
//
// For a description of each method, take a look at the docstrings.
//
// License: BSD3

contract DAOBalanceSnapShot {
    function balanceOf(address _dth) constant returns(uint);
    function totalSupply() constant returns(uint );
}

contract Owned {
    /// Prevents methods from perfoming any value transfer
    modifier noEther() {if (msg.value > 0) throw; _}
    /// Allows only the owner to call a function
    modifier onlyOwner { if (msg.sender != owner) throw; _ }

    address owner;

    function Owned() { owner = msg.sender;}

    function changeOwner(address _newOwner) onlyOwner {
        owner = _newOwner;
    }

    function getOwner() noEther constant returns (address) {
        return owner;
    }
}

contract WhitehatWithdraw is Owned {
    /// The balances of the DTH taken in the snapshot block. TBD

    DAOBalanceSnapShot daoBalance;
    mapping (address => uint) paidOut;
    mapping (address => bool) certifiedDepositors;
    uint totalFunds;
    uint deployTime;
    address whg_donation;
    address bot;
    address escape;
    address remainingBeneficary;

    event Withdraw(address indexed dth, address indexed beneficiary, uint256  amountToDth, uint256 amountToWhg);
    event CertifiedDepositorsChanged(address indexed _depositor, bool _allowed);
    event Deposit(uint amount);
    event EscapeCalled(uint amount);
    event RemainingClaimed(uint amount);

    function WhitehatWithdraw(address _whg_donation, address _daoBalanceSnapshotAddress, address _botAddress, address _escapeAddress, address _remainingBeneficiary) {
        whg_donation = _whg_donation;
        daoBalance = DAOBalanceSnapShot(_daoBalanceSnapshotAddress);
        bot = _botAddress;
        escape = _escapeAddress;
        remainingBeneficary = _remainingBeneficiary;

        totalFunds = msg.value;
        deployTime = now;

        // both the owner and the whitehat multisig can perform deposits to this contract
        certifiedDepositors[0x1ac729d2db43103faf213cb9371d6b42ea7a830f] = true;
        certifiedDepositors[msg.sender] = true;
    }

    /// Calculates the remaining funds available for a DTH to withdraw
    ///
    /// @param _dth          The address of the DAO Token Holder for whom
    ///                      to get the funds remaining for withdrawal
    /// @return              The amount of funds remaining for withdrawal
    function calculateWithdraw(address _dth) constant noEther returns(uint) {
        uint tokens = daoBalance.balanceOf(_dth);

        uint acumulatedReward = tokens * totalFunds / daoBalance.totalSupply();
        if (acumulatedReward < paidOut[_dth]) {
            return 0;
        }

        return acumulatedReward - paidOut[_dth];
    }

    /// The core of the withdraw functionality. It is called by all other withdraw functions
    ///
    /// @param _percentage    The percentage of the funds that the DTH wants to keep
    ///                       for himself. It should be a number ranging from 0
    ///                       to 100. Anything not claimed by the DTH will be going
    ///                       as a donation to the Whitehat Group.
    /// @param _dth           The address of the DAO token holder for whom the
    ///                       withdrawal is going to happen
    /// @param _beneficiary   The address that will receive the _percentage of
    ///                       the funds corresponding to the _dth.
    function commonWithdraw(uint _percentage, address _dth, address _beneficiary) internal {
        if (_percentage > 100) {
            return;
        }

        uint toPay = calculateWithdraw(_dth);
        if (toPay == 0) {
            return;
        }

        if (toPay > this.balance)
            toPay = this.balance;

        uint portionDth = toPay * _percentage / 100;
        uint portionWhg = toPay - portionDth;
        paidOut[_dth] += toPay;

        if ( !whg_donation.send(portionWhg) ||  !_beneficiary.send(portionDth) ) {
            throw;
        }

        Withdraw(_dth, _beneficiary,  portionDth, portionWhg);
    }

    /// The simple withdraw function, where the message sender is considered as
    /// the DAO token holder whose ratio needs to be retrieved.
    function withdraw(uint _percentage, address _beneficiary) noEther {
        commonWithdraw(_percentage, msg.sender, _beneficiary);
    }

    /// The proxy withdraw function. Anyone can call this for someone else as long
    /// as he includes signed data retrieved by using web3.eth.sign(address, hash).
    /// The DAO token holder whose ratio needs to be retrieved is determined by
    /// performing ecrecover on the signed data.
    function proxyWithdraw(uint _percentage, address _beneficiary, uint8 _v, bytes32 _r, bytes32 _s) noEther {
        bytes32 _hash = sha3("Withdraw DAOETC to ", _beneficiary, _percentage);
        address _dth = ecrecover(_hash, _v, _r, _s);
        commonWithdraw(_percentage, _dth, _beneficiary);
    }

    /// The bot withdraw function is a function that the only "the bot" can call.
    /// Once a user who does not use the ETC chain has used the bot withdraw the
    /// bot will use this function to perform withdrawal for that user.
    ///
    /// Bot Withdrawal is primarily for users who do not want to synchronize the ETC
    /// chain and would rather prove ownership in the ETH chain and provide a beneciary
    /// ETC address for the bot to withdraw to. This could allow for people to withdraw
    /// directly to an exchange's deposit address without sycnronizing the ETC chain.
    function botWithdraw(uint _percentage, address _dth, address _beneficiary) noEther {
        if (msg.sender != bot) {
            throw;
        }
        commonWithdraw(_percentage, _dth, _beneficiary);
    }

    /// This is the only way to send money to the contract, adding to the total
    /// amount of ETH to be refunded.
    ///
    /// Only people who are considered certified depositors like the whitehat ETC multisig
    /// or addresses owned by exchanges should be able to deposit more ETC for withdrals.
    /// If you need to become a certified depositor please contact Bity SA.
    function deposit() returns (bool) {
        if (!certifiedDepositors[msg.sender]) {
            throw;
        }
        totalFunds += msg.value;
        Deposit(msg.value);
        return true;
    }

    /// Last Resort call, to allow for a reaction if something bad happens to
    /// the contract or if some security issue is uncovered.
    function escapeHatch() noEther onlyOwner returns (bool) {
        uint total = this.balance;
        escape.send(total);
        EscapeCalled(total);
    }

    /// Allows the claiming of the remaining funds after a given amount of time
    /// Amount is set to 6 months for now but may still change in the future.
    function claimRemaining() noEther returns (bool) {
        if (now < deployTime + 24 weeks) {
            throw;
        }
        uint total = this.balance;
        remainingBeneficary.send(total);
        RemainingClaimed(total);
    }

    function () { //no donations
        throw;
    }

    function getPaidOut(address _account) noEther constant returns (uint) {
        return paidOut[_account];
    }

    function getMyBalance(address _account) noEther constant returns (uint) {
        return daoBalance.balanceOf(_account);
    }

    function getTotalFunds() noEther constant returns (uint) {
        return totalFunds;
    }

    function getWHGDonationAddress() noEther constant returns (address) {
        return whg_donation;
    }

    function getBotAddress() noEther constant returns (address) {
        return bot;
    }

    function isCertifiedDepositor(address _depositor) noEther constant returns (bool) {
        return certifiedDepositors[_depositor];
    }

    function changeCertifiedDepositors(address _depositor, bool _allowed) onlyOwner noEther external returns (bool _success) {
        certifiedDepositors[_depositor] = _allowed;
        CertifiedDepositorsChanged(_depositor, _allowed);
        return true;
    }
}


The final Contract

The final Contract

pragma solidity ^0.4.4;

// ## Mattew - a contract for increasing "whaleth"
// README: https://github.com/rolandkofler/mattew
// MIT LICENSE 2016 Roland Kofler, thanks to Crul for testing

contract Mattew {
    address whale;
    uint256 stake;
    uint256 blockheight;
    uint256 constant PERIOD = 200; //60 * 10 /14; //BLOCKS_PER_DAY;
    uint constant DELTA = 0.1 ether;

    event MattewWon(string msg, address winner, uint value,  uint blocknumber);
    event StakeIncreased(string msg, address staker, uint value, uint blocknumber);

    function Mattew(){
        setFacts();
    }

    function setFacts() private {
        stake = msg.value;
        blockheight = block.number;
        whale = msg.sender;
    }

    /// The rich get richer, the whale get whaler
    function () payable{
        if (block.number - PERIOD > blockheight){
            bool isSuccess = whale.send(stake);
            MattewWon("Mattew won (mattew, stake, blockheight)", whale, stake, block.number);
            setFacts();
            // selfdestruct(whale); People with Ethereum Foundation are ok with it.
            return;

        }else{

            if (msg.value < stake + DELTA) throw;
            bool isOtherSuccess = msg.sender.send(stake);
            setFacts();
            StakeIncreased("stake increased (whale, stake, blockheight)", whale, stake, blockheight);
        }
    }

    function getStake() public constant returns(uint){
        return stake;
    }

    function getBlocksTillMattew() public constant returns(uint){
        if (blockheight + PERIOD > block.number)
            return blockheight + PERIOD - block.number;
        else
            return 0;
    }
}

pragma solidity ^0.4.4;

/**
 * ## Mattew - a contract for increasing "whaleth"
 *
 * The rich get richer,
 * the WHALE get WHALER
 * ╭━━━━━━━━╮┏━╮╭━┓
 * ┃┈┈┈┈┈┈┈┈┃╰╮╰╯╭╯
 * ┃╰╯┈┈┈┈┈┈╰╮╰╮╭╯┈
 * ┣━━╯┈┈┈┈┈┈╰━╯┃┈┈
 * ╰━━━━━━━━━━━━╯┈┈
 *
 * In sociology, the Matthew effect (or accumulated advantage)
 * is the phenomenon where "the rich get richer and the poor get poorer.
 * - https://en.wikipedia.org/wiki/Matthew_effect
 *
 * This contract helps with this process by rewarding the richest player.
 *
 * ### Description
 *
 * 1. A player sends ether to the contract address
 * 2a. If the amount is too low it fails
 * 2b. If the amount at least +1 ETH is higher than the STAKE
 *      and send within PERIOD since the last pay-in
 *      then the sender receives the last STAKE but pays in his STAKE.
 *
 *
 *                      1ΞΞΞΞΞΞΞΞΞ*Period over
 *              1ΞΞΞΞΞΞΞΞΞΞΞΞΞΞΞΞΞΞ
 *           2ΞΞΞΞΞΞΞΞΞΞΞΞΞΞΞΞΞΞΞΞΞ      1ΞΞΞΞΞΞΞΞΞ*Period over
 *           ΞΞΞΞΞΞΞΞΞΞΞΞΞΞΞΞΞΞΞΞΞΞ  1ΞΞΞΞΞΞΞΞΞΞΞΞΞ
 *      1ΞΞΞΞΞΞΞΞΞΞΞΞΞΞΞΞΞΞΞΞΞΞΞΞΞΞ1ΞΞΞΞΞΞΞΞΞΞΞΞΞΞΞ1ΞΞΞΞΞ...
 *
 *      Figure: The STAKE gets higher until nobody pays in for > PERIOD
 *
 * 2c. If the grace PERIOD is over and nobody increased the STAKE,
 *      the last STAKE wins all the Ether
 * 3. Contract gets destroyed Experiment over.
 *
 * MIT LICENSE 2016 Roland Kofler, thanks to Crul for testing
 **/

contract Mattew {
    address whale;
    uint256 stake;
    uint256 blockheight;
    uint256 constant BLOCKS_PER_DAY= uint256(60 * 60 * 24 /14);
    uint256 constant PERIOD = 20; //60 * 10 /14; //BLOCKS_PER_DAY;

    event MattewWon(string msg, address winner, uint value,  uint blocknumber);
    event StakeIncreased(string msg, address staker, uint value, uint blocknumber);

    function Mattew(){
        setFacts();
    }

    function setFacts() private {
        stake = msg.value;
        blockheight = block.number;
        whale = msg.sender;
    }

    /// The rich get richer, the whale get whaler
    function () payable{
        if (block.number - PERIOD > blockheight){
            bool isSuccess = whale.send(stake);
            MattewWon("Mattew won (mattew, stake, blockheight)", whale, stake, block.number);
            setFacts();
            selfdestruct(whale); //a gesture of responsibility
            return;

        }else{

            if (msg.value < stake + 1 ether) throw;
            bool isOtherSuccess = msg.sender.send(stake);
            setFacts();
            StakeIncreased("stake increased (whale, stake, blockheight)", whale, stake, blockheight);
        }
    }

    function getStake() public constant returns(uint){
        return stake;
    }

    function getBlocksTillMattew() public constant returns(uint){
        if (blockheight + PERIOD > block.number)
            return blockheight + PERIOD - block.number;
        else
            return 0;
    }
}


Add the Vote.end() method to shutdown the smart contract.

pragma solidity ^0.4.2;

contract Vote {

    event Ballot (
        address indexed voter,
        uint8 proposal
    );

    event VoterRegistered (
        address indexed voter
    );

    event VoteError (
        address indexed user,
        string message
    );

    struct Voter {
        bool registered;
        bool voted;
        uint8 vote;
    }

    mapping(address => Voter) voters;
    address chairperson;
    uint[] results;

    /* This unnamed function is called whenever someone tries to send ether to it */
    function () {
        throw; // Prevents accidental sending of ether
    }

    // Create a new vote with $(_numProposals) different results.
    function Vote(uint8 _numProposals) {
        chairperson = msg.sender;
        results.length = _numProposals;
    }

    modifier onlyChairPerson() {
        if (msg.sender != chairperson)
            throw;
        _;
    }

    modifier onlyRegisteredVoter() {
        Voter voter = voters[msg.sender];

        if (voter.voted || !voter.registered)
            throw;
        _;
    }

    function registerVoter(address voterAddress) onlyChairPerson {
        Voter voter = voters[voterAddress];

        if (voter.voted || voter.registered) {
            VoteError(voterAddress, 'already registered');
            throw;
        }

        voter.registered = true;

        VoterRegistered(voterAddress);
    }

    // Give a single vote to proposal $(proposal).
    function vote(uint8 proposal) onlyRegisteredVoter {
        Voter voter = voters[msg.sender];

        if (proposal >= results.length)
            return; // FIXME: emit a BallotError event

        voter.voted = true;
        voter.vote = proposal;
        results[proposal] += 1;

        Ballot(msg.sender, proposal);
    }

    function cancelVote() onlyRegisteredVoter {
        Voter voter = voters[msg.sender];

        results[voter.vote] -= 1;

        voter.voted = false;
    }

    function getVoteResults() constant returns (uint[]) {
        return results;
    }

    function end() onlyChairPerson {
        selfdestruct(chairperson);
    }
}

pragma solidity ^0.4.2;

contract Vote {

    event Ballot (
        address indexed voter,
        uint8 proposal
    );

    event VoterRegistered (
        address indexed voter
    );

    event VoteError (
        address indexed user,
        string message
    );

    struct Voter {
        bool registered;
        bool voted;
        uint8 vote;
    }

    mapping(address => Voter) voters;
    address chairperson;
    uint[] results;

    /* This unnamed function is called whenever someone tries to send ether to it */
    function () {
        throw; // Prevents accidental sending of ether
    }

    // Create a new vote with $(_numProposals) different results.
    function Vote(uint8 _numProposals) {
        chairperson = msg.sender;
        results.length = _numProposals;
    }

    modifier onlyChairPerson() {
        if (msg.sender != chairperson)
            throw;
        _;
    }

    modifier onlyRegisteredVoter() {
        Voter voter = voters[msg.sender];

        if (voter.voted || !voter.registered)
            throw;
        _;
    }

    function registerVoter(address voterAddress) onlyChairPerson {
        Voter voter = voters[voterAddress];

        if (voter.voted || voter.registered) {
            VoteError(voterAddress, 'already registered');
            throw;
        }

        voter.registered = true;

        VoterRegistered(voterAddress);
    }

    // Give a single vote to proposal $(proposal).
    function vote(uint8 proposal) onlyRegisteredVoter {
        Voter voter = voters[msg.sender];

        if (proposal >= results.length)
            return; // FIXME: emit a BallotError event

        voter.voted = true;
        voter.vote = proposal;
        results[proposal] += 1;

        Ballot(msg.sender, proposal);
    }

    function cancelVote() onlyRegisteredVoter {
        Voter voter = voters[msg.sender];

        results[voter.vote] -= 1;

        voter.voted = false;
    }

    function getVoteResults() constant returns (uint[]) {
        return results;
    }
}


forgot to remove a parameter from Interactive2.callJudge

pragma solidity ^0.4.16;

interface JudgeInterface {
    function judge(bytes32[13] res, uint q,
                        bytes32[] _proof,
                        bytes32 vm_, bytes32 op, uint[4] regs,
                        bytes32[10] roots, uint[4] pointers) public returns (uint);
    function judgeFinality(bytes32[13] res, bytes32[] _proof,
                        bytes32[10] roots, uint[4] pointers) public returns (uint);
}

contract Interactive2 {

    JudgeInterface judge;

    struct Record {
        address prover;
        address challenger;

        bytes32 start_state;
        bytes32 end_state;

        // Maybe number of steps should be finished
        uint256 steps;

        address winner;
        address next;

        uint256 size;
        uint256 timeout;
        uint256 clock;

        uint256 idx1;
        uint256 idx2;

        uint256 phase;

        bytes32[] proof;
        bytes32[13] result;

    }

    function Interactive2(address addr) public {
        judge = JudgeInterface(addr);
    }

    // perhaps they should be indexed by end state ?
    // Record[] records;
    mapping (bytes32 => Record) records;

    function testMake() public returns (bytes32) {
        return make(msg.sender, msg.sender, bytes32(123), bytes32(123),
                    10, 1, 10);
    }

    event StartChallenge(address p, address c, bytes32 s, bytes32 e, uint256 idx1, uint256 idx2,
        uint256 par, uint to, bytes32 uniq);

    function make(address p, address c, bytes32 s, bytes32 e, uint256 _steps,
        uint256 par, uint to) public returns (bytes32) {
        bytes32 uniq = keccak256(p, c, s, e, _steps, par, to);
        Record storage r = records[uniq];
        r.prover = p;
        r.challenger = c;
        r.start_state = s;
        r.end_state = e;
        r.steps = _steps;
        r.size = par;
        if (r.size > r.steps - 2) r.size = r.steps-2;
        r.timeout = to;
        r.clock = block.number;
        r.next = r.prover;
        r.idx1 = 0;
        r.idx2 = r.steps-1;
        r.proof.length = r.steps;
        r.proof[0] = s;
        r.proof[r.steps-1] = e;
        r.phase = 16;
        StartChallenge(p, c, s, e, r.idx1, r.idx2, r.size, to, uniq);
        return uniq;
    }

    event StartFinalityChallenge(address p, address c, bytes32 s, bytes32 e, uint256 step, uint to, bytes32 uniq);

    // Solver thinks this is a final state, verifier disagrees
    // Solver has to post a proof that the next instruction is the "EXIT" opcode
    function makeFinality(address p, address c, bytes32 s, bytes32 e, uint256 _steps, uint to) public returns (bytes32) {
        bytes32 uniq = keccak256(p, c, s, e, _steps, to);
        Record storage r = records[uniq];
        r.prover = p;
        r.challenger = c;
        r.start_state = s;
        r.end_state = e;
        r.steps = _steps;
        r.timeout = to;
        r.clock = block.number;
        r.next = r.prover;
        r.phase = 20;
        r.size = 0;
        StartFinalityChallenge(p, c, s, e, _steps, to, uniq);
        return uniq;
    }

    function gameOver(bytes32 id) public {
        Record storage r = records[id];
        require(block.number >= r.clock + r.timeout);
        if (r.next == r.prover) r.winner = r.challenger;
        else r.winner = r.prover;
        WinnerSelected(id);
    }

    function getIter(bytes32 id) internal view returns (uint it, uint i1, uint i2) {
        Record storage r = records[id];
        it = (r.idx2-r.idx1)/(r.size+1);
        i1 = r.idx1;
        i2 = r.idx2;
    }

    event Reported(bytes32 id, uint idx1, uint idx2, bytes32[] arr);

    function report(bytes32 id, uint i1, uint i2, bytes32[] arr) public returns (bool) {
        Record storage r = records[id];
        require(r.size != 0 && arr.length == r.size && i1 == r.idx1 && i2 == r.idx2 &&
                msg.sender == r.prover && r.prover == r.next);
        r.clock = block.number;
        uint iter = (r.idx2-r.idx1)/(r.size+1);
        for (uint i = 0; i < arr.length; i++) {
            r.proof[r.idx1+iter*(i+1)] = arr[i];
        }
        r.next = r.challenger;
        Reported(id, i1, i2, arr);
        return true;
    }

    function roundsTest(uint rounds, uint stuff) internal returns (uint it, uint i1, uint i2) {
        bytes32 id = testMake();
        Record storage r = records[id];
        for (uint i = 0; i < rounds; i++) {
            bytes32[] memory arr = new bytes32[](1);
            arr[0] = bytes32(0xffff);
            report(id, r.idx1, r.idx2, arr);
            query(id, r.idx1, r.idx2, stuff % 2);
            stuff = stuff/2;
        }
        return getIter(id);
    }

    event Queried(bytes32 id, uint idx1, uint idx2);
    event NeedErrorPhases(bytes32 id, uint idx1);

    function query(bytes32 id, uint i1, uint i2, uint num) public {
        Record storage r = records[id];
        require(r.size != 0 && num <= r.size && i1 == r.idx1 && i2 == r.idx2 &&
                msg.sender == r.challenger && r.challenger == r.next);
        r.clock = block.number;
        uint iter = (r.idx2-r.idx1)/(r.size+1);
        r.idx1 = r.idx1+iter*num;
        // If last segment was selected, do not change last index
        if (num != r.size) r.idx2 = r.idx1+iter;
        if (r.size > r.idx2-r.idx1-1) r.size = r.idx2-r.idx1-1;
        // size eventually becomes zero here
        // check if they disagree on the last state being an error state
        if (r.size == 0 && r.idx2 == r.steps-1 && r.proof[r.idx2] == bytes32(0)) {
            r.next = r.challenger;
            // Challenger will have to post the phases
            NeedErrorPhases(id, r.idx1);
        }
        else {
            r.next = r.prover;
            Queried(id, r.idx1, r.idx2);
        }
    }

    function getStep(bytes32 id, uint idx) public view returns (bytes32) {
        Record storage r = records[id];
        return r.proof[idx];
    }

    event PostedPhases(bytes32 id, uint idx1, bytes32[13] arr);

    function postPhases(bytes32 id, uint i1, bytes32[13] arr) public {
        Record storage r = records[id];
        require(r.size == 0 && msg.sender == r.prover && r.next == r.prover && r.idx1 == i1 &&
                r.proof[r.idx1] == arr[0] && r.proof[r.idx1+1] == arr[12] && arr[12] != bytes32(0));
        r.result = arr;
        r.next = r.challenger;
        PostedPhases(id, i1, arr);
    }

    event PostedErrorPhases(bytes32 id, uint idx1, bytes32[13] arr);

    function postErrorPhases(bytes32 id, uint i1, bytes32[13] arr) public {
        Record storage r = records[id];
        require(r.size == 0 && msg.sender == r.challenger && r.next == r.challenger && r.idx1 == i1 &&
                r.proof[r.idx1] == arr[0] && r.proof[r.idx1+1] == bytes32(0));
        r.result = arr;
        r.next = r.prover;
        PostedErrorPhases(id, i1, arr);
    }

    function getResult(bytes32 id)  public view returns (bytes32[13]) {
        Record storage r = records[id];
        return r.result;
    }

    event SelectedPhase(bytes32 id, uint idx1, uint phase);

    function selectPhase(bytes32 id, uint i1, bytes32 st, uint q) public {
        Record storage r = records[id];
        require(r.phase == 16 && msg.sender == r.challenger && r.idx1 == i1 && r.result[q] == st &&
                r.next == r.challenger && q < 13);
        r.phase = q;
        SelectedPhase(id, i1, q);
        r.next = r.prover;
    }

    event SelectedErrorPhase(bytes32 id, uint idx1, uint phase);

    function selectErrorPhase(bytes32 id, uint i1, bytes32 st, uint q) public {
        Record storage r = records[id];
        require(r.phase == 16 && msg.sender == r.prover && r.idx1 == i1 && r.result[q] == st &&
                r.next == r.prover && q < 13);
        r.phase = q;
        SelectedErrorPhase(id, i1, q);
        r.next = r.challenger;
    }

    event WinnerSelected(bytes32 id);

    function callJudge(bytes32 id, uint i1, uint q,
                        bytes32[] proof,
                        bytes32 vm, bytes32 op, uint[4] regs,
                        bytes32[10] roots, uint[4] pointers) public {
        Record storage r = records[id];
        require(r.phase == q && msg.sender == r.prover && r.idx1 == i1 &&
                r.next == r.prover);
        judge.judge(r.result, r.phase, proof, vm, op, regs, roots, pointers);
        WinnerSelected(id);
        r.winner = r.prover;
    }

    // Challenger has claimed that the state is not final
    function callFinalityJudge(bytes32 id, uint i1,
                        bytes32[] proof,
                        bytes32[10] roots, uint[4] pointers) public {
        Record storage r = records[id];
        require(r.phase == 20 && msg.sender == r.prover && r.idx1 == i1 &&
                r.next == r.prover);
        // bytes32 fetched_op = 0x0000000000000000000000000000000000000000040606060001000106000000;
        judge.judgeFinality(r.result, proof, roots, pointers);
        WinnerSelected(id);
        r.winner = r.prover;
    }

    function callErrorJudge(bytes32 id, uint i1, uint q,
                        bytes32[] proof, uint,
                        bytes32 vm, bytes32 op, uint[4] regs,
                        bytes32[10] roots, uint[4] pointers) public {
        Record storage r = records[id];
        require(r.phase == q && msg.sender == r.challenger && r.idx1 == i1 &&
                r.next == r.prover);
        judge.judge(r.result, r.phase, proof, vm, op, regs, roots, pointers);
        WinnerSelected(id);
        r.winner = r.challenger;
    }

}

pragma solidity ^0.4.16;

interface JudgeInterface {
    function judge(bytes32[13] res, uint q,
                        bytes32[] _proof,
                        bytes32 vm_, bytes32 op, uint[4] regs,
                        bytes32[10] roots, uint[4] pointers) public returns (uint);
    function judgeFinality(bytes32[13] res, bytes32[] _proof,
                        bytes32[10] roots, uint[4] pointers) public returns (uint);
}

contract Interactive2 {

    JudgeInterface judge;

    struct Record {
        address prover;
        address challenger;

        bytes32 start_state;
        bytes32 end_state;

        // Maybe number of steps should be finished
        uint256 steps;

        address winner;
        address next;

        uint256 size;
        uint256 timeout;
        uint256 clock;

        uint256 idx1;
        uint256 idx2;

        uint256 phase;

        bytes32[] proof;
        bytes32[13] result;

    }

    function Interactive2(address addr) public {
        judge = JudgeInterface(addr);
    }

    // perhaps they should be indexed by end state ?
    // Record[] records;
    mapping (bytes32 => Record) records;

    function testMake() public returns (bytes32) {
        return make(msg.sender, msg.sender, bytes32(123), bytes32(123),
                    10, 1, 10);
    }

    event StartChallenge(address p, address c, bytes32 s, bytes32 e, uint256 idx1, uint256 idx2,
        uint256 par, uint to, bytes32 uniq);

    function make(address p, address c, bytes32 s, bytes32 e, uint256 _steps,
        uint256 par, uint to) public returns (bytes32) {
        bytes32 uniq = keccak256(p, c, s, e, _steps, par, to);
        Record storage r = records[uniq];
        r.prover = p;
        r.challenger = c;
        r.start_state = s;
        r.end_state = e;
        r.steps = _steps;
        r.size = par;
        if (r.size > r.steps - 2) r.size = r.steps-2;
        r.timeout = to;
        r.clock = block.number;
        r.next = r.prover;
        r.idx1 = 0;
        r.idx2 = r.steps-1;
        r.proof.length = r.steps;
        r.proof[0] = s;
        r.proof[r.steps-1] = e;
        r.phase = 16;
        StartChallenge(p, c, s, e, r.idx1, r.idx2, r.size, to, uniq);
        return uniq;
    }

    event StartFinalityChallenge(address p, address c, bytes32 s, bytes32 e, uint256 step, uint to, bytes32 uniq);

    // Solver thinks this is a final state, verifier disagrees
    // Solver has to post a proof that the next instruction is the "EXIT" opcode
    function makeFinality(address p, address c, bytes32 s, bytes32 e, uint256 _steps, uint to) public returns (bytes32) {
        bytes32 uniq = keccak256(p, c, s, e, _steps, to);
        Record storage r = records[uniq];
        r.prover = p;
        r.challenger = c;
        r.start_state = s;
        r.end_state = e;
        r.steps = _steps;
        r.timeout = to;
        r.clock = block.number;
        r.next = r.prover;
        r.phase = 20;
        r.size = 0;
        StartFinalityChallenge(p, c, s, e, _steps, to, uniq);
        return uniq;
    }

    function gameOver(bytes32 id) public {
        Record storage r = records[id];
        require(block.number >= r.clock + r.timeout);
        if (r.next == r.prover) r.winner = r.challenger;
        else r.winner = r.prover;
        WinnerSelected(id);
    }

    function getIter(bytes32 id) internal view returns (uint it, uint i1, uint i2) {
        Record storage r = records[id];
        it = (r.idx2-r.idx1)/(r.size+1);
        i1 = r.idx1;
        i2 = r.idx2;
    }

    event Reported(bytes32 id, uint idx1, uint idx2, bytes32[] arr);

    function report(bytes32 id, uint i1, uint i2, bytes32[] arr) public returns (bool) {
        Record storage r = records[id];
        require(r.size != 0 && arr.length == r.size && i1 == r.idx1 && i2 == r.idx2 &&
                msg.sender == r.prover && r.prover == r.next);
        r.clock = block.number;
        uint iter = (r.idx2-r.idx1)/(r.size+1);
        for (uint i = 0; i < arr.length; i++) {
            r.proof[r.idx1+iter*(i+1)] = arr[i];
        }
        r.next = r.challenger;
        Reported(id, i1, i2, arr);
        return true;
    }

    function roundsTest(uint rounds, uint stuff) internal returns (uint it, uint i1, uint i2) {
        bytes32 id = testMake();
        Record storage r = records[id];
        for (uint i = 0; i < rounds; i++) {
            bytes32[] memory arr = new bytes32[](1);
            arr[0] = bytes32(0xffff);
            report(id, r.idx1, r.idx2, arr);
            query(id, r.idx1, r.idx2, stuff % 2);
            stuff = stuff/2;
        }
        return getIter(id);
    }

    event Queried(bytes32 id, uint idx1, uint idx2);
    event NeedErrorPhases(bytes32 id, uint idx1);

    function query(bytes32 id, uint i1, uint i2, uint num) public {
        Record storage r = records[id];
        require(r.size != 0 && num <= r.size && i1 == r.idx1 && i2 == r.idx2 &&
                msg.sender == r.challenger && r.challenger == r.next);
        r.clock = block.number;
        uint iter = (r.idx2-r.idx1)/(r.size+1);
        r.idx1 = r.idx1+iter*num;
        // If last segment was selected, do not change last index
        if (num != r.size) r.idx2 = r.idx1+iter;
        if (r.size > r.idx2-r.idx1-1) r.size = r.idx2-r.idx1-1;
        // size eventually becomes zero here
        // check if they disagree on the last state being an error state
        if (r.size == 0 && r.idx2 == r.steps-1 && r.proof[r.idx2] == bytes32(0)) {
            r.next = r.challenger;
            // Challenger will have to post the phases
            NeedErrorPhases(id, r.idx1);
        }
        else {
            r.next = r.prover;
            Queried(id, r.idx1, r.idx2);
        }
    }

    function getStep(bytes32 id, uint idx) public view returns (bytes32) {
        Record storage r = records[id];
        return r.proof[idx];
    }

    event PostedPhases(bytes32 id, uint idx1, bytes32[13] arr);

    function postPhases(bytes32 id, uint i1, bytes32[13] arr) public {
        Record storage r = records[id];
        require(r.size == 0 && msg.sender == r.prover && r.next == r.prover && r.idx1 == i1 &&
                r.proof[r.idx1] == arr[0] && r.proof[r.idx1+1] == arr[12] && arr[12] != bytes32(0));
        r.result = arr;
        r.next = r.challenger;
        PostedPhases(id, i1, arr);
    }

    event PostedErrorPhases(bytes32 id, uint idx1, bytes32[13] arr);

    function postErrorPhases(bytes32 id, uint i1, bytes32[13] arr) public {
        Record storage r = records[id];
        require(r.size == 0 && msg.sender == r.challenger && r.next == r.challenger && r.idx1 == i1 &&
                r.proof[r.idx1] == arr[0] && r.proof[r.idx1+1] == bytes32(0));
        r.result = arr;
        r.next = r.prover;
        PostedErrorPhases(id, i1, arr);
    }

    function getResult(bytes32 id)  public view returns (bytes32[13]) {
        Record storage r = records[id];
        return r.result;
    }

    event SelectedPhase(bytes32 id, uint idx1, uint phase);

    function selectPhase(bytes32 id, uint i1, bytes32 st, uint q) public {
        Record storage r = records[id];
        require(r.phase == 16 && msg.sender == r.challenger && r.idx1 == i1 && r.result[q] == st &&
                r.next == r.challenger && q < 13);
        r.phase = q;
        SelectedPhase(id, i1, q);
        r.next = r.prover;
    }

    event SelectedErrorPhase(bytes32 id, uint idx1, uint phase);

    function selectErrorPhase(bytes32 id, uint i1, bytes32 st, uint q) public {
        Record storage r = records[id];
        require(r.phase == 16 && msg.sender == r.prover && r.idx1 == i1 && r.result[q] == st &&
                r.next == r.prover && q < 13);
        r.phase = q;
        SelectedErrorPhase(id, i1, q);
        r.next = r.challenger;
    }

    event WinnerSelected(bytes32 id);

    function callJudge(bytes32 id, uint i1, uint q,
                        bytes32[] proof, uint,
                        bytes32 vm, bytes32 op, uint[4] regs,
                        bytes32[10] roots, uint[4] pointers) public {
        Record storage r = records[id];
        require(r.phase == q && msg.sender == r.prover && r.idx1 == i1 &&
                r.next == r.prover);
        judge.judge(r.result, r.phase, proof, vm, op, regs, roots, pointers);
        WinnerSelected(id);
        r.winner = r.prover;
    }

    // Challenger has claimed that the state is not final
    function callFinalityJudge(bytes32 id, uint i1,
                        bytes32[] proof,
                        bytes32[10] roots, uint[4] pointers) public {
        Record storage r = records[id];
        require(r.phase == 20 && msg.sender == r.prover && r.idx1 == i1 &&
                r.next == r.prover);
        // bytes32 fetched_op = 0x0000000000000000000000000000000000000000040606060001000106000000;
        judge.judgeFinality(r.result, proof, roots, pointers);
        WinnerSelected(id);
        r.winner = r.prover;
    }

    function callErrorJudge(bytes32 id, uint i1, uint q,
                        bytes32[] proof, uint,
                        bytes32 vm, bytes32 op, uint[4] regs,
                        bytes32[10] roots, uint[4] pointers) public {
        Record storage r = records[id];
        require(r.phase == q && msg.sender == r.challenger && r.idx1 == i1 &&
                r.next == r.prover);
        judge.judge(r.result, r.phase, proof, vm, op, regs, roots, pointers);
        WinnerSelected(id);
        r.winner = r.challenger;
    }

}


refactor: change numberOfQuestions to dynamic getter

pragma solidity ^0.4.6;

contract DQuestions {
    string[] questions;

    function numberOfQuestions() constant returns (uint) {
        return questions.length;
    }

    function add(string question) {
        questions.push(question);
    }

    function getQuestion(uint i) constant returns (string) {
        return questions[i];
    }
}

pragma solidity ^0.4.6;

contract DQuestions {
    uint public numberOfQuestions;
    string[] questions;

    function add(string question) {
        ++numberOfQuestions;
        questions.push(question);
    }

    function getQuestion(uint i) constant returns (string) {
        return questions[i];
    }
}


Improves control flow and event logging

Improves control flow and event logging

/*
 * Partial src: https://github.com/eris-ltd/hello-eris/blob/master/contracts/DealManager.sol
 */

import "Task.sol";
import "LinkedList.sol";

contract TaskManager {
    DoublyLinkedList list;
    address ref;

    /*modifier onlyOwner() {
        if (msg.sender != owner)
        throw;

        _ // `_` is synonymous to JS middleware's `next()`
    }*/

  // TODO extend with eventObject if possible; `bytes32[]`?
    event ActionEvent(address indexed userAddr, bytes32 actionType);
    function registerActionEvent(bytes32 actionType) {
      ActionEvent(msg.sender, actionType);
    }

    /**
     * Adds a new task with the specified attributes
     */
    function addTask(bytes32 _id, bytes32 _title, bytes32 _desc, bytes32 _status, bytes32 _complete, bytes32 _reward)
        returns (bool status)
    {
        Task t = new Task(_id, _title, _desc, _status, _complete, _reward);

        ref = msg.sender;
        status = list.addElement(msg.sender, _id);
        registerActionEvent(_id);
        return status;
    }

    // TODO
    function getTask(bytes32 _id) constant returns (bytes32 taskData) {
        registerActionEvent(_id);
        return list.getData(ref);
    }

    /*function set(uint x) {
    example = Account(msg.sender, x);
    }

    function getBalance() constant returns (uint retVal) {
        registerActionEvent("getBalance");
        return example.balance;
    }

    function getOwner() constant returns (address retVal) {
        return example.owner;
    }

    function destroy() onlyOwner {
        selfdestruct(example.owner);
    }*/

}

/*
 * Partial src: https://github.com/eris-ltd/hello-eris/blob/master/contracts/DealManager.sol
 */

import "Task.sol";
import "LinkedList.sol";

contract TaskManager {
    DoublyLinkedList list;
    address ref;

    /*modifier onlyOwner() {
        if (msg.sender != owner)
        throw;

        _ // `_` is synonymous to JS middleware's `next()`
    }*/

  // TODO extend with eventObject if possible; `bytes32[]`?
    event ActionEvent(address indexed userAddr, string actionType);
    function registerActionEvent(string actionType) {
      ActionEvent(msg.sender, actionType);
    }

    /**
     * Adds a new task with the specified attributes
     */
    function addTask(bytes32 _id, bytes32 _title, bytes32 _desc, bytes32 _status, bytes32 _complete, bytes32 _reward)
        returns (bool success)
    {
        Task t = new Task(_id, _title, _desc, _status, _complete, _reward);

        ref = msg.sender;
        list.addElement(msg.sender, _id);
        registerActionEvent("addTask");
        return true;
    }

    // TODO
    function getTask(bytes32 _id) constant returns (bytes32 taskData) {
        return list.getData(ref);
    }

    /*function set(uint x) {
    example = Account(msg.sender, x);
    }

    function getBalance() constant returns (uint retVal) {
        registerActionEvent("getBalance");
        return example.balance;
    }

    function getOwner() constant returns (address retVal) {
        return example.owner;
    }

    function destroy() onlyOwner {
        selfdestruct(example.owner);
    }*/

}


Initial contract (untested, unverified)

Initial contract (untested, unverified)

//! MIT
//! A simple voting with account balanaces contract
//! Jaco Greeff <jacogr@gmail.com>

pragma solidity ^0.4.1;

// standard Owner interface
contract Owned {
  // emitted when a new owner is set
  event NewOwner(address indexed old, address indexed current);

  // only the owner is allowed to modify
  modifier only_owner {
    if (msg.sender != owner) throw;
    _;
  }

  // set the owner to the contract creator
  address public owner = msg.sender;

  // set a new owner
  function setOwner(address _newOwner) only_owner {
    NewOwner(owner, _new);
    owner = _newOwner;
  }
}

// the voting contract
contract Voting is Owned {
  // emitted when a new question was asked
  NewQuestion(address indexed owner, uint index, string question);

  // emitted when a new answer is provided
  NewAnswer(uint indexed index, uint value, bool isYes);

  // define a question with totals & voters
  struct Question {
    address owner;
    uint valueNo;
    uint valueYes;
    uint votesNo;
    uint votesYes;
    string question;
    mapping (address => bool) voters;
  }

  // the list of questions
  Question[] questions;

  // the applicable question & answer fees
  uint public answerFee = 0;
  uint public questionFee = 5 finney;

  // has the fee been paid to answer
  modifier is_answer_paid {
    if (msg.value < answerFee) throw;
    _;
  }

  // has the fee been paid to ask a question
  modifier is_question_paid {
    if (msg.value < questionFee) throw;
    _;
  }

  // is there an actual question at this index
  modifier is_valid_question (uint _index) {
    if (_index >= questions.length) throw;
    _;
  }

  // is the question of acceptable length
  modifier is_short_question (string _question) {
    if (bytes(_question).length > 160) throw;
    _;
  }

  // has the voter not voted already
  modifier has_not_voted (uint _index) {
    if (questions[_index].voters[msg.sender] == true) throw;
    _;
  }

  // the number of questions asked
  function count () constant returns (uint) {
    return questions.length;
  }

  // details for a specific question
  function get (uint _index) constant returns (address owner, uint valueNo, uint valueYes, uint votesNo, uint votesYes, string question) {
    Question q = questions[_index];

    owner = q.owner;
    valueNo = q.valueNo;
    valueYes = q.valueYes;
    votesNo = q.votesNo;
    votesYes = q.votesYes;
    question = q.question;
  }

  // tests if the sender has voted
  function hasSenderVoted () constant returns (bool) {
    return questions[_index].voters[msg.sender];
  }

  // ask a new question
  function newQuestion (string _question) payable is_question_paid is_short_question(_question) returns (bool) {
    uint index = questions.length;

    questions.length += 1;
    questions[index].owner = msg.sender;
    questions[index].question = _question;

    NewQuestion(msg.sender, index, _question);

    return true;
  }

  // answer a question
  function newAnswer (uint _index, bool _isYes) payable is_answer_paid is_valid_question(_index) has_not_voted(_index) return (bool) {
    questions[_index].voters[msg.sender] = true;

    if (_isYes) {
      questions[_index].valueYes += msg.sender.balance;
      questions[_index].votesYes += 1;
    } else {
      questions[_index].valueNo += msg.sender.balance;
      questions[_index].votesNo += 1;
    }

    newAnswer(_index, msg.sender.balance, _isYes);

    return true;
  }

  // adjust the fee for providing answers
  function setAnswerFee (uint _fee) only_owner {
    answerFee = _fee;
  }

  // adjust the fee for asking questions
  function setQuestionFee (uint _fee) only_owner {
    questionFee = _fee;
  }

  // drain all accumulated funds
  function drain() only_owner {
    if (!msg.sender.send(this.balance)) {
      throw;
    }
  }
}

error: pathspec 'Voting.sol' did not match any file(s) known to git


Bug fix, see commit body

Bug fix, see commit body

Fixes a bug related to the resolution of param proposals with challenges
not processed until after the processBy date. Previously, tokens in the
challenge would be burned. Now the challenge is resolved, but the param
is not updated no matter what if the processBy < now.

pragma solidity^0.4.11;

import "./PLCRVoting.sol";
import "./historical/StandardToken.sol";

contract Parameterizer {

  // ------
  // EVENTS
  // ------

  event _ReparameterizationProposal(address proposer, string name, uint value, bytes32 propID);
  event _NewChallenge(address challenger, bytes32 propID, uint pollID);

  mapping(bytes32 => uint) public params;

  struct ParamProposal {
    uint appExpiry;
    uint challengeID;
    uint deposit;
    string name;
    address owner;
    uint processBy;
    uint value;
  }

  struct Challenge {
    uint rewardPool;        // (remaining) pool of tokens distributed amongst winning voters
    address challenger;     // owner of Challenge
    bool resolved;          // indication of if challenge is resolved
    uint stake;             // number of tokens at risk for either party during challenge
    uint totalTokens;       // (remaining) amount of tokens used for voting by the winning side
  }

  // maps pollIDs to intended data change if poll passes
  mapping(bytes32 => ParamProposal) public proposalMap;

  // maps challengeIDs to associated challenge data
  mapping(uint => Challenge) public challengeMap;

  // maps challengeIDs and address to token claim data
  mapping(uint => mapping(address => bool)) public tokenClaims;

  // Global Variables
  StandardToken public token;
  PLCRVoting public voting;
  uint public PROCESSBY = 604800; // 7 days

  /**
  @dev constructor
  @param _tokenAddr        address of the token which parameterizes this system
  @param _plcrAddr         address of a PLCR voting contract for the provided token
  @param _minDeposit       minimum deposit for listing to be whitelisted
  @param _pMinDeposit      minimum deposit to propose a reparameterization
  @param _applyStageLen    period over which applicants wait to be whitelisted
  @param _pApplyStageLen   period over which reparmeterization proposals wait to be processed
  @param _dispensationPct  percentage of losing party's deposit distributed to winning party
  @param _pDispensationPct percentage of losing party's deposit distributed to winning party in parameterizer
  @param _commitPeriodLen  length of commit period for voting
  @param _pCommitPeriodLen length of commit period for voting in parameterizer
  @param _revealPeriodLen  length of reveal period for voting
  @param _pRevealPeriodLen length of reveal period for voting in parameterizer
  @param _voteQuorum       type of majority out of 100 necessary for vote success
  @param _pVoteQuorum      type of majority out of 100 necessary for vote success in parameterizer
  */
  function Parameterizer(
    address _tokenAddr,
    address _plcrAddr,
    uint _minDeposit,
    uint _pMinDeposit,
    uint _applyStageLen,
    uint _pApplyStageLen,
    uint _commitPeriodLen,
    uint _pCommitPeriodLen,
    uint _revealPeriodLen,
    uint _pRevealPeriodLen,
    uint _dispensationPct,
    uint _pDispensationPct,
    uint _voteQuorum,
    uint _pVoteQuorum
    ) {
      token = StandardToken(_tokenAddr);
      voting = PLCRVoting(_plcrAddr);

      set("minDeposit", _minDeposit);
      set("pMinDeposit", _pMinDeposit);
      set("applyStageLen", _applyStageLen);
      set("pApplyStageLen", _pApplyStageLen);
      set("commitPeriodLen", _commitPeriodLen);
      set("pCommitPeriodLen", _pCommitPeriodLen);
      set("revealPeriodLen", _revealPeriodLen);
      set("pRevealPeriodLen", _pRevealPeriodLen);
      set("dispensationPct", _dispensationPct);
      set("pDispensationPct", _pDispensationPct);
      set("voteQuorum", _voteQuorum);
      set("pVoteQuorum", _pVoteQuorum);
  }

  // -----------------------
  // TOKEN HOLDER INTERFACE:
  // -----------------------

  /**
  @notice propose a reparamaterization of the key _name's value to _value.
  @param _name the name of the proposed param to be set
  @param _value the proposed value to set the param to be set
  */
  function proposeReparameterization(string _name, uint _value) public returns (bytes32) {
    uint deposit = get("pMinDeposit");
    bytes32 propID = sha3(_name, _value);

    require(!propExists(propID)); // Forbid duplicate proposals
    require(get(_name) != _value); // Forbid NOOP reparameterizations
    require(token.transferFrom(msg.sender, this, deposit)); // escrow tokens (deposit amt)

    // attach name and value to pollID
    proposalMap[propID] = ParamProposal({
      appExpiry: now + get("pApplyStageLen"),
      challengeID: 0,
      deposit: deposit,
      name: _name,
      owner: msg.sender,
      processBy: now + get("pApplyStageLen") + get("pCommitPeriodLen") +
        get("pRevealPeriodLen") + PROCESSBY,
      value: _value
    });

    _ReparameterizationProposal(msg.sender, _name, _value, propID);
    return propID;
  }

  /**
  @notice challenge the provided proposal ID, and put tokens at stake to do so.
  @param _propID the proposal ID to challenge
  */
  function challengeReparameterization(bytes32 _propID) public returns (uint challengeID) {
    ParamProposal memory prop = proposalMap[_propID];
    uint deposit = get("pMinDeposit");

    require(propExists(_propID) && prop.challengeID == 0);

    //take tokens from challenger
    require(token.transferFrom(msg.sender, this, deposit));
    //start poll
    uint pollID = voting.startPoll(
      get("pVoteQuorum"),
      get("pCommitPeriodLen"),
      get("pRevealPeriodLen")
    );

    challengeMap[pollID] = Challenge({
      challenger: msg.sender,
      rewardPool: ((100 - get("pDispensationPct")) * deposit) / 100,
      stake: deposit,
      resolved: false,
      totalTokens: 0
    });

    proposalMap[_propID].challengeID = pollID;       // update listing to store most recent challenge

    _NewChallenge(msg.sender, _propID, pollID);
    return pollID;
  }

  /**
  @notice for the provided proposal ID, set it, resolve its challenge, or delete it depending on whether it can be set, has a challenge which can be resolved, or if its "process by" date has passed
  @param _propID the proposal ID to make a determination and state transition for
  */
  function processProposal(bytes32 _propID) public {
    ParamProposal storage prop = proposalMap[_propID];

    if (canBeSet(_propID)) {
      set(prop.name, prop.value);
    } else if (challengeCanBeResolved(_propID)) {
      resolveChallenge(_propID);
    } else if (now > prop.processBy) {
    } else {
      revert();
    }

    delete proposalMap[_propID];
  }

  /**
  @notice claim the tokens owed for the msg.sender in the provided challenge
  @param _challengeID the challenge ID to claim tokens for
  @param _salt the salt used to vote in the challenge being withdrawn for
  */
  function claimReward(uint _challengeID, uint _salt) public {
    // ensure voter has not already claimed tokens and challenge results have been processed
    require(tokenClaims[_challengeID][msg.sender] == false);
    require(challengeMap[_challengeID].resolved = true);

    uint voterTokens = voting.getNumPassingTokens(msg.sender, _challengeID, _salt);
    uint reward = calculateVoterReward(msg.sender, _challengeID, _salt);

    // subtract voter's information to preserve the participation ratios of other voters
    // compared to the remaining pool of rewards
    challengeMap[_challengeID].totalTokens -= voterTokens;
    challengeMap[_challengeID].rewardPool -= reward;

    require(token.transfer(msg.sender, reward));

    // ensures a voter cannot claim tokens again
    tokenClaims[_challengeID][msg.sender] = true;
  }

  // --------
  // GETTERS:
  // --------

  /**
  @dev Calculate the provided voter's token reward for the given poll
  @param _voter Address of the voter whose reward balance is to be returned
  @param _challengeID pollID of the challenge a reward balance is being queried for
  @param _salt the salt for the voter's commit hash in the given poll
  @return a uint indicating the voter's reward in nano-adToken
  */
  function calculateVoterReward(address _voter, uint _challengeID, uint _salt)
  public constant returns (uint) {
    uint totalTokens = challengeMap[_challengeID].totalTokens;
    uint rewardPool = challengeMap[_challengeID].rewardPool;
    uint voterTokens = voting.getNumPassingTokens(_voter, _challengeID, _salt);
    return (voterTokens * rewardPool) / totalTokens;
  }

  /**
  @notice Determines whether a proposal passed its application stage without a challenge
  @param _propID The proposal ID for which to determine whether its application stage passed without a challenge
  */
  function canBeSet(bytes32 _propID) constant public returns (bool) {
    ParamProposal memory prop = proposalMap[_propID];

    return (propExists(_propID) && now > prop.appExpiry && now < prop.processBy &&
        prop.challengeID == 0);
  }

  /**
  @notice Determines whether a proposal exists for the provided proposal ID
  @param _propID The proposal ID whose existance is to be determined
  */
  function propExists(bytes32 _propID) constant public returns (bool) {
    return proposalMap[_propID].processBy > 0;
  }

  /**
  @notice Determines whether the provided proposal ID has a challenge which can be resolved
  @param _propID The proposal ID whose challenge to inspect
  */
  function challengeCanBeResolved(bytes32 _propID) constant public returns (bool) {
    ParamProposal memory prop = proposalMap[_propID];

    return (prop.challengeID > 0);
  }

  /**
  @notice Determines the number of tokens to awarded to the winning party in a challenge
  @param _challengeID The challengeID to determine a reward for
  */
  function determineReward(uint _challengeID) public constant returns (uint) {
    require(!challengeMap[_challengeID].resolved && voting.pollEnded(_challengeID));

    if(voting.getTotalNumberOfTokensForWinningOption(_challengeID) == 0) {
      // Edge case, nobody voted, give all tokens to the winner.
      return 2 * challengeMap[_challengeID].stake;
    }

    return (2 * challengeMap[_challengeID].stake) - challengeMap[_challengeID].rewardPool;
  }

  /**
  @notice gets the parameter keyed by the provided name value from the params mapping
  @param _name the key whose value is to be determined
  */
  function get(string _name) public constant returns (uint value) {
    return params[sha3(_name)];
  }

  // ----------------
  // PRIVATE FUNCTIONS:
  // ----------------

  /**
  @dev sets the param keted by the provided name to the provided value
  @param _name the name of the param to be set
  @param _value the value to set the param to be set
  */
  function set(string _name, uint _value) private {
    params[sha3(_name)] = _value;
  }

  /**
  @dev resolves a challenge for the provided _propID. It must be checked in advance whether the _propID has a challenge on it
  @param _propID the proposal ID whose challenge is to be resolved.
  */
  function resolveChallenge(bytes32 _propID) private {
    ParamProposal memory prop = proposalMap[_propID];

    // winner gets back their full staked deposit, and dispensationPct*loser's stake
    uint reward = determineReward(prop.challengeID);

    if (voting.isPassed(prop.challengeID)) { // The challenge failed
      if(prop.processBy > now) {
        set(prop.name, prop.value);
      }
      require(token.transfer(prop.owner, reward));
    }
    else { // The challenge succeeded
      require(token.transfer(challengeMap[prop.challengeID].challenger, reward));
    }

    // set flag on challenge being processed
    challengeMap[prop.challengeID].resolved = true;

    // store the total tokens used for voting by the winning side for reward purposes
    challengeMap[prop.challengeID].totalTokens =
      voting.getTotalNumberOfTokensForWinningOption(prop.challengeID);
  }
}

pragma solidity^0.4.11;

import "./PLCRVoting.sol";
import "./historical/StandardToken.sol";

contract Parameterizer {

  // ------
  // EVENTS
  // ------

  event _ReparameterizationProposal(address proposer, string name, uint value, bytes32 propID);
  event _NewChallenge(address challenger, bytes32 propID, uint pollID);

  mapping(bytes32 => uint) public params;

  struct ParamProposal {
    uint appExpiry;
    uint challengeID;
    uint deposit;
    string name;
    address owner;
    uint processBy;
    uint value;
  }

  struct Challenge {
    uint rewardPool;        // (remaining) pool of tokens distributed amongst winning voters
    address challenger;     // owner of Challenge
    bool resolved;          // indication of if challenge is resolved
    uint stake;             // number of tokens at risk for either party during challenge
    uint totalTokens;       // (remaining) amount of tokens used for voting by the winning side
  }

  // maps pollIDs to intended data change if poll passes
  mapping(bytes32 => ParamProposal) public proposalMap;

  // maps challengeIDs to associated challenge data
  mapping(uint => Challenge) public challengeMap;

  // maps challengeIDs and address to token claim data
  mapping(uint => mapping(address => bool)) public tokenClaims;

  // Global Variables
  StandardToken public token;
  PLCRVoting public voting;
  uint public PROCESSBY = 604800; // 7 days

  /**
  @dev constructor
  @param _tokenAddr        address of the token which parameterizes this system
  @param _plcrAddr         address of a PLCR voting contract for the provided token
  @param _minDeposit       minimum deposit for listing to be whitelisted
  @param _pMinDeposit      minimum deposit to propose a reparameterization
  @param _applyStageLen    period over which applicants wait to be whitelisted
  @param _pApplyStageLen   period over which reparmeterization proposals wait to be processed
  @param _dispensationPct  percentage of losing party's deposit distributed to winning party
  @param _pDispensationPct percentage of losing party's deposit distributed to winning party in parameterizer
  @param _commitPeriodLen  length of commit period for voting
  @param _pCommitPeriodLen length of commit period for voting in parameterizer
  @param _revealPeriodLen  length of reveal period for voting
  @param _pRevealPeriodLen length of reveal period for voting in parameterizer
  @param _voteQuorum       type of majority out of 100 necessary for vote success
  @param _pVoteQuorum      type of majority out of 100 necessary for vote success in parameterizer
  */
  function Parameterizer(
    address _tokenAddr,
    address _plcrAddr,
    uint _minDeposit,
    uint _pMinDeposit,
    uint _applyStageLen,
    uint _pApplyStageLen,
    uint _commitPeriodLen,
    uint _pCommitPeriodLen,
    uint _revealPeriodLen,
    uint _pRevealPeriodLen,
    uint _dispensationPct,
    uint _pDispensationPct,
    uint _voteQuorum,
    uint _pVoteQuorum
    ) {
      token = StandardToken(_tokenAddr);
      voting = PLCRVoting(_plcrAddr);

      set("minDeposit", _minDeposit);
      set("pMinDeposit", _pMinDeposit);
      set("applyStageLen", _applyStageLen);
      set("pApplyStageLen", _pApplyStageLen);
      set("commitPeriodLen", _commitPeriodLen);
      set("pCommitPeriodLen", _pCommitPeriodLen);
      set("revealPeriodLen", _revealPeriodLen);
      set("pRevealPeriodLen", _pRevealPeriodLen);
      set("dispensationPct", _dispensationPct);
      set("pDispensationPct", _pDispensationPct);
      set("voteQuorum", _voteQuorum);
      set("pVoteQuorum", _pVoteQuorum);
  }

  // -----------------------
  // TOKEN HOLDER INTERFACE:
  // -----------------------

  /**
  @notice propose a reparamaterization of the key _name's value to _value.
  @param _name the name of the proposed param to be set
  @param _value the proposed value to set the param to be set
  */
  function proposeReparameterization(string _name, uint _value) public returns (bytes32) {
    uint deposit = get("pMinDeposit");
    bytes32 propID = sha3(_name, _value);

    require(!propExists(propID)); // Forbid duplicate proposals
    require(get(_name) != _value); // Forbid NOOP reparameterizations
    require(token.transferFrom(msg.sender, this, deposit)); // escrow tokens (deposit amt)

    // attach name and value to pollID
    proposalMap[propID] = ParamProposal({
      appExpiry: now + get("pApplyStageLen"),
      challengeID: 0,
      deposit: deposit,
      name: _name,
      owner: msg.sender,
      processBy: now + get("pApplyStageLen") + get("pCommitPeriodLen") +
        get("pRevealPeriodLen") + PROCESSBY,
      value: _value
    });

    _ReparameterizationProposal(msg.sender, _name, _value, propID);
    return propID;
  }

  /**
  @notice challenge the provided proposal ID, and put tokens at stake to do so.
  @param _propID the proposal ID to challenge
  */
  function challengeReparameterization(bytes32 _propID) public returns (uint challengeID) {
    ParamProposal memory prop = proposalMap[_propID];
    uint deposit = get("pMinDeposit");

    require(propExists(_propID) && prop.challengeID == 0);

    //take tokens from challenger
    require(token.transferFrom(msg.sender, this, deposit));
    //start poll
    uint pollID = voting.startPoll(
      get("pVoteQuorum"),
      get("pCommitPeriodLen"),
      get("pRevealPeriodLen")
    );

    challengeMap[pollID] = Challenge({
      challenger: msg.sender,
      rewardPool: ((100 - get("pDispensationPct")) * deposit) / 100,
      stake: deposit,
      resolved: false,
      totalTokens: 0
    });

    proposalMap[_propID].challengeID = pollID;       // update listing to store most recent challenge

    _NewChallenge(msg.sender, _propID, pollID);
    return pollID;
  }

  /**
  @notice for the provided proposal ID, set it, resolve its challenge, or delete it depending on whether it can be set, has a challenge which can be resolved, or if its "process by" date has passed
  @param _propID the proposal ID to make a determination and state transition for
  */
  function processProposal(bytes32 _propID) public {
    ParamProposal storage prop = proposalMap[_propID];

    if (canBeSet(_propID)) {
      set(prop.name, prop.value);
    } else if (challengeCanBeResolved(_propID)) {
      resolveChallenge(_propID);
    } else if (now > prop.processBy) {
    } else {
      revert();
    }

    delete proposalMap[_propID];
  }

  /**
  @notice claim the tokens owed for the msg.sender in the provided challenge
  @param _challengeID the challenge ID to claim tokens for
  @param _salt the salt used to vote in the challenge being withdrawn for
  */
  function claimReward(uint _challengeID, uint _salt) public {
    // ensure voter has not already claimed tokens and challenge results have been processed
    require(tokenClaims[_challengeID][msg.sender] == false);
    require(challengeMap[_challengeID].resolved = true);

    uint voterTokens = voting.getNumPassingTokens(msg.sender, _challengeID, _salt);
    uint reward = calculateVoterReward(msg.sender, _challengeID, _salt);

    // subtract voter's information to preserve the participation ratios of other voters
    // compared to the remaining pool of rewards
    challengeMap[_challengeID].totalTokens -= voterTokens;
    challengeMap[_challengeID].rewardPool -= reward;

    require(token.transfer(msg.sender, reward));

    // ensures a voter cannot claim tokens again
    tokenClaims[_challengeID][msg.sender] = true;
  }

  // --------
  // GETTERS:
  // --------

  /**
  @dev Calculate the provided voter's token reward for the given poll
  @param _voter Address of the voter whose reward balance is to be returned
  @param _challengeID pollID of the challenge a reward balance is being queried for
  @param _salt the salt for the voter's commit hash in the given poll
  @return a uint indicating the voter's reward in nano-adToken
  */
  function calculateVoterReward(address _voter, uint _challengeID, uint _salt)
  public constant returns (uint) {
    uint totalTokens = challengeMap[_challengeID].totalTokens;
    uint rewardPool = challengeMap[_challengeID].rewardPool;
    uint voterTokens = voting.getNumPassingTokens(_voter, _challengeID, _salt);
    return (voterTokens * rewardPool) / totalTokens;
  }

  /**
  @notice Determines whether a proposal passed its application stage without a challenge
  @param _propID The proposal ID for which to determine whether its application stage passed without a challenge
  */
  function canBeSet(bytes32 _propID) constant public returns (bool) {
    ParamProposal memory prop = proposalMap[_propID];

    return (propExists(_propID) && now > prop.appExpiry && now < prop.processBy &&
        prop.challengeID == 0);
  }

  /**
  @notice Determines whether a proposal exists for the provided proposal ID
  @param _propID The proposal ID whose existance is to be determined
  */
  function propExists(bytes32 _propID) constant public returns (bool) {
    return proposalMap[_propID].processBy > 0;
  }

  /**
  @notice Determines whether the provided proposal ID has a challenge which can be resolved
  @param _propID The proposal ID whose challenge to inspect
  */
  function challengeCanBeResolved(bytes32 _propID) constant public returns (bool) {
    ParamProposal memory prop = proposalMap[_propID];

    return (prop.challengeID > 0 && now < prop.processBy);
  }

  /**
  @notice Determines the number of tokens to awarded to the winning party in a challenge
  @param _challengeID The challengeID to determine a reward for
  */
  function determineReward(uint _challengeID) public constant returns (uint) {
    require(!challengeMap[_challengeID].resolved && voting.pollEnded(_challengeID));

    if(voting.getTotalNumberOfTokensForWinningOption(_challengeID) == 0) {
      // Edge case, nobody voted, give all tokens to the winner.
      return 2 * challengeMap[_challengeID].stake;
    }

    return (2 * challengeMap[_challengeID].stake) - challengeMap[_challengeID].rewardPool;
  }

  /**
  @notice gets the parameter keyed by the provided name value from the params mapping
  @param _name the key whose value is to be determined
  */
  function get(string _name) public constant returns (uint value) {
    return params[sha3(_name)];
  }

  // ----------------
  // PRIVATE FUNCTIONS:
  // ----------------

  /**
  @dev sets the param keted by the provided name to the provided value
  @param _name the name of the param to be set
  @param _value the value to set the param to be set
  */
  function set(string _name, uint _value) private {
    params[sha3(_name)] = _value;
  }

  /**
  @dev resolves a challenge for the provided _propID. It must be checked in advance whether the _propID has a challenge on it
  @param _propID the proposal ID whose challenge is to be resolved.
  */
  function resolveChallenge(bytes32 _propID) private {
    ParamProposal memory prop = proposalMap[_propID];

    // winner gets back their full staked deposit, and dispensationPct*loser's stake
    uint reward = determineReward(prop.challengeID);

    if (voting.isPassed(prop.challengeID)) { // The challenge failed
      set(prop.name, prop.value);
      require(token.transfer(prop.owner, reward));
    }
    else { // The challenge succeeded
      require(token.transfer(challengeMap[prop.challengeID].challenger, reward));
    }

    // set flag on challenge being processed
    challengeMap[prop.challengeID].resolved = true;

    // store the total tokens used for voting by the winning side for reward purposes
    challengeMap[prop.challengeID].totalTokens =
      voting.getTotalNumberOfTokensForWinningOption(prop.challengeID);
  }
}