Implement revokable and burnsOnRevoke options

pragma solidity ^0.4.8;

import "./StandardToken.sol";
import "./TransferableToken.sol";

contract VestedToken is StandardToken, TransferableToken {
  struct TokenGrant {
    address granter;
    uint256 value;
    uint64 cliff;
    uint64 vesting;
    uint64 start;
    bool revokable;
    bool burnsOnRevoke;
  }

  mapping (address => TokenGrant[]) public grants;

  function grantVestedTokens(
    address _to,
    uint256 _value,
    uint64 _start,
    uint64 _cliff,
    uint64 _vesting,
    bool _revokable,
    bool _burnsOnRevoke) {

    if (_cliff < _start) {
      throw;
    }
    if (_vesting < _start) {
      throw;
    }
    if (_vesting < _cliff) {
      throw;
    }

    grants[_to].push(
      TokenGrant(
        msg.sender,
        _value,
        _cliff,
        _vesting,
        _start,
        _revokable,
        _burnsOnRevoke
      )
    );

    transfer(_to, _value);
  }

  function revokeTokenGrant(address _holder, uint _grantId) {
    TokenGrant grant = grants[_holder][_grantId];

    if (!grant.revokable) { // Check if grant was revokable
      throw;
    }

    if (grant.granter != msg.sender) { // Only granter can revoke it
      throw;
    }

    address receiver = grant.burnsOnRevoke ? 0xdead : msg.sender;

    uint256 nonVested = nonVestedTokens(grant, uint64(now));

    // remove grant from array
    delete grants[_holder][_grantId];
    grants[_holder][_grantId] = grants[_holder][grants[_holder].length - 1];
    grants[_holder].length -= 1;

    balances[receiver] = safeAdd(balances[receiver], nonVested);
    balances[_holder] = safeSub(balances[_holder], nonVested);
    Transfer(_holder, receiver, nonVested);
  }

  function tokenGrantsCount(address _holder) constant returns (uint index) {
    return grants[_holder].length;
  }

  function tokenGrant(address _holder, uint _grantId) constant returns (address granter, uint256 value, uint256 vested, uint64 start, uint64 cliff, uint64 vesting, bool revokable, bool burnsOnRevoke) {
    TokenGrant grant = grants[_holder][_grantId];

    granter = grant.granter;
    value = grant.value;
    start = grant.start;
    cliff = grant.cliff;
    vesting = grant.vesting;
    revokable = grant.revokable;
    burnsOnRevoke = grant.burnsOnRevoke;

    vested = vestedTokens(grant, uint64(now));
  }

  function vestedTokens(TokenGrant grant, uint64 time) private constant returns (uint256) {
    return calculateVestedTokens(
      grant.value,
      uint256(time),
      uint256(grant.start),
      uint256(grant.cliff),
      uint256(grant.vesting)
    );
  }

  function calculateVestedTokens(
    uint256 tokens,
    uint256 time,
    uint256 start,
    uint256 cliff,
    uint256 vesting) constant returns (uint256 vestedTokens)
    {

    if (time < cliff) {
      return 0;
    }
    if (time > vesting) {
      return tokens;
    }

    uint256 cliffTokens = safeDiv(safeMul(tokens, safeSub(cliff, start)), safeSub(vesting, start));
    vestedTokens = cliffTokens;

    uint256 vestingTokens = safeSub(tokens, cliffTokens);

    vestedTokens = safeAdd(vestedTokens, safeDiv(safeMul(vestingTokens, safeSub(time, cliff)), safeSub(vesting, start)));
  }

  function nonVestedTokens(TokenGrant grant, uint64 time) private constant returns (uint256) {
    return safeSub(grant.value, vestedTokens(grant, time));
  }

  function lastTokenIsTransferableDate(address holder) constant public returns (uint64 date) {
    date = uint64(now);
    uint256 grantIndex = grants[holder].length;
    for (uint256 i = 0; i < grantIndex; i++) {
      date = max64(grants[holder][i].vesting, date);
    }
  }

  function transferableTokens(address holder, uint64 time) constant public returns (uint256 nonVested) {
    uint256 grantIndex = grants[holder].length;
    for (uint256 i = 0; i < grantIndex; i++) {
      nonVested = safeAdd(nonVested, nonVestedTokens(grants[holder][i], time));
    }

    return min256(safeSub(balances[holder], nonVested), super.transferableTokens(holder, time));
  }
}

pragma solidity ^0.4.8;

import "./StandardToken.sol";
import "./TransferableToken.sol";

contract VestedToken is StandardToken, TransferableToken {
  struct TokenGrant {
    address granter;
    uint256 value;
    uint64 cliff;
    uint64 vesting;
    uint64 start;
  }

  mapping (address => TokenGrant[]) public grants;

  function grantVestedTokens(
    address _to,
    uint256 _value,
    uint64 _start,
    uint64 _cliff,
    uint64 _vesting) {

    if (_cliff < _start) {
      throw;
    }
    if (_vesting < _start) {
      throw;
    }
    if (_vesting < _cliff) {
      throw;
    }

    TokenGrant memory grant = TokenGrant(msg.sender, _value, _cliff, _vesting, _start);
    grants[_to].push(grant);

    transfer(_to, _value);
  }

  function revokeTokenGrant(address _holder, uint _grantId) {
    TokenGrant grant = grants[_holder][_grantId];

    if (grant.granter != msg.sender) {
      throw;
    }
    uint256 nonVested = nonVestedTokens(grant, uint64(now));

    // remove grant from array
    delete grants[_holder][_grantId];
    grants[_holder][_grantId] = grants[_holder][grants[_holder].length - 1];
    grants[_holder].length -= 1;

    balances[msg.sender] = safeAdd(balances[msg.sender], nonVested);
    balances[_holder] = safeSub(balances[_holder], nonVested);
    Transfer(_holder, msg.sender, nonVested);
  }

  function tokenGrantsCount(address _holder) constant returns (uint index) {
    return grants[_holder].length;
  }

  function tokenGrant(address _holder, uint _grantId) constant returns (address granter, uint256 value, uint256 vested, uint64 start, uint64 cliff, uint64 vesting) {
    TokenGrant grant = grants[_holder][_grantId];

    granter = grant.granter;
    value = grant.value;
    start = grant.start;
    cliff = grant.cliff;
    vesting = grant.vesting;

    vested = vestedTokens(grant, uint64(now));
  }

  function vestedTokens(TokenGrant grant, uint64 time) private constant returns (uint256) {
    return calculateVestedTokens(
      grant.value,
      uint256(time),
      uint256(grant.start),
      uint256(grant.cliff),
      uint256(grant.vesting)
    );
  }

  function calculateVestedTokens(
    uint256 tokens,
    uint256 time,
    uint256 start,
    uint256 cliff,
    uint256 vesting) constant returns (uint256 vestedTokens)
    {

    if (time < cliff) {
      return 0;
    }
    if (time > vesting) {
      return tokens;
    }

    uint256 cliffTokens = safeDiv(safeMul(tokens, safeSub(cliff, start)), safeSub(vesting, start));
    vestedTokens = cliffTokens;

    uint256 vestingTokens = safeSub(tokens, cliffTokens);

    vestedTokens = safeAdd(vestedTokens, safeDiv(safeMul(vestingTokens, safeSub(time, cliff)), safeSub(vesting, start)));
  }

  function nonVestedTokens(TokenGrant grant, uint64 time) private constant returns (uint256) {
    return safeSub(grant.value, vestedTokens(grant, time));
  }

  function lastTokenIsTransferableDate(address holder) constant public returns (uint64 date) {
    date = uint64(now);
    uint256 grantIndex = grants[holder].length;
    for (uint256 i = 0; i < grantIndex; i++) {
      date = max64(grants[holder][i].vesting, date);
    }
  }

  function transferableTokens(address holder, uint64 time) constant public returns (uint256 nonVested) {
    uint256 grantIndex = grants[holder].length;
    for (uint256 i = 0; i < grantIndex; i++) {
      nonVested = safeAdd(nonVested, nonVestedTokens(grants[holder][i], time));
    }

    return min256(safeSub(balances[holder], nonVested), super.transferableTokens(holder, time));
  }
}


Explicitly cast `this` to address

Explicitly cast `this` to address

import "Rules.sol";
import "TicTacToeAdjudicator.sol";

/* Board state values are as follows:
 *  0 | 1 | 2
 *  ---------
 *  3 | 4 | 5
 *  ---------
 *  6 | 7 | 8
 *
 * 9: 4 if last player was O, 1 if the last player was X
 */
contract TicTacToeRules is Rules {

    event StateSent(bytes state);
    event Cheating(address cheater);
    event BoardWinner(address winner);
    event CheckedIn();

    uint constant BLANK = 0;
    uint constant X = 1;
    uint constant O = 4;

    address addressX;
    address addressO;
    uint timeout;

    /**
     * Creates a new TicTacToeRules
     * _addressX: the address of X
     * _addressO: the address of O
     * _timeout: the timeout before state can be closed
     */
    function TicTacToeRules(address _addressX, address _addressO, uint _timeout) {
        addressX = _addressX;
        addressO = _addressO;
        timeout = _timeout;
        adjudicator = createAdjudicator();
    }

    function createAdjudicator() internal returns (Adjudicator newAdjudicator) {
        newAdjudicator = new TicTacToeAdjudicator(addressX, addressO, timeout);
        delete timeout;
    }

    // Converts a grid coordinate to an index value
    function gridToIndex(uint x, uint y) constant internal returns (uint) {
        return x + 3*y;
    }

    /**
     * Send a state directly to the underlying state channel.
     * Allows for transactions to be closed without any adjudication fees.
     *
     * state: the state that will be sent
     * nonce: the nonce that will be sent
     * the rest are signature values for X and O, respectively
     * returns: true if state sent sucessfully, otherwise false
     */
    function sendState(
        bytes state,
        uint nonce,
        uint8 vX,
        bytes32 rX,
        bytes32 sX,
        uint8 vO,
        bytes32 rO,
        bytes32 sO
    ) external returns (bool) {
        uint8[] memory v = new uint8[](2);
        bytes32[] memory r = new bytes32[](2);
        bytes32[] memory s = new bytes32[](2);

        v[0] = vX;
        v[1] = vO;
        r[0] = rX;
        r[1] = rO;
        s[0] = sX;
        s[1] = sO;

        if (adjudicator.close(2, state, nonce, v, r, s)) {
            StateSent(state);
            return true;
        } else {
            return false;
        }
    }

    /**
     * Sends a unilateral ruling (0 signatures required) to underlying adjudicator.
     *
     * uintState: the state which will be sent
     * nonce: the nonce which will be sent
     * returns: true if the state was sent successfully, otherwise false
     */
    function unilateralRuling(uint8 uintState, uint nonce) internal returns (bool) {
        bytes memory state = new bytes(1);
        state[0] = byte(uintState);
        adjudicator.close(0, state, nonce, new uint8[](1), new bytes32[](1), new bytes32[](1));
    }

    /**
     * Sends a board to be adjudicated upon.
     *
     * board: the board to be adjudicated upon
     * nonce: the nonce that will be used
     * v, r, s: X's signature if last player was X, O's signature if last player was O
     * returns: true if adjudication was sucessful, otherwise false
     */
    function sendBoard(
        bytes10 board,
        uint nonce,
        uint8 v,
        bytes32 r,
        bytes32 s
    ) external returns (bool) {
        uint x;
        uint y;
        uint i;
        uint8 uintState = uint(board[9]) == X ? 0x28 : 0x14;// by default, the person who didn't play will lose all deposits

        if (
            !((uint(board[9]) == X && addressX == ecrecover(sha3(board, nonce, address(this)), v, r, s))
            || (uint(board[9]) == O && addressO == ecrecover(sha3(board, nonce, address(this)), v, r, s)))
        ) {
            return false;
        }

        // do something about what happens if you send old boards???

        // checking wins
        // checking |
        for (x = 0; x < 3; x++) {
            i = 0;
            for (y = 0; y < 3; y++) {
                i += uint(board[gridToIndex(x, y)]);
            }
            if (i == X * 3) {
                if (unilateralRuling(uintState | 0x01, nonce)) {// give X the bet winnings
                    BoardWinner(addressX);
                    return true;
                } else {
                    return false;
                }
            } else if (i == O * 3) {
                if (unilateralRuling(uintState | 0x02, nonce)) {// give O the bet winnings
                    BoardWinner(addressO);
                    return true;
                } else {
                    return false;
                }
            }
        }

        // checking -
        for (y = 0; y < 3; y++) {
            i = 0;
            for (x = 0; x < 3; x++) {
                i += uint(board[gridToIndex(x, y)]);
            }
            if (i == X * 3) {
                if (unilateralRuling(uintState | 0x01, nonce)) {
                    BoardWinner(addressX);
                    return true;
                } else {
                    return false;
                }
            } else if (i == O * 3) {
                if (unilateralRuling(uintState | 0x02, nonce)) {
                    BoardWinner(addressO);
                    return true;
                } else {
                    return false;
                }
            }
        }

        // checking \
        i = 0;
        for (x = 0; x < 3; x++) {
            i += uint(board[gridToIndex(x, x)]);
        }
        if (i == X * 3) {
            if (unilateralRuling(uintState | 0x01, nonce)) {
                BoardWinner(addressX);
                return true;
            } else {
                return false;
            }
        } else if (i == O * 3) {
            if (unilateralRuling(uintState | 0x02, nonce)) {
                BoardWinner(addressO);
                return true;
            } else {
                return false;
            }
        }

        // checking /
        i = 0;
        for (x = 0; x < 3; x++) {
            i += uint(board[gridToIndex(x, 2 - x)]);
        }
        if (i == X * 3) {
            if (unilateralRuling(uintState | 0x01, nonce)) {
                BoardWinner(addressX);
                return true;
            } else {
                return false;
            }
        } else if (i == O * 3) {
            if (unilateralRuling(uintState | 0x02, nonce)) {
                BoardWinner(addressO);
                return true;
            } else {
                return false;
            }
        }

        // check if tie
        for (i = 0; i < 9; i++) {
            if (uint(board[i]) == BLANK) {
                // last player wins
                if (unilateralRuling(uintState | uint(board[9]) == X ? 0x01 : 0x02, nonce)) {// bets sent to last player
                    BoardWinner(uint(board[9]) == X ? addressX : addressO);
                    return true;
                } else {
                    return false;
                }
            }
        }
        // it is a tie
        if (unilateralRuling(uintState, nonce)) {// if tie, bets returned
            BoardWinner(0);
            return true;
        } else {
            return false;
        }
    }

    /**
     * Punishes a sender for sending an errornous board.
     *
     * oldBoard: the old board to be compared against
     * oldNonce: the old nonce to verify the old board
     * oldV, oldR, oldS: the signature for oldBoard, from the last player
     * newBoard: the new board which has an error
     * newNonce: the new nonce of newBoard
     * newV, newR, newS: the signatures for newBoard, from the last player
     */
    function badBoardSent(
        bytes10 oldBoard,
        uint oldNonce,
        uint8 oldV,
        bytes32 oldR,
        bytes32 oldS,
        bytes10 newBoard,
        uint newNonce,
        uint8 newV,
        bytes32 newR,
        bytes32 newS
    ) external returns (bool) {
        address signer = uint(newBoard[9]) == X ? addressX : addressO;
        // verify the integrity of the boards
        if (
            oldNonce >= newNonce ||
            !(signer == ecrecover(sha3(oldBoard, oldNonce, address(this)), oldV, oldR, oldS) &&
            signer == ecrecover(sha3(newBoard, newNonce, address(this)), newV, newR, newS))
        ) {
            return false;
        }

        bool notChanged = true;
        for (uint i = 0; i < 9; i++) {
            if (oldBoard[i] == newBoard[i]) {
                continue;
            }
            if ((uint(newBoard[i]) == X || uint(newBoard[i]) == O) && (uint(oldBoard[i]) == BLANK) && notChanged && (newBoard[i] == newBoard[9])) {
                notChanged = false;
                continue;
            }
            // shenanigans
            if (unilateralRuling(uint(newBoard[9]) == X ? 0x5E : 0x6D, newNonce)) {
                Cheating(uint(newBoard[9]) == X ? addressX : addressO);
                return true;
            } else {
                return false;
            }
        }
        if (notChanged && unilateralRuling(uint(newBoard[9]) == X ? 0x5E : 0x6D, newNonce)) {
            // shenanigans
            Cheating(uint(newBoard[9]) == X ? addressX : addressO);
            return true;
        } else {
            // nothing fishy
            return false;
        }
    }

    /**
     * Lets the contract know that you have not disconnected.
     * Will modify the state such that the disconnect deposits will be
     * refunded and both party's adjudication deposits will be lost.
     *
     * returns: true if sucessful, otherwise false
     */
    function checkIn() external returns (bool) {
        uint8 uintState = uint8(adjudicator.getStateAt(0));

        // does not work if someone has cheated or if adjudicator wasn't used
        if (uintState & 0x40 != 0x00 || uintState & 0x3C == 0x00) {
            return false;
        }
        if (unilateralRuling(uintState & 0xCF | 0x0C, adjudicator.getNonce())) {
            CheckedIn();
            return true;
        } else {
            return false;
        }
    }
}

import "Rules.sol";
import "TicTacToeAdjudicator.sol";

/* Board state values are as follows:
 *  0 | 1 | 2
 *  ---------
 *  3 | 4 | 5
 *  ---------
 *  6 | 7 | 8
 *
 * 9: 4 if last player was O, 1 if the last player was X
 */
contract TicTacToeRules is Rules {

    event StateSent(bytes state);
    event Cheating(address cheater);
    event BoardWinner(address winner);
    event CheckedIn();

    uint constant BLANK = 0;
    uint constant X = 1;
    uint constant O = 4;

    address addressX;
    address addressO;
    uint timeout;

    /**
     * Creates a new TicTacToeRules
     * _addressX: the address of X
     * _addressO: the address of O
     * _timeout: the timeout before state can be closed
     */
    function TicTacToeRules(address _addressX, address _addressO, uint _timeout) {
        addressX = _addressX;
        addressO = _addressO;
        timeout = _timeout;
        adjudicator = createAdjudicator();
    }

    function createAdjudicator() internal returns (Adjudicator newAdjudicator) {
        newAdjudicator = new TicTacToeAdjudicator(addressX, addressO, timeout);
        delete timeout;
    }

    // Converts a grid coordinate to an index value
    function gridToIndex(uint x, uint y) constant internal returns (uint) {
        return x + 3*y;
    }

    /**
     * Send a state directly to the underlying state channel.
     * Allows for transactions to be closed without any adjudication fees.
     *
     * state: the state that will be sent
     * nonce: the nonce that will be sent
     * the rest are signature values for X and O, respectively
     * returns: true if state sent sucessfully, otherwise false
     */
    function sendState(
        bytes state,
        uint nonce,
        uint8 vX,
        bytes32 rX,
        bytes32 sX,
        uint8 vO,
        bytes32 rO,
        bytes32 sO
    ) external returns (bool) {
        uint8[] memory v = new uint8[](2);
        bytes32[] memory r = new bytes32[](2);
        bytes32[] memory s = new bytes32[](2);

        v[0] = vX;
        v[1] = vO;
        r[0] = rX;
        r[1] = rO;
        s[0] = sX;
        s[1] = sO;

        if (adjudicator.close(2, state, nonce, v, r, s)) {
            StateSent(state);
            return true;
        } else {
            return false;
        }
    }

    /**
     * Sends a unilateral ruling (0 signatures required) to underlying adjudicator.
     *
     * uintState: the state which will be sent
     * nonce: the nonce which will be sent
     * returns: true if the state was sent successfully, otherwise false
     */
    function unilateralRuling(uint8 uintState, uint nonce) internal returns (bool) {
        bytes memory state = new bytes(1);
        state[0] = byte(uintState);
        adjudicator.close(0, state, nonce, new uint8[](1), new bytes32[](1), new bytes32[](1));
    }

    /**
     * Sends a board to be adjudicated upon.
     *
     * board: the board to be adjudicated upon
     * nonce: the nonce that will be used
     * v, r, s: X's signature if last player was X, O's signature if last player was O
     * returns: true if adjudication was sucessful, otherwise false
     */
    function sendBoard(
        bytes10 board,
        uint nonce,
        uint8 v,
        bytes32 r,
        bytes32 s
    ) external returns (bool) {
        uint x;
        uint y;
        uint i;
        uint8 uintState = uint(board[9]) == X ? 0x28 : 0x14;// by default, the person who didn't play will lose all deposits

        if (
            !((uint(board[9]) == X && addressX == ecrecover(sha3(board, nonce, address(this)), v, r, s))
            || (uint(board[9]) == O && addressO == ecrecover(sha3(board, nonce, address(this)), v, r, s)))
        ) {
            return false;
        }

        // do something about what happens if you send old boards???

        // checking wins
        // checking |
        for (x = 0; x < 3; x++) {
            i = 0;
            for (y = 0; y < 3; y++) {
                i += uint(board[gridToIndex(x, y)]);
            }
            if (i == X * 3) {
                if (unilateralRuling(uintState | 0x01, nonce)) {// give X the bet winnings
                    BoardWinner(addressX);
                    return true;
                } else {
                    return false;
                }
            } else if (i == O * 3) {
                if (unilateralRuling(uintState | 0x02, nonce)) {// give O the bet winnings
                    BoardWinner(addressO);
                    return true;
                } else {
                    return false;
                }
            }
        }

        // checking -
        for (y = 0; y < 3; y++) {
            i = 0;
            for (x = 0; x < 3; x++) {
                i += uint(board[gridToIndex(x, y)]);
            }
            if (i == X * 3) {
                if (unilateralRuling(uintState | 0x01, nonce)) {
                    BoardWinner(addressX);
                    return true;
                } else {
                    return false;
                }
            } else if (i == O * 3) {
                if (unilateralRuling(uintState | 0x02, nonce)) {
                    BoardWinner(addressO);
                    return true;
                } else {
                    return false;
                }
            }
        }

        // checking \
        i = 0;
        for (x = 0; x < 3; x++) {
            i += uint(board[gridToIndex(x, x)]);
        }
        if (i == X * 3) {
            if (unilateralRuling(uintState | 0x01, nonce)) {
                BoardWinner(addressX);
                return true;
            } else {
                return false;
            }
        } else if (i == O * 3) {
            if (unilateralRuling(uintState | 0x02, nonce)) {
                BoardWinner(addressO);
                return true;
            } else {
                return false;
            }
        }

        // checking /
        i = 0;
        for (x = 0; x < 3; x++) {
            i += uint(board[gridToIndex(x, 2 - x)]);
        }
        if (i == X * 3) {
            if (unilateralRuling(uintState | 0x01, nonce)) {
                BoardWinner(addressX);
                return true;
            } else {
                return false;
            }
        } else if (i == O * 3) {
            if (unilateralRuling(uintState | 0x02, nonce)) {
                BoardWinner(addressO);
                return true;
            } else {
                return false;
            }
        }

        // check if tie
        for (i = 0; i < 9; i++) {
            if (uint(board[i]) == BLANK) {
                // last player wins
                if (unilateralRuling(uintState | uint(board[9]) == X ? 0x01 : 0x02, nonce)) {// bets sent to last player
                    BoardWinner(uint(board[9]) == X ? addressX : addressO);
                    return true;
                } else {
                    return false;
                }
            }
        }
        // it is a tie
        if (unilateralRuling(uintState, nonce)) {// if tie, bets returned
            BoardWinner(0);
            return true;
        } else {
            return false;
        }
    }

    /**
     * Punishes a sender for sending an errornous board.
     *
     * oldBoard: the old board to be compared against
     * oldNonce: the old nonce to verify the old board
     * oldV, oldR, oldS: the signature for oldBoard, from the last player
     * newBoard: the new board which has an error
     * newNonce: the new nonce of newBoard
     * newV, newR, newS: the signatures for newBoard, from the last player
     */
    function badBoardSent(
        bytes10 oldBoard,
        uint oldNonce,
        uint8 oldV,
        bytes32 oldR,
        bytes32 oldS,
        bytes10 newBoard,
        uint newNonce,
        uint8 newV,
        bytes32 newR,
        bytes32 newS
    ) external returns (bool) {
        address signer = uint(newBoard[9]) == X ? addressX : addressO;
        // verify the integrity of the boards
        if (
            oldNonce >= newNonce ||
            !(signer == ecrecover(sha3(oldBoard, oldNonce, this), oldV, oldR, oldS) &&
            signer == ecrecover(sha3(newBoard, newNonce, this), newV, newR, newS))
        ) {
            return false;
        }

        bool notChanged = true;
        for (uint i = 0; i < 9; i++) {
            if (oldBoard[i] == newBoard[i]) {
                continue;
            }
            if ((uint(newBoard[i]) == X || uint(newBoard[i]) == O) && (uint(oldBoard[i]) == BLANK) && notChanged && (newBoard[i] == newBoard[9])) {
                notChanged = false;
                continue;
            }
            // shenanigans
            if (unilateralRuling(uint(newBoard[9]) == X ? 0x5E : 0x6D, newNonce)) {
                Cheating(uint(newBoard[9]) == X ? addressX : addressO);
                return true;
            } else {
                return false;
            }
        }
        if (notChanged && unilateralRuling(uint(newBoard[9]) == X ? 0x5E : 0x6D, newNonce)) {
            // shenanigans
            Cheating(uint(newBoard[9]) == X ? addressX : addressO);
            return true;
        } else {
            // nothing fishy
            return false;
        }
    }

    /**
     * Lets the contract know that you have not disconnected.
     * Will modify the state such that the disconnect deposits will be
     * refunded and both party's adjudication deposits will be lost.
     *
     * returns: true if sucessful, otherwise false
     */
    function checkIn() external returns (bool) {
        uint8 uintState = uint8(adjudicator.getStateAt(0));

        // does not work if someone has cheated or if adjudicator wasn't used
        if (uintState & 0x40 != 0x00 || uintState & 0x3C == 0x00) {
            return false;
        }
        if (unilateralRuling(uintState & 0xCF | 0x0C, adjudicator.getNonce())) {
            CheckedIn();
            return true;
        } else {
            return false;
        }
    }
}


legacy SafeSend

legacy SafeSend

pragma solidity ^0.4.22;

contract OldSafeSend {
  address public recipient;

  constructor(address _recipient) payable {
    recipient = _recipient;
  }

  function deliver() {
    selfdestruct(recipient);
  }
}

error: pathspec 'packages/truffle-core/lib/testing/OldSafeSend.sol' did not match any file(s) known to git


fixed docstrings in nettingchannelcontract

pragma solidity ^0.4.0;

import "./NettingChannelLibrary.sol";

contract NettingChannelContract {
    using NettingChannelLibrary for NettingChannelLibrary.Data;
    NettingChannelLibrary.Data public data;

    event ChannelNewBalance(address token_address, address participant, uint balance, uint block_number);
    event ChannelClosed(address closing_address, uint block_number);
    event TransferUpdated(address node_address, uint block_number);
    event ChannelSettled(uint block_number);
    event ChannelSecretRevealed(bytes32 secret);

    modifier settleTimeoutNotTooLow(uint t) {
        if (t < 6) throw;
        _;
    }

    function NettingChannelContract(
        address token_address,
        address participant1,
        address participant2,
        uint timeout)
        settleTimeoutNotTooLow(timeout)
    {
        if (participant1 == participant2) {
            throw;
        }

        data.participants[0].node_address = participant1;
        data.participants[1].node_address = participant2;

        data.token = Token(token_address);
        data.settle_timeout = timeout;
    }

    /// @notice Caller makes a deposit into their channel balance.
    /// @param amount The amount caller wants to deposit.
    /// @return True if deposit is successful.
    function deposit(uint256 amount) returns (bool) {
        bool success;
        uint256 balance;

        (success, balance) = data.deposit(msg.sender, this, amount);

        if (success == true) {
            ChannelNewBalance(data.token, msg.sender, balance, data.opened);
        }

        return success;
    }

    /// @notice Get the address of the channel partner.
    /// @param participant_address The address of one participant.
    /// @return The address of the partner to that participant.
    function partner(address participant_address) constant returns (address) {
        return data.partner(participant_address);
    }

    /// @notice Get the address and balance of both partners in a channel.
    /// @return The address and balance pairs.
    function addressAndBalance()
        constant
        returns (
        address participant1,
        uint balance1,
        address participant2,
        uint balance2)
    {
        return data.addressAndBalance();
    }

    /// @notice Get the amount one partner has transferred to the other partner.
    /// @param participant The address of one partner.
    /// @return The amount one partner has transferred to the other.
    function transferredAmount(address participant) constant returns (uint) {
        return data.transferredAmount(participant);
    }

    /// @notice Close the channel. Can only be called by a participant in the channel.
    /// @param theirs_encoded The last transfer recieved from our partner.
    /// @param ours_encoded The last transfer sent to our partner.
    function close(bytes theirs_encoded, bytes ours_encoded) {
        data.close(msg.sender, theirs_encoded, ours_encoded);
        ChannelClosed(msg.sender, data.closed);
    }

    /// @notice Dispute the state after closing, called by the counterparty (the
    ///         participant who did not close the channel).
    /// @param theirs_encoded The transfer the counterparty believes is the valid
    ///                       state of the first participant.
    function updateTransfer(bytes theirs_encoded) {
        data.updateTransfer(msg.sender, theirs_encoded);
        TransferUpdated(msg.sender, block.number);
    }

    /// @notice Unlock a locked transfer.
    function unlock(bytes locked_encoded, bytes merkle_proof, bytes32 secret) {
        data.unlock(msg.sender, locked_encoded, merkle_proof, secret);
        ChannelSecretRevealed(secret);
    }

    /// @notice Settle the transfers and balances of the channel and pay out to
    ///         each participant. Can only be called after the channel is closed
    ///         and only after the number of blocks in the settlement timeout
    ///         have passed.
    function settle() {
        data.settle(msg.sender);
        ChannelSettled(data.settled);
    }

    /// @notice Returns the number of blocks until the settlement timeout.
    function settleTimeout() constant returns (uint) {
        return data.settle_timeout;
    }

    /// @notice Returns the address of the token.
    function tokenAddress() constant returns (address) {
        return data.token;
    }

    /// @notice Returns the block number for when the channel was opened.
    function opened() constant returns (uint) {
        return data.opened;
    }

    /// @notice Returns the block number for when the channel was closed.
    function closed() constant returns (uint) {
        return data.closed;
    }

    /// @notice Returns the block number for when the channel was settled.
    function settled() constant returns (uint) {
        return data.settled;
    }

    /// @notice Returns the address of the closing participant.
    function closingAddress() constant returns (address) {
        return data.closing_address;
    }

    function () { throw; }
}

pragma solidity ^0.4.0;

import "./NettingChannelLibrary.sol";

contract NettingChannelContract {
    using NettingChannelLibrary for NettingChannelLibrary.Data;
    NettingChannelLibrary.Data public data;

    event ChannelNewBalance(address token_address, address participant, uint balance, uint block_number);
    event ChannelClosed(address closing_address, uint block_number);
    event TransferUpdated(address node_address, uint block_number);
    event ChannelSettled(uint block_number);
    event ChannelSecretRevealed(bytes32 secret);

    modifier settleTimeoutNotTooLow(uint t) {
        if (t < 6) throw;
        _;
    }

    function NettingChannelContract(
        address token_address,
        address participant1,
        address participant2,
        uint timeout)
        settleTimeoutNotTooLow(timeout)
    {
        if (participant1 == participant2) {
            throw;
        }

        data.participants[0].node_address = participant1;
        data.participants[1].node_address = participant2;

        data.token = Token(token_address);
        data.settle_timeout = timeout;
    }

    /// @notice Caller makes a deposit into their channel balance.
    /// @param amount The amount caller wants to deposit.
    /// @return True if deposit is successful.
    function deposit(uint256 amount) returns (bool) {
        bool success;
        uint256 balance;

        (success, balance) = data.deposit(msg.sender, this, amount);

        if (success == true) {
            ChannelNewBalance(data.token, msg.sender, balance, data.opened);
        }

        return success;
    }

    /// @notice Get the address of the channel partner.
    /// @param one_address The address of partner 1.
    /// @return The address of partner 2.
    function partner(address one_address) constant returns (address) {
        return data.partner(one_address);
    }

    /// @notice Get the address and balance of both partners in a channel.
    /// @return The address and balance pairs.
    function addressAndBalance()
        constant
        returns (
        address participant1,
        uint balance1,
        address participant2,
        uint balance2)
    {
        return data.addressAndBalance();
    }

    /// @notice Get the amount one partner has sent/transferred to the other partner.
    /// @param participant The address of one partner.
    /// @return The amount one partner has sent to the other.
    function transferredAmount(address participant) constant returns (uint) {
        return data.transferredAmount(participant);
    }

    /// @notice Close the channel. Can only be called by a participant in the channel.
    /// @param theirs_encoded The state of the partner's transfers.
    /// @param ours_encoded The state of the caller's transfers.
    function close(bytes theirs_encoded, bytes ours_encoded) {
        data.close(msg.sender, theirs_encoded, ours_encoded);
        ChannelClosed(msg.sender, data.closed);
    }

    /// @notice Dispute the state after closing, called by a counterparty (the
    ///         participant who did not close the channel).
    /// @param theirs_encoded The transfer the counterparty believes is the valid
    ///                       state of the first participant.
    function updateTransfer(bytes theirs_encoded) {
        data.updateTransfer(msg.sender, theirs_encoded);
        TransferUpdated(msg.sender, block.number);
    }

    /// @notice Unlock a locked transfer.
    function unlock(bytes locked_encoded, bytes merkle_proof, bytes32 secret) {
        data.unlock(msg.sender, locked_encoded, merkle_proof, secret);
        ChannelSecretRevealed(secret);
    }

    /// @notice Settle the transfers and balances of the channel and pay out to
    ///         each participant. Must be called by a participating address.
    function settle() {
        data.settle(msg.sender);
        ChannelSettled(data.settled);
    }

    /// @notice Returns the number of blocks until the settlement timeout.
    function settleTimeout() constant returns (uint) {
        return data.settle_timeout;
    }

    /// @notice Returns the address of the token.
    function tokenAddress() constant returns (address) {
        return data.token;
    }

    /// @notice Returns the block number for when the channel was opened.
    function opened() constant returns (uint) {
        return data.opened;
    }

    /// @notice Returns the block number for when the channel was closed.
    function closed() constant returns (uint) {
        return data.closed;
    }

    /// @notice Returns the block number for when the channel was settled.
    function settled() constant returns (uint) {
        return data.settled;
    }

    /// @notice Returns the address of the closing participant.
    function closingAddress() constant returns (address) {
        return data.closing_address;
    }

    /// @notice All other attempted functions are thrown. (Wasted gas.)
    function () { throw; }
}


Remove old reentrancy example

Remove old reentrancy example

contract Reentrancy {

  mapping(address => uint) public balances;

  function donate(address _to) public payable {
    balances[_to] += msg.value;
  }

  function balanceOf(address _who) public constant returns (uint balance) {
    return balances[_who];
  }

  function withdraw(uint _amount) public {
    if(balances[msg.sender] >= _amount) {
      if (msg.sender.call.value(_amount)()) {
        balances[msg.sender] -= _amount;
      }
    }
  }

  function() payable {}
}


Space for poetry

Space for poetry

pragma solidity ^0.4.11;

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

contract Registry {

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

    event _Application(string domain, uint deposit);
    event _Challenge(string domain, uint deposit, uint pollID);
    event _Deposit(string domain, uint added, uint newTotal);
    event _Withdrawal(string domain, uint withdrew, uint newTotal);
    event _NewDomainWhitelisted(string domain);
    event _ApplicationRemoved(string domain);
    event _ListingRemoved(string domain);
    event _ChallengeFailed(uint challengeID);
    event _ChallengeSucceeded(uint challengeID);
    event _RewardClaimed(address voter, uint challengeID, uint reward);

    struct Listing {
        uint applicationExpiry; // expiration date of apply stage
        bool whitelisted;       // indicates registry status
        address owner;          // owner of Listing
        uint currentDeposit;    // number of tokens staked
        uint challengeID;       // identifier of canonical challenge
    }

    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 challengeIDs to associated challenge data
    mapping(uint => Challenge) public challengeMap;
    // maps domainHashes to associated listing data
    mapping(bytes32 => Listing) public listingMap;
    // maps challengeIDs and address to token claim data
    mapping(uint => mapping(address => bool)) public tokenClaims;

    // Global Variables
    StandardToken public token;
    PLCRVoting public voting;
    Parameterizer public parameterizer;

    // ------------
    // CONSTRUCTOR:
    // ------------

    function Registry(
        address _tokenAddr,
        address _paramsAddr
    ) {
        token = StandardToken(_tokenAddr);
        parameterizer = Parameterizer(_paramsAddr);
        voting = new PLCRVoting(_tokenAddr);
    }

    // --------------------
    // PUBLISHER INTERFACE:
    // --------------------

    //Allow a user to start an application
    //take tokens from user and set apply stage end time
    function apply(string domain, uint amount) external {
        require(!isWhitelisted(domain));
        require(!appExists(domain));
        require(amount >= parameterizer.get("minDeposit"));

        //set owner
        Listing storage listing = listingMap[sha3(domain)];
        listing.owner = msg.sender;

        //transfer tokens
        require(token.transferFrom(listing.owner, this, amount));

        //set apply stage end time
        listing.applicationExpiry = block.timestamp + parameterizer.get("applyStageLen");
        listing.currentDeposit = amount;

        _Application(domain, amount);
    }

    //Allow the owner of a domain in the listing to increase their deposit
    function deposit(string domain, uint amount) external {
        Listing storage listing = listingMap[sha3(domain)];

        require(listing.owner == msg.sender);
        require(token.transferFrom(msg.sender, this, amount));

        listing.currentDeposit += amount;

        _Deposit(domain, amount, listing.currentDeposit);
    }

    //Allow the owner of a domain in the listing to withdraw
    //tokens not locked in a challenge.
    //The publisher's domain remains whitelisted
    function withdraw(string domain, uint amount) external {
        Listing storage listing = listingMap[sha3(domain)];

        require(listing.owner == msg.sender);
        require(amount <= listing.currentDeposit);
        require(listing.currentDeposit - amount >= parameterizer.get("minDeposit"));

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

        listing.currentDeposit -= amount;

        _Withdrawal(domain, amount, listing.currentDeposit);
    }

    //Allow the owner of a domain to remove the domain from the whitelist
    //Return all tokens to the owner
    function exit(string domain) external {
        Listing storage listing = listingMap[sha3(domain)];

        require(msg.sender == listing.owner);
        require(isWhitelisted(domain));
        // cannot exit during ongoing challenge
        require(listing.challengeID == 0 || challengeMap[listing.challengeID].resolved);

        //remove domain & return tokens
        resetListing(domain);
    }

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

    //start a poll for a domain in the apply stage or already on the whitelist
    //tokens are taken from the challenger and the publisher's tokens are locked
    function challenge(string domain) external returns (uint challengeID) {
        bytes32 domainHash = sha3(domain);
        Listing storage listing = listingMap[domainHash];
        //to be challenged, domain must be in apply stage or already on the whitelist
        require(appExists(domain) || listing.whitelisted);
        // prevent multiple challenges
        require(listing.challengeID == 0 || challengeMap[listing.challengeID].resolved);
        uint deposit = parameterizer.get("minDeposit");
        if (listing.currentDeposit < deposit) {
            // not enough tokens, publisher auto-delisted
            resetListing(domain);
            return 0;
        }
        //take tokens from challenger
        require(token.transferFrom(msg.sender, this, deposit));
        //start poll
        uint pollID = voting.startPoll(
            parameterizer.get("voteQuorum"),
            parameterizer.get("commitPeriodLen"),
            parameterizer.get("revealPeriodLen")
        );

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

        listingMap[domainHash].challengeID = pollID;      // update listing to store most recent challenge
        listingMap[domainHash].currentDeposit -= deposit; // lock tokens for listing during challenge

        _Challenge(domain, deposit, pollID);
        return pollID;
    }

    // whitelist domain if apply stage ended without a challenge
    function updateStatus(string domain) public {
        bytes32 domainHash = sha3(domain);
        uint challengeID = listingMap[domainHash].challengeID;
        require(!challengeMap[challengeID].resolved);  // require processed flag to be false
        // IF NO CHALLENGE AFTER APPLY STAGE
        if (challengeID == 0 && isExpired(listingMap[domainHash].applicationExpiry)) {
            listingMap[domainHash].whitelisted = true;
            _NewDomainWhitelisted(domain);
        } else {
            // PROCESS THE RESULT OF THE POLL
            // winner gets back their full staked deposit, and dispensationPct*loser's stake
            // (1-dispensationPct)*loser's stake = rewardPool
            uint stake = 2*challengeMap[challengeID].stake - challengeMap[challengeID].rewardPool;
            bool wasWhitelisted = isWhitelisted(domain);
            // if voting is not yet over, isPassed will throw
            if (voting.isPassed(challengeID)) {
                listingMap[domainHash].whitelisted = true;
                listingMap[domainHash].currentDeposit += stake; // give stake back to applicant

                _ChallengeFailed(challengeID);
                if (!wasWhitelisted) {
                  _NewDomainWhitelisted(domain);
                }
            } else {
                resetListing(domain); // whitelisted = false
                require(token.transfer(challengeMap[challengeID].challenger, stake)); // give stake to challenger
                _ChallengeSucceeded(challengeID);
                if (wasWhitelisted) {
                  _ListingRemoved(domain);
                } else {
                  _ApplicationRemoved(domain);
                }
            }

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

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

    // ----------------
    // TOKEN FUNCTIONS:
    // ----------------

    // called by voter to claim reward for each completed vote
    // someone must call updateStatus() before this can be called
    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;

        _RewardClaimed(msg.sender, _challengeID, reward);
    }

    /**
    @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;
    }

    // --------
    // HELPERS:
    // --------

    //return true if domain is whitelisted
    function isWhitelisted(string domain) constant public returns (bool whitelisted) {
        return listingMap[sha3(domain)].whitelisted;
    }

    //return true if apply(domain) was called for this domain
    function appExists(string domain) constant public returns (bool exists) {
        return listingMap[sha3(domain)].applicationExpiry > 0;
    }

    //return true if termDate has passed
    function isExpired(uint termDate) constant public returns (bool expired) {
        return termDate < block.timestamp;
    }

    //delete listing from whitelist and return tokens to owner
    function resetListing(string domain) internal {
        bytes32 domainHash = sha3(domain);
        Listing storage listing = listingMap[domainHash];
        //transfer any remaining balance back to the owner
        if (listing.currentDeposit > 0)
            require(token.transfer(listing.owner, listing.currentDeposit));
        delete listingMap[domainHash];
    }
}


Remove excess spaces.

Remove excess spaces.

pragma solidity ^0.4.11;

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

contract Registry {

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

    event _Application(string domain, uint deposit);
    event _Challenge(string domain, uint deposit, uint pollID);
    event _Deposit(string domain, uint added, uint newTotal);
    event _Withdrawal(string domain, uint withdrew, uint newTotal);
    event _NewDomainWhitelisted(string domain);
    event _ApplicationRemoved(string domain);
    event _ListingRemoved(string domain);
    event _ChallengeFailed(uint challengeID);
    event _ChallengeSucceeded(uint challengeID);
    event _RewardClaimed(address voter, uint challengeID, uint reward);

    struct Listing {
        uint applicationExpiry; // expiration date of apply stage
        bool whitelisted;       // indicates registry status
        address owner;          // owner of Listing
        uint currentDeposit;    // number of tokens staked
        uint challengeID;       // identifier of canonical challenge
    }

    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 challengeIDs to associated challenge data
    mapping(uint => Challenge) public challengeMap;
    // maps domainHashes to associated listing data
    mapping(bytes32 => Listing) public listingMap;
    // maps challengeIDs and address to token claim data
    mapping(uint => mapping(address => bool)) public tokenClaims;

    // Global Variables
    StandardToken public token;
    PLCRVoting public voting;
    Parameterizer public parameterizer;

    // ------------
    // CONSTRUCTOR:
    // ------------

    function Registry(
        address _tokenAddr,
        address _paramsAddr
    ) {
        token = StandardToken(_tokenAddr);
        parameterizer = Parameterizer(_paramsAddr);
        voting = new PLCRVoting(_tokenAddr);
    }

    // --------------------
    // PUBLISHER INTERFACE:
    // --------------------

    //Allow a user to start an application
    //take tokens from user and set apply stage end time
    function apply(string domain, uint amount) external {
        require(!isWhitelisted(domain));
        require(!appExists(domain));
        require(amount >= parameterizer.get("minDeposit"));

        //set owner
        Listing storage listing = listingMap[sha3(domain)];
        listing.owner = msg.sender;

        //transfer tokens
        require(token.transferFrom(listing.owner, this, amount));

        //set apply stage end time
        listing.applicationExpiry = block.timestamp + parameterizer.get("applyStageLen");
        listing.currentDeposit = amount;

        _Application(domain, amount);
    }

    //Allow the owner of a domain in the listing to increase their deposit
    function deposit(string domain, uint amount) external {
        Listing storage listing = listingMap[sha3(domain)];

        require(listing.owner == msg.sender);
        require(token.transferFrom(msg.sender, this, amount));

        listing.currentDeposit += amount;

        _Deposit(domain, amount, listing.currentDeposit);
    }

    //Allow the owner of a domain in the listing to withdraw
    //tokens not locked in a challenge.
    //The publisher's domain remains whitelisted
    function withdraw(string domain, uint amount) external {
        Listing storage listing = listingMap[sha3(domain)];

        require(listing.owner == msg.sender);
        require(amount <= listing.currentDeposit);
        require(listing.currentDeposit - amount >= parameterizer.get("minDeposit"));

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

        listing.currentDeposit -= amount;

        _Withdrawal(domain, amount, listing.currentDeposit);
    }

    //Allow the owner of a domain to remove the domain from the whitelist
    //Return all tokens to the owner
    function exit(string domain) external {
        Listing storage listing = listingMap[sha3(domain)];

        require(msg.sender == listing.owner);
        require(isWhitelisted(domain));
        // cannot exit during ongoing challenge
        require(listing.challengeID == 0 || challengeMap[listing.challengeID].resolved);

        //remove domain & return tokens
        resetListing(domain);
    }

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

    //start a poll for a domain in the apply stage or already on the whitelist
    //tokens are taken from the challenger and the publisher's tokens are locked
    function challenge(string domain) external returns (uint challengeID) {
        bytes32 domainHash = sha3(domain);
        Listing storage listing = listingMap[domainHash];
        //to be challenged, domain must be in apply stage or already on the whitelist
        require(appExists(domain) || listing.whitelisted);
        // prevent multiple challenges
        require(listing.challengeID == 0 || challengeMap[listing.challengeID].resolved);
        uint deposit = parameterizer.get("minDeposit");
        if (listing.currentDeposit < deposit) {
            // not enough tokens, publisher auto-delisted
            resetListing(domain);
            return 0;
        }
        //take tokens from challenger
        require(token.transferFrom(msg.sender, this, deposit));
        //start poll
        uint pollID = voting.startPoll(
            parameterizer.get("voteQuorum"),
            parameterizer.get("commitPeriodLen"),
            parameterizer.get("revealPeriodLen")
        );

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

        listingMap[domainHash].challengeID = pollID;      // update listing to store most recent challenge
        listingMap[domainHash].currentDeposit -= deposit; // lock tokens for listing during challenge

        _Challenge(domain, deposit, pollID);
        return pollID;
    }

    // whitelist domain if apply stage ended without a challenge
    function updateStatus(string domain) public {
        bytes32 domainHash = sha3(domain);
        uint challengeID = listingMap[domainHash].challengeID;
        require(!challengeMap[challengeID].resolved);  // require processed flag to be false
        // IF NO CHALLENGE AFTER APPLY STAGE
        if (challengeID == 0 && isExpired(listingMap[domainHash].applicationExpiry)) {
            listingMap[domainHash].whitelisted = true;
            _NewDomainWhitelisted(domain);
        } else {
            // PROCESS THE RESULT OF THE POLL
            // winner gets back their full staked deposit, and dispensationPct*loser's stake
            // (1-dispensationPct)*loser's stake = rewardPool
            uint stake = 2*challengeMap[challengeID].stake - challengeMap[challengeID].rewardPool;
            bool wasWhitelisted = isWhitelisted(domain);
            // if voting is not yet over, isPassed will throw
            if (voting.isPassed(challengeID)) {
                listingMap[domainHash].whitelisted = true;
                listingMap[domainHash].currentDeposit += stake; // give stake back to applicant

                _ChallengeFailed(challengeID);
                if (!wasWhitelisted) {
                  _NewDomainWhitelisted(domain);
                }
            } else {
                resetListing(domain); // whitelisted = false
                require(token.transfer(challengeMap[challengeID].challenger, stake)); // give stake to challenger
                _ChallengeSucceeded(challengeID);
                if (wasWhitelisted) {
                  _ListingRemoved(domain);
                } else {
                  _ApplicationRemoved(domain);
                }
            }

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

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

    // ----------------
    // TOKEN FUNCTIONS:
    // ----------------

    // called by voter to claim reward for each completed vote
    // someone must call updateStatus() before this can be called
    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;

        _RewardClaimed(msg.sender, _challengeID, reward);
    }

    /**
    @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;
    }

    // --------
    // HELPERS:
    // --------

    //return true if domain is whitelisted
    function isWhitelisted(string domain) constant public returns (bool whitelisted) {
        return listingMap[sha3(domain)].whitelisted;
    }

    //return true if apply(domain) was called for this domain
    function appExists(string domain) constant public returns (bool exists) {
        return listingMap[sha3(domain)].applicationExpiry > 0;
    }

    //return true if termDate has passed
    function isExpired(uint termDate) constant public returns (bool expired) {
        return termDate < block.timestamp;
    }

    //delete listing from whitelist and return tokens to owner
    function resetListing(string domain) internal {
        bytes32 domainHash = sha3(domain);
        Listing storage listing = listingMap[domainHash];
        //transfer any remaining balance back to the owner
        if (listing.currentDeposit > 0)
            require(token.transfer(listing.owner, listing.currentDeposit));
        delete listingMap[domainHash];
    }
}


Added Order value

Added Order value

pragma solidity ^0.4.8;

import "./Exchange.sol";
import "./tokens/ChainXToken.sol";
import "./base/Token.sol";
import "./base/Ownable.sol";
import "./base/SafeMath.sol";

contract SimpleCrowdsale is Ownable, SafeMath {

    address public PROXY_ADDRESS;
    address public EXCHANGE_ADDRESS;
    address public PROTOCOL_TOKEN_ADDRESS;
    address public CHX_TOKEN_ADDRESS;

    Exchange exchange;
    Token protocolToken;
    ChainXToken chxToken;

    bool public isInitialized;
    bool public isFinished;
    Order order;

    struct Order {
        address maker;
        address taker;
        address tokenM;
        address tokenT;
        address feeRecipient;
        uint valueM;
        uint valueT;
        uint feeM;
        uint feeT;
        uint expiration;
        uint salt;
        uint8 v;
        bytes32 r;
        bytes32 s;
        bytes32 orderHash;
    }

    modifier saleInitialized() {
        assert(isInitialized);
        _;
    }

    modifier saleNotInitialized() {
        assert(!isInitialized);
        _;
    }

    modifier saleNotFinished() {
        assert(!isFinished);
        _;
    }

    function SimpleCrowdsale(
        address _exchange,
        address _proxy,
        address _protocolToken,
        address _chxToken)
    {
        PROXY_ADDRESS = _proxy;
        EXCHANGE_ADDRESS = _exchange;
        PROTOCOL_TOKEN_ADDRESS = _protocolToken;
        ChainX_TOKEN_ADDRESS = _chxToken;

        exchange = Exchange(_exchange);
        protocolToken = Token(_protocolToken);
        Token = CHXToken(_chxToken);
    }

    /// @dev Allows users to fill stored order by sending ChainX to contract.
    function()
        payable
        saleInitialized
        saleNotFinished
    {
        uint remainingChx = safeSub(order.valueT, exchange.getUnavailableValueT(order.orderHash));
        uint chxToFill = min(msg.value, remainingChx);
        chxToken.deposit.value(chxToFill)();
        assert(exchange.fillOrKill(
            [order.maker, order.taker, order.tokenM, order.tokenT, order.feeRecipient],
            [order.valueM, order.valueT, order.feeM, order.feeT, order.expiration, order.salt],
            chxToFill,
            order.v,
            order.r,
            order.s
        ));
        uint filledProtocolToken = safeDiv(safeMul(order.valueM, chxToFill), order.valueT);
        assert(protocolToken.transfer(msg.sender, filledProtocolToken));
        if (chxToFill < msg.value) {
            assert(msg.sender.send(safeSub(msg.value, chxToFill)));
            isFinished = true;
        }
    }

    /// @dev Stores order and initializes sale.
    /// @param orderAddresses Array of order's maker, taker, tokenM, tokenT, and feeRecipient.
    /// @param orderValues Array of order's valueM, valueT, feeM, feeT, expiration, and salt.
    /// @param v ECDSA signature parameter v.
    /// @param r CDSA signature parameters r.
    /// @param s CDSA signature parameters s.
    function init(
        address[5] orderAddresses,
        uint[6] orderValues,
        uint8 v,
        bytes32 r,
        bytes32 s)
        saleNotInitialized
        onlyOwner
    {
        order = Order({
            maker: orderAddresses[0],
            taker: orderAddresses[1],
            tokenM: orderAddresses[2],
            tokenT: orderAddresses[3],
            feeRecipient: orderAddresses[4],
            valueM: orderValues[0],
            valueT: orderValues[1],
            feeM: orderValues[2],
            feeT: orderValues[3],
            expiration: orderValues[4],
            salt: orderValues[5],
            feeT: orderValues[6]
            feeT: orderValues[7]
            v: v,
            r: r,
            s: s,
            orderHash: getOrderHash(orderAddresses, orderValues)
        });

        assert(order.tokenM == PROTOCOL_TOKEN_ADDRESS);
        assert(order.tokenT == CHX_TOKEN_ADDRESS);

        assert(isValidSignature(
            order.maker,
            order.orderHash,
            v,
            r,
            s
        ));

        assert(setTokenAllowance(order.tokenT, order.valueT));
        isInitialized = true;
    }

    function setTokenAllowance(address _token, uint _allowance)
        onlyOwner
        returns (bool success)
    {
        assert(Token(_token).approve(PROXY_ADDRESS, _allowance));
        return true;
    }

    /// @dev Calculates Keccak-256 hash of order with specified parameters.
    /// @param orderAddresses Array of order's maker, taker, tokenM, tokenT, and feeRecipient.
    /// @param orderValues Array of order's valueM, valueT, feeM, feeT, expiration, and salt.
    /// @return Keccak-256 hash of order.
    function getOrderHash(address[5] orderAddresses, uint[6] orderValues)
        constant
        returns (bytes32 orderHash)
    {
        return sha3(
            EXCHANGE_ADDRESS,
            orderAddresses[0],
            orderAddresses[1],
            orderAddresses[2],
            orderAddresses[3],
            orderAddresses[4],
            orderValues[0],
            orderValues[1],
            orderValues[2],
            orderValues[3],
            orderValues[4],
            orderValues[5]
        );
    }

    /// @dev Verifies that an order signature is valid.
    /// @param pubKey Public address of signer.
    /// @param hash Signed Keccak-256 hash.
    /// @param v ECDSA signature parameter v.
    /// @param r ECDSA signature parameters r.
    /// @param s ECDSA signature parameters s.
    /// @return Validity of order signature.
    function isValidSignature(
        address pubKey,
        bytes32 hash,
        uint8 v,
        bytes32 r,
        bytes32 s)
        constant
        returns (bool isValid)
    {
        return pubKey == ecrecover(
            sha3("\x19CHX Signed Message:\n32", hash),
            v,
            r,
            s
        );
    }

    /// @dev Calculates minimum of two values.
    /// @param a First value.
    /// @param b Second value.
    /// @return Minimum of values.
    function min(uint a, uint b)
        constant
        returns (uint min)
    {
        if (a < b) return a;
        return b;
    }
}

pragma solidity ^0.4.8;

import "./Exchange.sol";
import "./tokens/ChainXToken.sol";
import "./base/Token.sol";
import "./base/Ownable.sol";
import "./base/SafeMath.sol";

contract SimpleCrowdsale is Ownable, SafeMath {

    address public PROXY_ADDRESS;
    address public EXCHANGE_ADDRESS;
    address public PROTOCOL_TOKEN_ADDRESS;
    address public CHX_TOKEN_ADDRESS;

    Exchange exchange;
    Token protocolToken;
    ChainXToken chxToken;

    bool public isInitialized;
    bool public isFinished;
    Order order;

    struct Order {
        address maker;
        address taker;
        address tokenM;
        address tokenT;
        address feeRecipient;
        uint valueM;
        uint valueT;
        uint feeM;
        uint feeT;
        uint expiration;
        uint salt;
        uint8 v;
        bytes32 r;
        bytes32 s;
        bytes32 orderHash;
    }

    modifier saleInitialized() {
        assert(isInitialized);
        _;
    }

    modifier saleNotInitialized() {
        assert(!isInitialized);
        _;
    }

    modifier saleNotFinished() {
        assert(!isFinished);
        _;
    }

    function SimpleCrowdsale(
        address _exchange,
        address _proxy,
        address _protocolToken,
        address _chxToken)
    {
        PROXY_ADDRESS = _proxy;
        EXCHANGE_ADDRESS = _exchange;
        PROTOCOL_TOKEN_ADDRESS = _protocolToken;
        ChainX_TOKEN_ADDRESS = _chxToken;

        exchange = Exchange(_exchange);
        protocolToken = Token(_protocolToken);
        Token = CHXToken(_chxToken);
    }

    /// @dev Allows users to fill stored order by sending ChainX to contract.
    function()
        payable
        saleInitialized
        saleNotFinished
    {
        uint remainingChx = safeSub(order.valueT, exchange.getUnavailableValueT(order.orderHash));
        uint chxToFill = min(msg.value, remainingChx);
        chxToken.deposit.value(chxToFill)();
        assert(exchange.fillOrKill(
            [order.maker, order.taker, order.tokenM, order.tokenT, order.feeRecipient],
            [order.valueM, order.valueT, order.feeM, order.feeT, order.expiration, order.salt],
            chxToFill,
            order.v,
            order.r,
            order.s
        ));
        uint filledProtocolToken = safeDiv(safeMul(order.valueM, chxToFill), order.valueT);
        assert(protocolToken.transfer(msg.sender, filledProtocolToken));
        if (chxToFill < msg.value) {
            assert(msg.sender.send(safeSub(msg.value, chxToFill)));
            isFinished = true;
        }
    }

    /// @dev Stores order and initializes sale.
    /// @param orderAddresses Array of order's maker, taker, tokenM, tokenT, and feeRecipient.
    /// @param orderValues Array of order's valueM, valueT, feeM, feeT, expiration, and salt.
    /// @param v ECDSA signature parameter v.
    /// @param r CDSA signature parameters r.
    /// @param s CDSA signature parameters s.
    function init(
        address[5] orderAddresses,
        uint[6] orderValues,
        uint8 v,
        bytes32 r,
        bytes32 s)
        saleNotInitialized
        onlyOwner
    {
        order = Order({
            maker: orderAddresses[0],
            taker: orderAddresses[1],
            tokenM: orderAddresses[2],
            tokenT: orderAddresses[3],
            feeRecipient: orderAddresses[4],
            valueM: orderValues[0],
            valueT: orderValues[1],
            feeM: orderValues[2],
            feeT: orderValues[3],
            expiration: orderValues[4],
            salt: orderValues[5],
            feeT: orderValues[6]
            v: v,
            r: r,
            s: s,
            orderHash: getOrderHash(orderAddresses, orderValues)
        });

        assert(order.tokenM == PROTOCOL_TOKEN_ADDRESS);
        assert(order.tokenT == CHX_TOKEN_ADDRESS);

        assert(isValidSignature(
            order.maker,
            order.orderHash,
            v,
            r,
            s
        ));

        assert(setTokenAllowance(order.tokenT, order.valueT));
        isInitialized = true;
    }

    function setTokenAllowance(address _token, uint _allowance)
        onlyOwner
        returns (bool success)
    {
        assert(Token(_token).approve(PROXY_ADDRESS, _allowance));
        return true;
    }

    /// @dev Calculates Keccak-256 hash of order with specified parameters.
    /// @param orderAddresses Array of order's maker, taker, tokenM, tokenT, and feeRecipient.
    /// @param orderValues Array of order's valueM, valueT, feeM, feeT, expiration, and salt.
    /// @return Keccak-256 hash of order.
    function getOrderHash(address[5] orderAddresses, uint[6] orderValues)
        constant
        returns (bytes32 orderHash)
    {
        return sha3(
            EXCHANGE_ADDRESS,
            orderAddresses[0],
            orderAddresses[1],
            orderAddresses[2],
            orderAddresses[3],
            orderAddresses[4],
            orderValues[0],
            orderValues[1],
            orderValues[2],
            orderValues[3],
            orderValues[4],
            orderValues[5]
        );
    }

    /// @dev Verifies that an order signature is valid.
    /// @param pubKey Public address of signer.
    /// @param hash Signed Keccak-256 hash.
    /// @param v ECDSA signature parameter v.
    /// @param r ECDSA signature parameters r.
    /// @param s ECDSA signature parameters s.
    /// @return Validity of order signature.
    function isValidSignature(
        address pubKey,
        bytes32 hash,
        uint8 v,
        bytes32 r,
        bytes32 s)
        constant
        returns (bool isValid)
    {
        return pubKey == ecrecover(
            sha3("\x19CHX Signed Message:\n32", hash),
            v,
            r,
            s
        );
    }

    /// @dev Calculates minimum of two values.
    /// @param a First value.
    /// @param b Second value.
    /// @return Minimum of values.
    function min(uint a, uint b)
        constant
        returns (uint min)
    {
        if (a < b) return a;
        return b;
    }
}


change sha3 and suicide methods to keccak256 and selfdestruct

see ethereum/solidity#1476

pragma solidity ^0.4.8;

import "./ownership/Multisig.sol";
import "./ownership/Shareable.sol";
import "./DayLimit.sol";

/*
 * MultisigWallet
 * usage:
 * bytes32 h = Wallet(w).from(oneOwner).execute(to, value, data);
 * Wallet(w).from(anotherOwner).confirm(h);
 */
contract MultisigWallet is Multisig, Shareable, DayLimit {

  struct Transaction {
    address to;
    uint value;
    bytes data;
  }

  function MultisigWallet(address[] _owners, uint _required, uint _daylimit)
    Shareable(_owners, _required)
    DayLimit(_daylimit) { }

  // kills the contract sending everything to `_to`.
  function kill(address _to) onlymanyowners(keccak256(msg.data)) external {
    selfdestruct(_to);
  }

  // gets called when no other function matches
  function() payable {
    // just being sent some cash?
    if (msg.value > 0)
      Deposit(msg.sender, msg.value);
  }

  // Outside-visible transact entry point. Executes transaction immediately if below daily spend limit.
  // If not, goes into multisig process. We provide a hash on return to allow the sender to provide
  // shortcuts for the other confirmations (allowing them to avoid replicating the _to, _value
  // and _data arguments). They still get the option of using them if they want, anyways.
  function execute(address _to, uint _value, bytes _data) external onlyOwner returns (bytes32 _r) {
    // first, take the opportunity to check that we're under the daily limit.
    if (underLimit(_value)) {
      SingleTransact(msg.sender, _value, _to, _data);
      // yes - just execute the call.
      if (!_to.call.value(_value)(_data)) {
        throw;
      }
      return 0;
    }
    // determine our operation hash.
    _r = keccak256(msg.data, block.number);
    if (!confirm(_r) && txs[_r].to == 0) {
      txs[_r].to = _to;
      txs[_r].value = _value;
      txs[_r].data = _data;
      ConfirmationNeeded(_r, msg.sender, _value, _to, _data);
    }
  }

  // confirm a transaction through just the hash. we use the previous transactions map, txs, in order
  // to determine the body of the transaction from the hash provided.
  function confirm(bytes32 _h) onlymanyowners(_h) returns (bool) {
    if (txs[_h].to != 0) {
      if (!txs[_h].to.call.value(txs[_h].value)(txs[_h].data)) {
        throw;
      }
      MultiTransact(msg.sender, _h, txs[_h].value, txs[_h].to, txs[_h].data);
      delete txs[_h];
      return true;
    }
  }

  function setDailyLimit(uint _newLimit) onlymanyowners(keccak256(msg.data)) external {
    _setDailyLimit(_newLimit);
  }

  function resetSpentToday() onlymanyowners(keccak256(msg.data)) external {
    _resetSpentToday();
  }

  // INTERNAL METHODS

  function clearPending() internal {
    uint length = pendingsIndex.length;
    for (uint i = 0; i < length; ++i) {
      delete txs[pendingsIndex[i]];
    }
    super.clearPending();
  }

  // FIELDS

  // pending transactions we have at present.
  mapping (bytes32 => Transaction) txs;
}

pragma solidity ^0.4.8;

import "./ownership/Multisig.sol";
import "./ownership/Shareable.sol";
import "./DayLimit.sol";

/*
 * MultisigWallet
 * usage:
 * bytes32 h = Wallet(w).from(oneOwner).execute(to, value, data);
 * Wallet(w).from(anotherOwner).confirm(h);
 */
contract MultisigWallet is Multisig, Shareable, DayLimit {

  struct Transaction {
    address to;
    uint value;
    bytes data;
  }

  function MultisigWallet(address[] _owners, uint _required, uint _daylimit)
    Shareable(_owners, _required)
    DayLimit(_daylimit) { }

  // kills the contract sending everything to `_to`.
  function kill(address _to) onlymanyowners(sha3(msg.data)) external {
    suicide(_to);
  }

  // gets called when no other function matches
  function() payable {
    // just being sent some cash?
    if (msg.value > 0)
      Deposit(msg.sender, msg.value);
  }

  // Outside-visible transact entry point. Executes transaction immediately if below daily spend limit.
  // If not, goes into multisig process. We provide a hash on return to allow the sender to provide
  // shortcuts for the other confirmations (allowing them to avoid replicating the _to, _value
  // and _data arguments). They still get the option of using them if they want, anyways.
  function execute(address _to, uint _value, bytes _data) external onlyOwner returns (bytes32 _r) {
    // first, take the opportunity to check that we're under the daily limit.
    if (underLimit(_value)) {
      SingleTransact(msg.sender, _value, _to, _data);
      // yes - just execute the call.
      if (!_to.call.value(_value)(_data)) {
        throw;
      }
      return 0;
    }
    // determine our operation hash.
    _r = sha3(msg.data, block.number);
    if (!confirm(_r) && txs[_r].to == 0) {
      txs[_r].to = _to;
      txs[_r].value = _value;
      txs[_r].data = _data;
      ConfirmationNeeded(_r, msg.sender, _value, _to, _data);
    }
  }

  // confirm a transaction through just the hash. we use the previous transactions map, txs, in order
  // to determine the body of the transaction from the hash provided.
  function confirm(bytes32 _h) onlymanyowners(_h) returns (bool) {
    if (txs[_h].to != 0) {
      if (!txs[_h].to.call.value(txs[_h].value)(txs[_h].data)) {
        throw;
      }
      MultiTransact(msg.sender, _h, txs[_h].value, txs[_h].to, txs[_h].data);
      delete txs[_h];
      return true;
    }
  }

  function setDailyLimit(uint _newLimit) onlymanyowners(sha3(msg.data)) external {
    _setDailyLimit(_newLimit);
  }

  function resetSpentToday() onlymanyowners(sha3(msg.data)) external {
    _resetSpentToday();
  }

  // INTERNAL METHODS

  function clearPending() internal {
    uint length = pendingsIndex.length;
    for (uint i = 0; i < length; ++i) {
      delete txs[pendingsIndex[i]];
    }
    super.clearPending();
  }

  // FIELDS

  // pending transactions we have at present.
  mapping (bytes32 => Transaction) txs;
}


Remove wrong comment.

Remove wrong comment.

pragma solidity ^0.4.15;

import './SafeMath.sol';
import './Ownable.sol';
import './KinToken.sol';

/// @title Vesting trustee contract for Kin token.
contract VestingTrustee is Ownable {
    using SafeMath for uint256;

    // Kin token contract.
    KinToken public kin;

    // Vesting grant for a speicifc holder.
    struct Grant {
        uint256 value;
        uint256 start;
        uint256 cliff;
        uint256 end;
        uint256 installmentLength; // In seconds.
        uint256 transferred;
        bool revokable;
    }

    // Holder to grant information mapping.
    mapping (address => Grant) public grants;

    // Total tokens available for vesting.
    uint256 public totalVesting;

    event NewGrant(address indexed _from, address indexed _to, uint256 _value);
    event TokensUnlocked(address indexed _to, uint256 _value);
    event GrantRevoked(address indexed _holder, uint256 _refund);

    /// @dev Constructor that initializes the address of the Kin token contract.
    /// @param _kin KinToken The address of the previously deployed Kin token contract.
    function VestingTrustee(KinToken _kin) {
        require(_kin != address(0));

        kin = _kin;
    }

    /// @dev Grant tokens to a specified address. Please note, that the trustee must have enough ungranted tokens to
    /// accomodate the new grant. Otherwise, the call with fail.
    /// @param _to address The holder address.
    /// @param _value uint256 The amount of tokens to be granted.
    /// @param _start uint256 The beginning of the vesting period.
    /// @param _cliff uint256 Duration of the cliff period (when the first installment is made).
    /// @param _end uint256 The end of the vesting period.
    /// @param _installmentLength uint256 The length of each vesting installment (in seconds).
    /// @param _revokable bool Whether the grant is revokable or not.
    function grant(address _to, uint256 _value, uint256 _start, uint256 _cliff, uint256 _end,
        uint256 _installmentLength, bool _revokable)
        external onlyOwner {

        require(_to != address(0));
        require(_to != address(this)); // Protect this contract from receiving a grant.
        require(_value > 0);

        // Require that every holder can be granted tokens only once.
        require(grants[_to].value == 0);

        // Require for time ranges to be consistent and valid.
        require(_start <= _cliff && _cliff <= _end);

        // Require installment length to be valid and no longer than (end - start).
        require(_installmentLength > 0 && _installmentLength <= _end.sub(_start));

        // Grant must not exceed the total amount of tokens currently available for vesting.
        require(totalVesting.add(_value) <= kin.balanceOf(address(this)));

        // Assign a new grant.
        grants[_to] = Grant({
            value: _value,
            start: _start,
            cliff: _cliff,
            end: _end,
            installmentLength: _installmentLength,
            transferred: 0,
            revokable: _revokable
        });

        // Since tokens have been granted, reduce the total amount available for vesting.
        totalVesting = totalVesting.add(_value);

        NewGrant(msg.sender, _to, _value);
    }

    /// @dev Revoke the grant of tokens of a specifed address.
    /// @param _holder The address which will have its tokens revoked.
    function revoke(address _holder) public onlyOwner {
        Grant memory grant = grants[_holder];

        // Grant must be revokable.
        require(grant.revokable);

        // Calculate amount of remaining tokens that can still be returned.
        uint256 refund = grant.value.sub(grant.transferred);

        // Remove the grant.
        delete grants[_holder];

        // Update total vesting amount and transfer previously calculated tokens to owner.
        totalVesting = totalVesting.sub(refund);
        kin.transfer(msg.sender, refund);

        GrantRevoked(_holder, refund);
    }

    /// @dev Calculate the total amount of vested tokens of a holder at a given time.
    /// @param _holder address The address of the holder.
    /// @param _time uint256 The specific time to calculate against.
    /// @return a uint256 Representing a holder's total amount of vested tokens.
    function vestedTokens(address _holder, uint256 _time) external constant returns (uint256) {
        Grant memory grant = grants[_holder];
        if (grant.value == 0) {
            return 0;
        }

        return calculateVestedTokens(grant, _time);
    }

    /// @dev Calculate amount of vested tokens at a specifc time.
    /// @param _grant Grant The vesting grant.
    /// @param _time uint256 The time to be checked
    /// @return An uint256 Representing the amount of vested tokens of a specific grant.
    function calculateVestedTokens(Grant _grant, uint256 _time) private constant returns (uint256) {
        // If we're before the cliff, then nothing is vested.
        if (_time < _grant.cliff) {
            return 0;
        }

        // If we're after the end of the vesting period - everything is vested;
        if (_time >= _grant.end) {
            return _grant.value;
        }

        // Calculate amount of installments past until now.
        //
        // NOTE result gets floored because of integer division.
        uint256 installmentsPast = _time.sub(_grant.start).div(_grant.installmentLength);

        // Calculate amount of days in entire vesting period.
        uint256 vestingDays = _grant.end.sub(_grant.start);

        // Calculate and return the number of tokens according to vesting days that have passed.
        return _grant.value.mul(installmentsPast.mul(_grant.installmentLength)).div(vestingDays);
    }

    /// @dev Unlock vested tokens and transfer them to the grantee.
    function unlockVestedTokens() external {
        Grant storage grant = grants[msg.sender];

        // Make sure the grant has tokens available.
        require(grant.value != 0);

        // Get the total amount of vested tokens, acccording to grant.
        uint256 vested = calculateVestedTokens(grant, now);
        if (vested == 0) {
            return;
        }

        // Make sure the holder doesn't transfer more than what he already has.
        uint256 transferable = vested.sub(grant.transferred);
        if (transferable == 0) {
            return;
        }

        // Update transferred and total vesting amount, then transfer remaining vested funds to holder.
        grant.transferred = grant.transferred.add(transferable);
        totalVesting = totalVesting.sub(transferable);
        kin.transfer(msg.sender, transferable);

        TokensUnlocked(msg.sender, transferable);
    }
}

pragma solidity ^0.4.15;

import './SafeMath.sol';
import './Ownable.sol';
import './KinToken.sol';

/// @title Vesting trustee contract for Kin token.
contract VestingTrustee is Ownable {
    using SafeMath for uint256;

    // Kin token contract.
    KinToken public kin;

    // Vesting grant for a speicifc holder.
    struct Grant {
        uint256 value;
        uint256 start;
        uint256 cliff;
        uint256 end;
        uint256 installmentLength; // In seconds.
        uint256 transferred;
        bool revokable;
    }

    // Holder to grant information mapping.
    mapping (address => Grant) public grants;

    // Total tokens available for vesting.
    uint256 public totalVesting;

    event NewGrant(address indexed _from, address indexed _to, uint256 _value);
    event TokensUnlocked(address indexed _to, uint256 _value);
    event GrantRevoked(address indexed _holder, uint256 _refund);

    /// @dev Constructor that initializes the address of the Kin token contract.
    /// @param _kin KinToken The address of the previously deployed Kin token contract.
    function VestingTrustee(KinToken _kin) {
        require(_kin != address(0));

        kin = _kin;
    }

    /// @dev Grant tokens to a specified address. Please note, that the trustee must have enough ungranted tokens to
    /// accomodate the new grant. Otherwise, the call with fail.
    /// @param _to address The holder address.
    /// @param _value uint256 The amount of tokens to be granted.
    /// @param _start uint256 The beginning of the vesting period.
    /// @param _cliff uint256 Duration of the cliff period (when the first installment is made).
    /// @param _end uint256 The end of the vesting period.
    /// @param _installmentLength uint256 The length of each vesting installment (in seconds).
    /// @param _revokable bool Whether the grant is revokable or not.
    function grant(address _to, uint256 _value, uint256 _start, uint256 _cliff, uint256 _end,
        uint256 _installmentLength, bool _revokable)
        external onlyOwner {

        require(_to != address(0));
        require(_to != address(this)); // Protect this contract from receiving a grant.
        require(_value > 0);

        // Require that every holder can be granted tokens only once.
        require(grants[_to].value == 0);

        // Require for time ranges to be consistent and valid.
        require(_start <= _cliff && _cliff <= _end);

        // Require installment length to be valid and no longer than (end - start).
        require(_installmentLength > 0 && _installmentLength <= _end.sub(_start));

        // Grant must not exceed the total amount of tokens currently available for vesting.
        require(totalVesting.add(_value) <= kin.balanceOf(address(this)));

        // Assign a new grant.
        grants[_to] = Grant({
            value: _value,
            start: _start,
            cliff: _cliff,
            end: _end,
            installmentLength: _installmentLength,
            transferred: 0,
            revokable: _revokable
        });

        // Since tokens have been granted, reduce the total amount available for vesting.
        totalVesting = totalVesting.add(_value);

        NewGrant(msg.sender, _to, _value);
    }

    /// @dev Revoke the grant of tokens of a specifed address.
    /// @param _holder The address which will have its tokens revoked.
    function revoke(address _holder) public onlyOwner {
        Grant memory grant = grants[_holder];

        // Grant must be revokable.
        require(grant.revokable);

        // Calculate amount of remaining tokens that can still be returned.
        uint256 refund = grant.value.sub(grant.transferred);

        // Remove the grant.
        delete grants[_holder];

        // Update total vesting amount and transfer previously calculated tokens to owner.
        totalVesting = totalVesting.sub(refund);
        kin.transfer(msg.sender, refund);

        GrantRevoked(_holder, refund);
    }

    /// @dev Calculate the total amount of vested tokens of a holder at a given time.
    /// @param _holder address The address of the holder.
    /// @param _time uint256 The specific time to calculate against.
    /// @return a uint256 Representing a holder's total amount of vested tokens.
    function vestedTokens(address _holder, uint256 _time) external constant returns (uint256) {
        Grant memory grant = grants[_holder];
        if (grant.value == 0) {
            return 0;
        }

        return calculateVestedTokens(grant, _time);
    }

    /// @dev Calculate amount of vested tokens at a specifc time.
    /// @param _grant Grant The vesting grant.
    /// @param _time uint256 The time to be checked
    /// @return An uint256 Representing the amount of vested tokens of a specific grant.
    function calculateVestedTokens(Grant _grant, uint256 _time) private constant returns (uint256) {
        // If we're before the cliff, then nothing is vested.
        if (_time < _grant.cliff) {
            return 0;
        }

        // If we're after the end of the vesting period - everything is vested;
        if (_time >= _grant.end) {
            return _grant.value;
        }

        // Calculate amount of installments past until now.
        //
        // NOTE result gets floored because of integer division.
        uint256 installmentsPast = _time.sub(_grant.start).div(_grant.installmentLength);

        // Calculate amount of days in entire vesting period.
        uint256 vestingDays = _grant.end.sub(_grant.start);

        // Calculate and return the number of tokens according to vesting days that have passed.
        return _grant.value.mul(installmentsPast.mul(_grant.installmentLength)).div(vestingDays);
    }

    /// @dev Unlock vested tokens and transfer them to the grantee.
    /// @return a uint256 Representing the amount of vested tokens transferred to their holder.
    function unlockVestedTokens() external {
        Grant storage grant = grants[msg.sender];

        // Make sure the grant has tokens available.
        require(grant.value != 0);

        // Get the total amount of vested tokens, acccording to grant.
        uint256 vested = calculateVestedTokens(grant, now);
        if (vested == 0) {
            return;
        }

        // Make sure the holder doesn't transfer more than what he already has.
        uint256 transferable = vested.sub(grant.transferred);
        if (transferable == 0) {
            return;
        }

        // Update transferred and total vesting amount, then transfer remaining vested funds to holder.
        grant.transferred = grant.transferred.add(transferable);
        totalVesting = totalVesting.sub(transferable);
        kin.transfer(msg.sender, transferable);

        TokensUnlocked(msg.sender, transferable);
    }
}