arbiter should not vote

arbiter should not vote

pragma solidity ^0.4.11;

import './governanceInterface.sol';

contract Bet is ProposalInterface{

  modifier onlyOwner() {
    require(msg.sender == owner);
    _;
  }
  modifier onlyArbiter() {
    require(msg.sender == address(arbiter));
    _;
  }
  modifier beforeMatchBegun() {
    require(block.timestamp < timestampMatchBegin);
    _;
  }
  modifier afterMatchEnded() {
    require(block.timestamp >= timestampMatchEnd);
    _;
  }
  modifier beforeResolverCanCall() {
    require(block.timestamp < timestampArbiterDeadline);
    _;
  }
  modifier matchIsOpenOrUndecided() {
    require(betState == BET_STATES.OPEN || betState == BET_STATES.UNDECIDED);
    _;
  }
  modifier matchIsDecided() {
    require(betState == BET_STATES.TEAM_ZERO_WON ||
            betState == BET_STATES.TEAM_ONE_WON ||
            betState == BET_STATES.DRAW);
    _;
  }
  modifier betInSomeTeam() {
    require(betsToTeam0[msg.sender] > 0 || betsToTeam1[msg.sender] > 0);
    _;
  }

  enum BET_STATES {
    OPEN,
    TEAM_ZERO_WON,
    TEAM_ONE_WON,
    DRAW,
    UNDECIDED
    }

  BET_STATES public betState = BET_STATES.OPEN;
  address public owner; // Can be a parent contract
  GovernanceInterface public arbiter; // Governance account
  bool public isFeatured;
  string public team0Name;
  string public team1Name;
  string public description;
  string public category;
  uint public team0BetSum;
  uint public team1BetSum;
  mapping (address => uint) public betsToTeam0;
  mapping (address => uint) public betsToTeam1;

  uint public timestampMatchBegin;
  uint public timestampMatchEnd;
  // Self-destruct is possible if time > timestampArbiterDeadline
  uint public timestampArbiterDeadline;

  uint8 constant TAX = 10;
  uint constant TIMESTAMP_MARGIN = 1000;

  event NewBet(bool for_team, address from, uint amount);
  event StateChanged(BET_STATES state);

  function Bet(GovernanceInterface _arbiter, string _team0Name,
               string _team1Name, string _category,
               uint[] _timestamps
               ) {
    require(block.timestamp < _timestamps[0]);
    require(_timestamps[0] < _timestamps[1]);
    require(_timestamps[1] < _timestamps[2]);

    isFeatured = false;
    owner = msg.sender;
    arbiter = _arbiter;
    team0Name = _team0Name;
    team1Name = _team1Name;
    category = _category;
    timestampMatchBegin = _timestamps[0] - TIMESTAMP_MARGIN;
    timestampMatchEnd = _timestamps[1] + TIMESTAMP_MARGIN;
    timestampArbiterDeadline = _timestamps[2] + TIMESTAMP_MARGIN;
  }

  function __resolve(uint outcome)
    onlyArbiter()
    afterMatchEnded()
    beforeResolverCanCall()
    matchIsOpenOrUndecided() {

    if (outcome == 1)
      betState = BET_STATES.TEAM_ZERO_WON;
    else if (outcome == 2)
      betState = BET_STATES.TEAM_ONE_WON;
    else if (outcome == 3)
      betState = BET_STATES.DRAW;
    else
      betState = BET_STATES.UNDECIDED;
    StateChanged(betState);
  }

  // Will create a Proposal on the arbiter
  function updateResult() payable
    matchIsOpenOrUndecided()
    afterMatchEnded() {
    arbiter.addProposal(this, timestampArbiterDeadline);
  }

  function toggleFeatured() onlyOwner() {
    isFeatured = !isFeatured;
  }

  function modifyCategory(string newCategory) onlyOwner() {
    category = newCategory;
  }

  //
  function bet(bool forTeam) payable
    beforeMatchBegun() {
    require(msg.sender != address(arbiter));
    uint prevSum;

    if (forTeam == false) {
      // Cannot bet in two teams
      require(betsToTeam1[msg.sender] == 0);
      prevSum = team0BetSum;
      require((prevSum + msg.value) >= prevSum); // Overflow
      team0BetSum += msg.value;
      assert(team0BetSum >= prevSum);
      betsToTeam0[msg.sender] += msg.value;
    }
    else {
      // Cannot bet in two teams
      require(betsToTeam0[msg.sender] == 0);
      prevSum = team1BetSum;
      require((prevSum + msg.value) >= prevSum); // Overflow
      team1BetSum += msg.value;
      assert(team1BetSum >= prevSum);
      betsToTeam1[msg.sender] += msg.value;
    }

    NewBet(forTeam, msg.sender, msg.value);
  }

  // The commented code works allows money withdraw before the match begins.
  // It was decided that this will not be allowed.
  function withdraw()
    afterMatchEnded()
    matchIsDecided()
    {
    if (betState == BET_STATES.DRAW) {
      collectBet();
    }
    else {
      collectProfit();
    }
  }

  // Transfers the user's initial bet back
  function collectBet() internal betInSomeTeam() {
    uint amount;
    if (betsToTeam0[msg.sender] > 0) {
      amount = betsToTeam0[msg.sender];
      betsToTeam0[msg.sender] = 0;
      msg.sender.transfer(amount);
    }
    else { // if (betsToTeam1[msg.sender] > 0)
      amount = betsToTeam1[msg.sender];
      betsToTeam1[msg.sender] = 0;
      msg.sender.transfer(amount);
    }
  }

  // Transfers the user's profit
  function collectProfit() internal {
    require( ( betState == BET_STATES.TEAM_ZERO_WON && betsToTeam0[msg.sender] > 0 ) ||
             ( betState == BET_STATES.TEAM_ONE_WON && betsToTeam1[msg.sender] > 0 ) );

    uint bet = 0;
    uint sum = 0;
    uint profit = 0;

    if (betState == BET_STATES.TEAM_ZERO_WON && betsToTeam0[msg.sender] > 0) {
      bet = betsToTeam0[msg.sender];
      sum = team0BetSum;
      profit = team1BetSum;
    }
    else { // if (BET_STATES.bet_state == TEAM_ONE_WON && betsToTeam1[msg.sender] > 0)
      bet = betsToTeam1[msg.sender];
      sum = team1BetSum;
      profit = team0BetSum;
    }

    assert(bet <= sum);

    // Approach one:
    // We might lose precision, but no overflow
    var senderPc = bet / sum;
    assert(senderPc >= 0 && senderPc <= 1);

    var senderProfit = senderPc * profit;
    assert(senderProfit <= profit);

    // Approach two:
    // Better precision, since multiplication is done first, but may overflow
    //uint sender_profit = (bet * profit) / sum;

    var mulTax = (senderProfit * TAX);
    require(mulTax >= senderProfit); // Overflow
    var tax = mulTax / 100;
    assert(tax <= senderProfit);

    var notaxProfit = senderProfit;
    senderProfit -= tax;
    assert(senderProfit <= notaxProfit);

    owner.transfer(tax);
    collectBet();
    msg.sender.transfer(senderProfit);
  }

  function close() {
    require(block.timestamp > timestampArbiterDeadline);
    selfdestruct(owner);
  }

  /* Fallback just throws now
   * Can do something, maybe increase the value of both pools
  */
  function () { require(false); }
}

pragma solidity ^0.4.11;

import './governanceInterface.sol';
import './helpers.sol';

contract Bet is ProposalInterface{

  modifier onlyOwner() {
    require(msg.sender == owner);
    _;
  }
  modifier onlyArbiter() {
    require(msg.sender == address(arbiter));
    _;
  }
  modifier beforeMatchBegun() {
    require(block.timestamp < timestampMatchBegin);
    _;
  }
  modifier afterMatchEnded() {
    require(block.timestamp >= timestampMatchEnd);
    _;
  }
  modifier beforeResolverCanCall() {
    require(block.timestamp < timestampArbiterDeadline);
    _;
  }
  modifier matchIsOpenOrUndecided() {
    require(betState == BET_STATES.OPEN || betState == BET_STATES.UNDECIDED);
    _;
  }
  modifier matchIsDecided() {
    require(betState == BET_STATES.TEAM_ZERO_WON ||
            betState == BET_STATES.TEAM_ONE_WON ||
            betState == BET_STATES.DRAW);
    _;
  }
  modifier betInSomeTeam() {
    require(betsToTeam0[msg.sender] > 0 || betsToTeam1[msg.sender] > 0);
    _;
  }

  enum BET_STATES {
    OPEN,
    TEAM_ZERO_WON,
    TEAM_ONE_WON,
    DRAW,
    UNDECIDED
    }

  BET_STATES public betState = BET_STATES.OPEN;
  address public owner; // Can be a parent contract
  GovernanceInterface public arbiter; // Governance account
  bool public isFeatured;
  string public team0Name;
  string public team1Name;
  string public description;
  string public category;
  uint public team0BetSum;
  uint public team1BetSum;
  mapping (address => uint) public betsToTeam0;
  mapping (address => uint) public betsToTeam1;

  uint public timestampMatchBegin;
  uint public timestampMatchEnd;
  // Self-destruct is possible if time > timestampArbiterDeadline
  uint public timestampArbiterDeadline;

  uint8 constant TAX = 10;
  uint constant TIMESTAMP_MARGIN = 1000;

  event NewBet(bool for_team, address from, uint amount);
  event StateChanged(BET_STATES state);

  function Bet(GovernanceInterface _arbiter, string _team0Name,
               string _team1Name, string _category,
               uint[] _timestamps
               ) {
    require(block.timestamp < _timestamps[0]);
    require(_timestamps[0] < _timestamps[1]);
    require(_timestamps[1] < _timestamps[2]);

    isFeatured = false;
    owner = msg.sender;
    arbiter = _arbiter;
    team0Name = _team0Name;
    team1Name = _team1Name;
    category = _category;
    timestampMatchBegin = _timestamps[0] - TIMESTAMP_MARGIN;
    timestampMatchEnd = _timestamps[1] + TIMESTAMP_MARGIN;
    timestampArbiterDeadline = _timestamps[2] + TIMESTAMP_MARGIN;
  }

  function __resolve(uint outcome)
    onlyArbiter()
    afterMatchEnded()
    beforeResolverCanCall()
    matchIsOpenOrUndecided() {

    if (outcome == 1)
      betState = BET_STATES.TEAM_ZERO_WON;
    else if (outcome == 2)
      betState = BET_STATES.TEAM_ONE_WON;
    else if (outcome == 3)
      betState = BET_STATES.DRAW;
    else
      betState = BET_STATES.UNDECIDED;
    StateChanged(betState);
  }

  // Will create a Proposal on the arbiter
  function updateResult() payable
    matchIsOpenOrUndecided()
    afterMatchEnded() {
    arbiter.addProposal(this, timestampArbiterDeadline);
  }

  function toggleFeatured() onlyOwner() {
    isFeatured = !isFeatured;
  }

  function modifyCategory(string newCategory) onlyOwner() {
    category = newCategory;
  }

  //
  function bet(bool forTeam) payable
    beforeMatchBegun() {
    uint prevSum;

    if (forTeam == false) {
      // Cannot bet in two teams
      require(betsToTeam1[msg.sender] == 0);
      prevSum = team0BetSum;
      require((prevSum + msg.value) >= prevSum); // Overflow
      team0BetSum += msg.value;
      assert(team0BetSum >= prevSum);
      betsToTeam0[msg.sender] += msg.value;
    }
    else {
      // Cannot bet in two teams
      require(betsToTeam0[msg.sender] == 0);
      prevSum = team1BetSum;
      require((prevSum + msg.value) >= prevSum); // Overflow
      team1BetSum += msg.value;
      assert(team1BetSum >= prevSum);
      betsToTeam1[msg.sender] += msg.value;
    }

    NewBet(forTeam, msg.sender, msg.value);
  }

  // The commented code works allows money withdraw before the match begins.
  // It was decided that this will not be allowed.
  function withdraw()
    afterMatchEnded()
    matchIsDecided()
    {
    if (betState == BET_STATES.DRAW) {
      collectBet();
    }
    else {
      collectProfit();
    }
  }

  // Transfers the user's initial bet back
  function collectBet() internal betInSomeTeam() {
    uint amount;
    if (betsToTeam0[msg.sender] > 0) {
      amount = betsToTeam0[msg.sender];
      betsToTeam0[msg.sender] = 0;
      msg.sender.transfer(amount);
    }
    else { // if (betsToTeam1[msg.sender] > 0)
      amount = betsToTeam1[msg.sender];
      betsToTeam1[msg.sender] = 0;
      msg.sender.transfer(amount);
    }
  }

  // Transfers the user's profit
  function collectProfit() internal {
    require( ( betState == BET_STATES.TEAM_ZERO_WON && betsToTeam0[msg.sender] > 0 ) ||
             ( betState == BET_STATES.TEAM_ONE_WON && betsToTeam1[msg.sender] > 0 ) );

    uint bet = 0;
    uint sum = 0;
    uint profit = 0;

    if (betState == BET_STATES.TEAM_ZERO_WON && betsToTeam0[msg.sender] > 0) {
      bet = betsToTeam0[msg.sender];
      sum = team0BetSum;
      profit = team1BetSum;
    }
    else { // if (BET_STATES.bet_state == TEAM_ONE_WON && betsToTeam1[msg.sender] > 0)
      bet = betsToTeam1[msg.sender];
      sum = team1BetSum;
      profit = team0BetSum;
    }

    assert(bet <= sum);

    // Approach one:
    // We might lose precision, but no overflow
    var senderPc = bet / sum;
    assert(senderPc >= 0 && senderPc <= 1);

    var senderProfit = senderPc * profit;
    assert(senderProfit <= profit);

    // Approach two:
    // Better precision, since multiplication is done first, but may overflow
    //uint sender_profit = (bet * profit) / sum;

    var mulTax = (senderProfit * TAX);
    require(mulTax >= senderProfit); // Overflow
    var tax = mulTax / 100;
    assert(tax <= senderProfit);

    var notaxProfit = senderProfit;
    senderProfit -= tax;
    assert(senderProfit <= notaxProfit);

    owner.transfer(tax);
    collectBet();
    msg.sender.transfer(senderProfit);
  }

  function close() {
    require(block.timestamp > timestampArbiterDeadline);
    selfdestruct(owner);
  }

  /* Fallback just throws now
   * Can do something, maybe increase the value of both pools
  */
  function () { require(false); }
}


Reorder functions to prevent shadowing warning

pragma solidity ^0.5.0;

import "../../GSN/Context.sol";
import "./ERC721.sol";
import "./IERC721Metadata.sol";
import "../../introspection/ERC165.sol";

contract ERC721Metadata is Context, ERC165, ERC721, IERC721Metadata {
    // Token name
    string private _name;

    // Token symbol
    string private _symbol;

    // Base URI
    string private _baseURI;

    // Optional mapping for token URIs
    mapping(uint256 => string) private _tokenURIs;

    /*
     *     bytes4(keccak256('name()')) == 0x06fdde03
     *     bytes4(keccak256('symbol()')) == 0x95d89b41
     *     bytes4(keccak256('tokenURI(uint256)')) == 0xc87b56dd
     *
     *     => 0x06fdde03 ^ 0x95d89b41 ^ 0xc87b56dd == 0x5b5e139f
     */
    bytes4 private constant _INTERFACE_ID_ERC721_METADATA = 0x5b5e139f;

    /**
     * @dev Constructor function
     */
    constructor (string memory name, string memory symbol) public {
        _name = name;
        _symbol = symbol;

        // register the supported interfaces to conform to ERC721 via ERC165
        _registerInterface(_INTERFACE_ID_ERC721_METADATA);
    }

    /**
     * @dev Gets the token name.
     * @return string representing the token name
     */
    function name() external view returns (string memory) {
        return _name;
    }

    /**
     * @dev Gets the token symbol.
     * @return string representing the token symbol
     */
    function symbol() external view returns (string memory) {
        return _symbol;
    }

    /**
     * @dev Returns the URI for a given token ID. May return an empty string.
     *
     * If the token's URI is non-empty and a base URI was set (via
     * {_setBaseURI}), it will be added to the token ID's URI as a prefix.
     *
     * Reverts if the token ID does not exist.
     */
    function tokenURI(uint256 tokenId) external view returns (string memory) {
        require(_exists(tokenId), "ERC721Metadata: URI query for nonexistent token");

        string memory _tokenURI = _tokenURIs[tokenId];

        // Even if there is a base URI, it is only appended to non-empty token-specific URIs
        if (bytes(_tokenURI).length == 0) {
            return "";
        } else {
            // abi.encodePacked is being used to concatenate strings
            return string(abi.encodePacked(_baseURI, _tokenURI));
        }
    }

    /**
     * @dev Internal function to set the token URI for a given token.
     *
     * Reverts if the token ID does not exist.
     *
     * TIP: if all token IDs share a prefix (e.g. if your URIs look like
     * `http://api.myproject.com/token/<id>`), use {_setBaseURI} to store
     * it and save gas.
     */
    function _setTokenURI(uint256 tokenId, string memory _tokenURI) internal {
        require(_exists(tokenId), "ERC721Metadata: URI set of nonexistent token");
        _tokenURIs[tokenId] = _tokenURI;
    }

    /**
     * @dev Internal function to set the base URI for all token IDs. It is
     * automatically added as a prefix to the value returned in {tokenURI}.
     *
     * _Available since v2.5.0._
     */
    function _setBaseURI(string memory baseURI) internal {
        _baseURI = baseURI;
    }

    /**
    * @dev Returns the base URI set via {_setBaseURI}. This will be
    * automatically added as a preffix in {tokenURI} to each token's URI, when
    * they are non-empty.
    *
    * _Available since v2.5.0._
    */
    function baseURI() external view returns (string memory) {
        return _baseURI;
    }

    /**
     * @dev Internal function to burn a specific token.
     * Reverts if the token does not exist.
     * Deprecated, use _burn(uint256) instead.
     * @param owner owner of the token to burn
     * @param tokenId uint256 ID of the token being burned by the msg.sender
     */
    function _burn(address owner, uint256 tokenId) internal {
        super._burn(owner, tokenId);

        // Clear metadata (if any)
        if (bytes(_tokenURIs[tokenId]).length != 0) {
            delete _tokenURIs[tokenId];
        }
    }
}

pragma solidity ^0.5.0;

import "../../GSN/Context.sol";
import "./ERC721.sol";
import "./IERC721Metadata.sol";
import "../../introspection/ERC165.sol";

contract ERC721Metadata is Context, ERC165, ERC721, IERC721Metadata {
    // Token name
    string private _name;

    // Token symbol
    string private _symbol;

    // Base URI
    string private _baseURI;

    // Optional mapping for token URIs
    mapping(uint256 => string) private _tokenURIs;

    /*
     *     bytes4(keccak256('name()')) == 0x06fdde03
     *     bytes4(keccak256('symbol()')) == 0x95d89b41
     *     bytes4(keccak256('tokenURI(uint256)')) == 0xc87b56dd
     *
     *     => 0x06fdde03 ^ 0x95d89b41 ^ 0xc87b56dd == 0x5b5e139f
     */
    bytes4 private constant _INTERFACE_ID_ERC721_METADATA = 0x5b5e139f;

    /**
     * @dev Constructor function
     */
    constructor (string memory name, string memory symbol) public {
        _name = name;
        _symbol = symbol;

        // register the supported interfaces to conform to ERC721 via ERC165
        _registerInterface(_INTERFACE_ID_ERC721_METADATA);
    }

    /**
     * @dev Gets the token name.
     * @return string representing the token name
     */
    function name() external view returns (string memory) {
        return _name;
    }

    /**
     * @dev Gets the token symbol.
     * @return string representing the token symbol
     */
    function symbol() external view returns (string memory) {
        return _symbol;
    }

    /**
     * @dev Returns the URI for a given token ID. May return an empty string.
     *
     * If the token's URI is non-empty and a base URI was set (via
     * {_setBaseURI}), it will be added to the token ID's URI as a prefix.
     *
     * Reverts if the token ID does not exist.
     */
    function tokenURI(uint256 tokenId) external view returns (string memory) {
        require(_exists(tokenId), "ERC721Metadata: URI query for nonexistent token");

        string memory _tokenURI = _tokenURIs[tokenId];

        // Even if there is a base URI, it is only appended to non-empty token-specific URIs
        if (bytes(_tokenURI).length == 0) {
            return "";
        } else {
            // abi.encodePacked is being used to concatenate strings
            return string(abi.encodePacked(_baseURI, _tokenURI));
        }
    }

    /**
    * @dev Returns the base URI set via {_setBaseURI}. This will be
    * automatically added as a preffix in {tokenURI} to each token's URI, when
    * they are non-empty.
    *
    * _Available since v2.5.0._
    */
    function baseURI() external view returns (string memory) {
        return _baseURI;
    }

    /**
     * @dev Internal function to set the token URI for a given token.
     *
     * Reverts if the token ID does not exist.
     *
     * TIP: if all token IDs share a prefix (e.g. if your URIs look like
     * `http://api.myproject.com/token/<id>`), use {_setBaseURI} to store
     * it and save gas.
     */
    function _setTokenURI(uint256 tokenId, string memory _tokenURI) internal {
        require(_exists(tokenId), "ERC721Metadata: URI set of nonexistent token");
        _tokenURIs[tokenId] = _tokenURI;
    }

    /**
     * @dev Internal function to set the base URI for all token IDs. It is
     * automatically added as a prefix to the value returned in {tokenURI}.
     *
     * _Available since v2.5.0._
     */
    function _setBaseURI(string memory baseURI) internal {
        _baseURI = baseURI;
    }

    /**
     * @dev Internal function to burn a specific token.
     * Reverts if the token does not exist.
     * Deprecated, use _burn(uint256) instead.
     * @param owner owner of the token to burn
     * @param tokenId uint256 ID of the token being burned by the msg.sender
     */
    function _burn(address owner, uint256 tokenId) internal {
        super._burn(owner, tokenId);

        // Clear metadata (if any)
        if (bytes(_tokenURIs[tokenId]).length != 0) {
            delete _tokenURIs[tokenId];
        }
    }
}


Add ItemStoreShortId contract.

Add ItemStoreShortId contract.

pragma solidity ^0.4.23;

/**
 * @title ItemStoreShortId
 * @author Jonathan Brown <jbrown@mix-blockchain.org>
 * @dev Maintain bidirectional mapping between 32 byte itemIds and 4 byte shortIds.
 */
contract ItemStoreShortId {

    /**
     * @dev Mapping of itemId to shortId.
     */
    mapping (bytes32 => bytes4) itemIdShortId;

    /**
     * @dev Mapping of shortId to itemId.
     */
    mapping (bytes4 => bytes32) shortIdItemId;

    /**
     * @dev
     * @param itemId itemId of the item.
     * @param nonce Extra parameter to change the shortId if it is already taken.
     * @return shortId
     */
    function createShortId(bytes32 itemId, bytes32 nonce) external returns (bytes4 shortId) {
        // Caluculate the shortId.
        shortId = bytes4(keccak256(itemId, nonce));
        // Make sure it hasn't been used before.
        assert(shortIdItemId[shortId] == 0);
        // Store the mappings.
        itemIdShortId[itemId] = shortId;
        shortIdItemId[shortId] = itemId;
    }

    /**
     * @dev Get itemId for shortId.
     * @param shortId to get the itemId for.
     * @return The itemId.
     */
    function getItemId(bytes4 shortId) external view returns (bytes32) {
        return shortIdItemId[shortId];
    }

    /**
     * @dev Get shortId for itemId.
     * @param itemId to get the shortId for.
     * @return The shortId.
     */
    function getShortId(bytes32 itemId) external view returns (bytes4) {
        return itemIdShortId[itemId];
    }

}

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


Use Inherited event instead of OwnershipTransfered

pragma solidity ^0.4.11;

import './Ownable.sol';

/**
 * @title Inheritable
 * @dev The Inheritable contract provides ownership transfer capabilities, in the
 * case that the current owner stops "heartbeating". Only the heir can pronounce the
 * owner's death.
 */
contract Inheritable is Ownable {
  address public heir;

  // Time window the owner has to notify they are alive.
  uint public heartbeatTimeout;

  // Timestamp of the owner's death, as pronounced by the heir.
  uint public timeOfDeath;

  event HeirChanged(address indexed owner, address indexed newHeir);
  event OwnerHeartbeated(address indexed owner);
  event OwnerPronouncedDead(address indexed owner, address indexed heir, uint timeOfDeath);
  event Inherited(address indexed previousOwner, address indexed newOwner);

  /**
   * @dev Throw an exception if called by any account other than the heir's.
   */
  modifier onlyHeir() {
    require(msg.sender == heir);
    _;
  }

  /**
   * @notice Create a new Inheritable Contract with heir address 0x0.
   * @param _heartbeatTimeout time available for the owner to notify they are alive,
   * before the heir can take ownership.
   */
  function Inheritable(uint _heartbeatTimeout) public {
    heartbeatTimeout = _heartbeatTimeout;
  }

  function setHeir(address newHeir) public onlyOwner {
    heartbeat();
    HeirChanged(owner, newHeir);
    heir = newHeir;
  }

  /**
   * @dev set heir = 0x0
   */
  function removeHeir() public onlyOwner {
    heartbeat();
    heir = 0;
  }

  function setHeartbeatTimeout(uint newHeartbeatTimeout) public onlyOwner {
    require(ownerLives());
    heartbeatTimeout = newHeartbeatTimeout;
  }

  /**
   * @dev Heir can pronounce the owners death. To inherit the ownership, they will
   * have to wait for `heartbeatTimeout` seconds.
   */
  function pronounceDeath() public onlyHeir {
    require(ownerLives());
    OwnerPronouncedDead(owner, heir, timeOfDeath);
    timeOfDeath = now;
  }

  /**
   * @dev Owner can send a heartbeat if they were mistakenly pronounced dead.
   */
  function heartbeat() public onlyOwner {
    OwnerHeartbeated(owner);
    timeOfDeath = 0;
  }

  /**
   * @dev Allows heir to transfer ownership only if heartbeat has timed out.
   */
  function inherit() public onlyHeir {
    require(!ownerLives());
    require(now >= timeOfDeath + heartbeatTimeout);
    Inherited(owner, heir);
    owner = heir;
    timeOfDeath = 0;
  }

  function ownerLives() internal returns (bool) {
    return timeOfDeath == 0;
  }
}

pragma solidity ^0.4.11;

import './Ownable.sol';

/**
 * @title Inheritable
 * @dev The Inheritable contract provides ownership transfer capabilities, in the
 * case that the current owner stops "heartbeating". Only the heir can pronounce the
 * owner's death.
 */
contract Inheritable is Ownable {
  address public heir;

  // Time window the owner has to notify they are alive.
  uint public heartbeatTimeout;

  // Timestamp of the owner's death, as pronounced by the heir.
  uint public timeOfDeath;

  event HeirChanged(address indexed owner, address indexed newHeir);
  event OwnerHeartbeated(address indexed owner);
  event OwnerPronouncedDead(address indexed owner, address indexed heir, uint timeOfDeath);

  /**
   * @dev Throw an exception if called by any account other than the heir's.
   */
  modifier onlyHeir() {
    require(msg.sender == heir);
    _;
  }

  /**
   * @notice Create a new Inheritable Contract with heir address 0x0.
   * @param _heartbeatTimeout time available for the owner to notify they are alive,
   * before the heir can take ownership.
   */
  function Inheritable(uint _heartbeatTimeout) public {
    heartbeatTimeout = _heartbeatTimeout;
  }

  function setHeir(address newHeir) public onlyOwner {
    heartbeat();
    HeirChanged(owner, newHeir);
    heir = newHeir;
  }

  /**
   * @dev set heir = 0x0
   */
  function removeHeir() public onlyOwner {
    heartbeat();
    heir = 0;
  }

  function setHeartbeatTimeout(uint newHeartbeatTimeout) public onlyOwner {
    require(ownerLives());
    heartbeatTimeout = newHeartbeatTimeout;
  }

  /**
   * @dev Heir can pronounce the owners death. To inherit the ownership, they will
   * have to wait for `heartbeatTimeout` seconds.
   */
  function pronounceDeath() public onlyHeir {
    require(ownerLives());
    OwnerPronouncedDead(owner, heir, timeOfDeath);
    timeOfDeath = now;
  }

  /**
   * @dev Owner can send a heartbeat if they were mistakenly pronounced dead.
   */
  function heartbeat() public onlyOwner {
    OwnerHeartbeated(owner);
    timeOfDeath = 0;
  }

  /**
   * @dev Allows heir to transfer ownership only if heartbeat has timed out.
   */
  function inherit() public onlyHeir {
    require(!ownerLives());
    require(now >= timeOfDeath + heartbeatTimeout);
    OwnershipTransferred(owner, heir);
    owner = heir;
    timeOfDeath = 0;
  }

  function ownerLives() internal returns (bool) {
    return timeOfDeath == 0;
  }
}


fix syntax

fix syntax

pragma solidity ^0.4.11;
//import "./StandardToken.sol";
// import "./PartialLockVoting.sol";
// import "./Parametrizer.sol";

// to do:
// implement events
// check on delete in solidity
// keep deposit if never challenged (?) if win (?)

contract Registry {

    /*
     * Storage
     */

    //Registry storage
    StandardToken public token;
    mapping(bytes32 => Publisher) public whitelist;
    mapping(bytes32 => Application) public appPool;
    mapping(uint => bool) public voteProcessed;
    mapping(address => mapping(uint => bool)) public voterInfo;
    //Parameter storage
    mapping(bytes32 => Application) public Proposals; // similar to appPool
    mapping(bytes32 => uint) public Parameters;

    struct Publisher {
        address owner;
        uint expTime;
        uint deposit;
    }

    struct Application {
        address owner;
        bool challenged;
        uint challengeTime; //End of challenge period
        address challenger;
        Param snapshot;
    }

    struct Param {
        // parameters concerning the whitelist and application pool
        uint minDeposit;
        uint challengeLen;
        uint registryLen;

        // parameters to be passed into the voting contract
        uint commitVoteLen;
        uint revealVoteLen;
        uint majority;

        // parameter representing the scale of how token rewards are distributed
        uint dispensationPct;
    }

    // Constructor
    /// @param _minDeposit      application & challenger deposit amounts
    /// @param _challengeLen    duration of the challenge period
    /// @param _registryLen     duration of a registration’s validity
    /// @param _commitVoteLen   duration of the commit period in token votes
    /// @param _revealVoteLen   duration of reveal period in token votes
    /// @param _dispensationPct percentage of forfeited deposit distributed to winning party; uint between 0 and 100
    /// @param _majority        percentage of votes that constitutes the majority; uint between 0 and 100

    function Registry(address _token,
       uint _minDeposit,
       uint _challengeLen,
       uint _registryLen,
       uint _commitVoteLen,
       uint _revealVoteLen,
       uint _dispensationPct,
       uint _majority) {

       token = StandardToken(_token);
       // initialize values
       Parameters[sha3("minDeposit")]        = _minDeposit;
       Parameters[sha3("challengeLen")]      = _challengeLen;
       Parameters[sha3("registryLen")]       = _registryLen;
       Parameters[sha3("commitVoteLen")]     = _commitVoteLen;
       Parameters[sha3("revealVoteLen")]     = _revealVoteLen;
       Parameters[sha3("dispensationPct")]   = _dispensationPct;
       Parameters[sha3("majority")]          = _majority;
    }

    // called by an applicant to apply (moves them into the application pool on success)
    function apply(string _domain) {
        bytes32 domainHash = sha3(_domain);
        // applicant must pay the current value of minDeposit
        uint deposit = get("minDeposit");
        // check to prevent repeat applications
        require(appPool[domainHash].owner == 0);
        // check that registry can take sufficient amount of tokens from the applicant
        require(token.allowance(msg.sender, this) >= deposit);
        token.transferFrom(msg.sender, this, deposit);
        // initialize application with a snapshot with the current values of all parameters
        initializeSnapshot(_domain);
        appPool[domainHash].challengeTime = now + appPool[domainHash].snapshot[challengeLen];
        appPool[domainHash].owner = msg.sender;
    }

    // called by any adtoken holder to challenge an application to the whitelist and start a vote
    function challenge(string _domain) {
        bytes32 domainHash = sha3(_domain);
        // check that registry can take sufficient amount of tokens from the challenger
        uint deposit = appPool[domainHash].snapshot.minDeposit;
        require(token.allowance(msg.sender, this) >= deposit);
        token.transferFrom(msg.sender, this, deposit);
        // prevent someone from challenging an unintialized application, rechallenging,
        // or challenging after the challenge period has ended
        require(appPool[domainHash].owner != 0);
        require(appPool[domainHash].challenged == false);
        require(appPool[domainHash].challengeTime > now);
        // update the application's status
        appPool[domainHash].challenged = true;
        appPool[domainHash].challenger = msg.sender;
        // start a vote
        // poll ID = callVote(voting params);
    }

    // helper function to the challenge() function. Initializes a vote through the voting contract
    function callVote(bytes32 _domainHash) private returns (bool) {
        // event that vote has started
        // ??
    }

    // a one-time function for each completed vote
    // if domain won: domain is moved to the whitelist and applicant is rewarded tokens
    // if domain lost: challenger is rewarded tokens
    function processResult(uint _pollID)
    {
        require(voteProcessed[_pollID] == false);
        // string domain = ??;
        bytes32 domainHash = sha3(domain);
        if (didProposalPass(_pollID)) {
            //??what would happen if didProposalPass() called and vote's still ongoing??
            // add to registry
            add(domain, appPool[domainHash].owner);
            delete appPool[domainHash].owner;
            // give tokens to applicant based on dist and total tokens
        }
        else {
            delete appPool[domainHash].owner;
            deposit = appPool[domainHash].snapshot[minDeposit];
            winning = appPool[domainHash].snapshot[minDeposit]*appPool[domainHash].snapshot[dispensationPct];
            tokens.transfer(appPool[domainHash].challenger, winning+ deposit);
            // check math
        }
        // ensures the result cannot be processed again
        voteProcessed[_pollID] = true;
    }

    // called by each voter to claim their reward for each completed vote
    function claimReward(uint _pollID, uint _salt) {
        // checks if a voter has claimed tokens
        require(voterInfo[msg.sender][_pollID] == false);
        uint reward = giveTokens(_pollID, _salt);
        // ensures a voter cannot claim tokens again
        transfer(msg.sender, reward);
        voterInfo[msg.sender][_pollID] = true;
    }

    // called to move an applying domain to the whitelist
    // iff the domain's challenge period has passed without a challenge
    function moveToRegistry(string _domain) {
        bytes32 domainHash = sha3(_domain);
        require(appPool[domainHash].challengeTime < now);
        require(appPool[domainHash].challenged == false);
        // prevents moving a domain to the registry without ever applying
        require(appPool[domainHash].owner != 0);
        // prevent applicant from moving to registry multiple times
        add(_domain, appPool[domainHash].owner);
        delete appPool[domainHash].owner;
    }

    // private function to add a domain name to the whitelist
    function add(string _domain, address _owner)  {
        bytes32 domainHash = sha3(_domain);
        uint expiration = appPool[domainHash].snapshot.registryLen;
        whitelist[domainHash].expTime = now + expiration;
        whitelist[domainHash].owner = _owner;
        whitelist[domainHash].deposit = appPool[domainHash].snapshot.minDeposit;
    }

    // checks if a domain name is in the whitelist and unexpired
    function isVerified(string _domain) returns (bool) {
        bytes32 domainHash = sha3(_domain);
        if (whitelist[domainHash].expTime > now) {
            return true;
        }
        else {
            return false;
        }
    }

    // private function to initialize a snapshot of parameters for each application
    function initializeSnapshot(string _domain) {
        bytes32 domainHash = sha3(_domain);
        appPool[domainHash].snapshot.minDeposit = get("minDeposit");
        appPool[domainHash].snapshot.challengeLen = get("challengeLen");
        appPool[domainHash].snapshot.registryLen = get("registryLen");
        appPool[domainHash].snapshot.commitVoteLen = get("commitVoteLen");
        appPool[domainHash].snapshot.revealVoteLen = get("revealVoteLen");
        appPool[domainHash].snapshot.majority = get("majority");
        appPool[domainHash].snapshot.dispensationPct = get("dispensationPct");
    }

    function giveTokens(uint _pollID, uint _salt) returns(uint) {
        // number of tokens person used to vote / total number of tokens for winning side
        // scale using distribution number
        // give the tokens
        // string domain = ??
        bytes32 domainHash = sha3(domain);
        uint minDeposit = appPool[domainHash].snapshot[minDeposit];
        uint dispensationPct = appPool[domainHash].snapshot[dispensationPct];
        uint totalTokens = getTotalNumberOfTokensForWinningOption(_pollID);
        uint voterTokens = getNumCorrectInvestment(_pollID, _salt);

        uint reward = voterTokens*minDeposit*(1-dispensationPct)/totalTokens;
        return reward;
    }

    // FOR TESTING
    function toHash(string _domain) returns (bytes32){
        return sha3(_domain);
    }
    function getCurrentTime() returns (uint){
        return now;
    }

/*******************************************************************/

    //called by a user who wishes to change a parameter
    //initializes a proposal to change a parameter
    function proposeUpdate(string _parameter, uint _value) {
        bytes32 parameterHash = sha3(_parameter, _value);
        // applicant must pay the current value of minDeposit
        uint deposit = get("minDeposit");
        // check that registry can take sufficient amount of tokens from the applicant
        require(token.allowance(msg.sender, this) >= deposit);
        token.transferFrom(msg.sender, this, deposit);
        // initialize application with a snapshot with the current values of all parameters
        initializeSnapshotParam(parameterHash);
        uint challengeLen = Proposals[parameterHash].snapshot[challengeLen];
        Proposals[parameterHash].challengeTime= now + challengeLen;
        Proposals[parameterHash].owner = msg.sender;

    }

    //called by user who wishes to reject a proposal
    //initializes a vote to accept/reject the param change proposal
    function challengeProposal(string _parameter, uint _value) {
        bytes32 parameterHash = sha3(_parameter, _value);

        // check that registry can take sufficient amount of tokens from the challenger
        uint deposit = Proposals[parameterHash ].snapshot.minDeposit;
        require(token.allowance(msg.sender, this) >= deposit);
        token.transferFrom(msg.sender, this, deposit);

        // prevent someone from challenging an unintialized application, rechallenging,
        // or challenging after the challenge period has ended
        require(Proposals[parameterHash].owner != 0);
        require(Proposals[parameterHash].challenged == false);
        require(Proposals[parameterHash].challengeTime> now);

        // update the application's status
        Proposals[parameterHash].challenged = true;
        Proposals[parameterHash].challenger = msg.sender;
        // start a vote
        // poll ID = callVote(voting params);
    }

    // called to change parameter
    // iff the proposal's challenge period has passed without a challenge
    function setParams(string _parameter, uint _value) {
        bytes32 parameterHash = sha3(_parameter, _value);
        require(Proposals[parameterHash].challengeTime < now);
        require(Proposals[parameterHash].challenged == false);
        // prevents moving a domain to the registry without ever applying
        require(Proposals[parameterHash].owner != 0);
        // prevent applicant from moving to registry multiple times
        Parameters[sha3(_parameter)] = _value;
        delete Proposals[parameterHash].owner;
    }

    // a one-time function for each completed vote
    // if proposal won: new parameter value is set, and applicant is rewarded tokens
    // if prospsal lost: challenger is rewarded tokens
    function processProposal(uint _pollID)
    {
        require(voteProcessed[_pollID] == false);
        // string parameter = ??;
        //uint value = ??
        bytes32 parameterHash = sha3(parameter, value);
        if (didProposalPass(_pollID)) {
            //??what would happen if didProposalPass() called and vote's still ongoing??
            // setting the value of parameter
            Parameters[sha3(parameter)] = value;
            delete Proposals[parameterHash].owner;
            // give tokens to applicant based on dist and total tokens
        }
        else {
            delete Proposals[parameterHash].owner;
            // give tokens to challenger based on dist and total tokens
        }
        // ensures the result cannot be processed again
        voteProcessed[_pollID] = true;
    }

    function claimParamReward(uint _pollID, uint _salt) {
        // checks if a voter has claimed tokens
        require(voterInfo[msg.sender][_pollID] == false);
        uint reward = giveTokens(_pollID, _salt);
        // ensures a voter cannot claim tokens again
        transfer(msg.sender, reward);
        voterInfo[msg.sender][_pollID] = true;
    }

     function giveParamTokens(uint _pollID, uint _salt) returns(uint) {
        // number of tokens person used to vote / total number of tokens for winning side
        // scale using distribution number
        // give the tokens
        // string parameter = ??
        bytes32 parameterHash = sha3(parameter, value);
        uint minDeposit = Proposals[parameterHash].snapshot[minDeposit];
        uint dispensationPct = Proposals[parameterHash].snapshot[dispensationPct];
        uint totalTokens = getTotalNumberOfTokensForWinningOption(_pollID);
        uint voterTokens = getNumCorrectInvestment(_pollID, _salt);

        uint reward = voterTokens*minDeposit*(1-dispensationPct)/totalTokens;
        return reward;
    }

     // private function to initialize a snapshot of parameters for each proposal
     function initializeSnapshotParam(bytes32 _hash) {
        Proposals[_hash].snapshot.minDeposit = get("minDeposit");
        Proposals[_hash].snapshot.challengeLen = get("challengeLen");
        Proposals[_hash].snapshot.commitVoteLen = get("commitVoteLen");
        Proposals[_hash].snapshot.revealVoteLen = get("revealVoteLen");
        Proposals[_hash].snapshot.majority = get("majority");
        Proposals[_hash].snapshot.dispensationPct = get("dispensationPct");
    }

    // interface for retrieving config parameter from hashmapping
    /// @param _keyword key for hashmap (only useful when keyword matches variable name)
    function get(string _keyword) returns (uint) {
       return Parameters[sha3(_keyword)];
    }

}

pragma solidity ^0.4.11;
//import "./StandardToken.sol";
// import "./PartialLockVoting.sol";
// import "./Parametrizer.sol";

// to do:
// implement events
// check on delete in solidity
// keep deposit if never challenged (?) if win (?)

contract Registry {

    /*
     * Storage
     */

    //Registry storage
    StandardToken public token;
    mapping(bytes32 => Publisher) public whitelist;
    mapping(bytes32 => Application) public appPool;
    mapping(uint => bool) public voteProcessed;
    mapping(address => mapping(uint => bool)) public voterInfo;
    //Parameter storage
    mapping(bytes32 => Application) public Proposals; // similar to appPool
    mapping(bytes32 => uint) public Parameters;

    struct Publisher {
        address owner;
        uint expTime;
        uint deposit;
    }

    struct Application {
        address owner;
        bool challenged;
        uint challengeTime; //End of challenge period
        address challenger;
        Param snapshot;
    }

    struct Param {
        // parameters concerning the whitelist and application pool
        uint minDeposit;
        uint challengeLen;
        uint registryLen;

        // parameters to be passed into the voting contract
        uint commitVoteLen;
        uint revealVoteLen;
        uint majority;

        // parameter representing the scale of how token rewards are distributed
        uint dispensationPct;
    }

    // Constructor
    /// @param _minDeposit      application & challenger deposit amounts
    /// @param _challengeLen    duration of the challenge period
    /// @param _registryLen     duration of a registration’s validity
    /// @param _commitVoteLen   duration of the commit period in token votes
    /// @param _revealVoteLen   duration of reveal period in token votes
    /// @param _dispensationPct percentage of forfeited deposit distributed to winning party; uint between 0 and 100
    /// @param _proposalThresh  share of tokens required to initiate a reparameterization
    /// @param _majority        percentage of votes that constitutes the majority; uint between 0 and 100

    function Registry(address _token,
       uint _minDeposit,
       uint _challengeLen,
       uint _registryLen,
       uint _commitVoteLen,
       uint _revealVoteLen,
       uint _dispensationPct,
       uint _majority) {

       token = StandardToken(_token);
       // initialize values
       paramMap[sha3("minDeposit")]        = _minDeposit;
       paramMap[sha3("challengeLen")]      = _challengeLen;
       paramMap[sha3("registryLen")]       = _registryLen;
       paramMap[sha3("commitVoteLen")]     = _commitVoteLen;
       paramMap[sha3("revealVoteLen")]     = _revealVoteLen;
       paramMap[sha3("dispensationPct")]   = _dispensationPct;
       paramMap[sha3("majority")]          = _majority;
    }

    // called by an applicant to apply (moves them into the application pool on success)
    function apply(string _domain) {
        bytes32 domainHash = sha3(_domain);
        // applicant must pay the current value of minDeposit
        uint deposit = get("minDeposit");
        // check to prevent repeat applications
        require(appPool[domainHash].owner == 0);
        // check that registry can take sufficient amount of tokens from the applicant
        require(token.allowance(msg.sender, this) >= deposit);
        token.transferFrom(msg.sender, this, deposit);
        // initialize application with a snapshot with the current values of all parameters
        initializeSnapshot(_domain);
        appPool[domainHash].challengeTime = now + appPool[domainHash].snapshot[challengeLen];
        appPool[domainHash].owner = msg.sender;
    }

    // called by any adtoken holder to challenge an application to the whitelist and start a vote
    function challenge(string _domain) {
        bytes32 domainHash = sha3(_domain);
        // check that registry can take sufficient amount of tokens from the challenger
        uint deposit = appPool[domainHash].snapshot[minDeposit];
        require(token.allowance(msg.sender, this) >= deposit);
        token.transferFrom(msg.sender, this, deposit);
        // prevent someone from challenging an unintialized application, rechallenging,
        // or challenging after the challenge period has ended
        require(appPool[domainHash].owner != 0);
        require(appPool[domainHash].challenged == false);
        require(appPool[domainHash].challengeTime > now);
        // update the application's status
        appPool[domainHash].challenged = true;
        appPool[domainHash].challenger = msg.sender;
        // start a vote
        // poll ID = callVote(voting params);
    }

    // helper function to the challenge() function. Initializes a vote through the voting contract
    function callVote(bytes32 _domainHash) private returns (bool) {
        // event that vote has started
        // ??
    }

    // a one-time function for each completed vote
    // if domain won: domain is moved to the whitelist and applicant is rewarded tokens
    // if domain lost: challenger is rewarded tokens
    function processResult(uint _pollID)
    {
        require(voteProcessed[_pollID] == false);
        // string domain = ??;
        bytes32 domainHash = sha3(domain);
        if (didProposalPass(_pollID)) {
            //??what would happen if didProposalPass() called and vote's still ongoing??
            // add to registry
            add(domain, appPool[domainHash].owner);
            delete appPool[domainHash].owner;
            // give tokens to applicant based on dist and total tokens
        }
        else {
            delete appPool[domainHash].owner;
            deposit = appPool[domainHash].snapshot[minDeposit];
            winning = appPool[domainHash].snapshot[minDeposit]*appPool[domainHash].snapshot[dispensationPct];
            tokens.transfer(appPool[domainHash].challenger, winning+ deposit);
            // check math
        }
        // ensures the result cannot be processed again
        voteProcessed[_pollID] = true;
    }

    // called by each voter to claim their reward for each completed vote
    function claimReward(uint _pollID, uint _salt) {
        // checks if a voter has claimed tokens
        require(voterInfo[msg.sender][_pollID] == false);
        reward = giveTokens(_pollID, _salt);
        // ensures a voter cannot claim tokens again
        transfer(msg.sender, reward);
        voterInfo[msg.sender][_pollID] = true;
    }

    // called to move an applying domain to the whitelist
    // iff the domain's challenge period has passed without a challenge
    function moveToRegistry(string _domain) {
        bytes32 domainHash = sha3(_domain);
        require(appPool[domainHash].challengeTime < now);
        require(appPool[domainHash].challenged == false);
        // prevents moving a domain to the registry without ever applying
        require(appPool[domainHash].owner != 0);
        // prevent applicant from moving to registry multiple times
        add(_domain, appPool[domainHash].owner);
        delete appPool[domainHash].owner;
    }

    // private function to add a domain name to the whitelist
    function add(string _domain, address _owner)  {
        bytes32 domainHash = sha3(_domain);
        uint expiration = appPool[domainHash].snapshot[registryLen];
        whitelist[domainHash].expTime = now + expiration;
        whitelist[domainHash].owner = _owner;
        whitelist[domainHash].deposit = appPool[domainHash].snapshot[minDeposit];
    }

    // checks if a domain name is in the whitelist and unexpired
    function isVerified(string _domain) returns (bool) {
        bytes32 domainHash = sha3(_domain);
        if (whitelist[domainHash].expTime > now) {
            return true;
        }
        else {
            return false;
        }
    }

    // private function to initialize a snapshot of parameters for each application
    function initializeSnapshot(string _domain) {
        bytes32 domainHash = sha3(_domain);
        appPool[domainHash].snapshot[minDeposit] = get("minDeposit");
        appPool[domainHash].snapshot[challengeLen] = get("challengeLen");
        appPool[domainHash].snapshot[registryLen] = get("registryLen");
        appPool[domainHash].snapshot[commitVoteLen] = get("commitVoteLen");
        appPool[domainHash].snapshot[revealVoteLen] = get("revealVoteLen");
        appPool[domainHash].snapshot[majority] = get("majority");
        appPool[domainHash].snapshot[dispensationPct] = get("dispensationPct");
    }

    function giveTokens(uint _pollID, uint _salt) returns(uint) {
        // number of tokens person used to vote / total number of tokens for winning side
        // scale using distribution number
        // give the tokens
        // string domain = ??
        bytes32 domainHash = sha3(domain);
        uint minDeposit = appPool[domainHash].snapshot[minDeposit];
        uint dispensationPct = appPool[domainHash].snapshot[dispensationPct];
        uint totalTokens = getTotalNumberOfTokensForWinningOption(_pollID);
        uint voterTokens = getNumCorrectInvestment(_pollID, _salt);

        uint reward = voterTokens*minDeposit*(1-dispensationPct)/totalTokens;
        return reward;
    }

    // FOR TESTING
    function toHash(string _domain) returns (bytes32){
        return sha3(_domain);
    }
    function getCurrentTime() returns (uint){
        return now;
    }

/*******************************************************************/

    //called by a user who wishes to change a parameter
    //initializes a proposal to change a parameter
    function proposeUpdate(string _parameter, uint _value) {
        parameterHash = sha3(_parameter, _value);
        // applicant must pay the current value of minDeposit
        uint deposit = get("minDeposit");
        // check that registry can take sufficient amount of tokens from the applicant
        require(token.allowance(msg.sender, this) >= deposit);
        token.transferFrom(msg.sender, this, deposit);
        // initialize application with a snapshot with the current values of all parameters
        initializeSnapshotParam(parameterHash);
        uint challengeLen = Proposals[parameterHash].snapshot[challengeLen];
        Proposals[parameterHash].challengeTime= now + challengeLen;
        Proposals[parameterHash].owner = msg.sender;

    }

    //called by user who wishes to reject a proposal
    //initializes a vote to accept/reject the param change proposal
    function challengeProposal(string _parameter, uint _value) {
        parameterHash = sha3(_parameter, _value);

        // check that registry can take sufficient amount of tokens from the challenger
        uint deposit = Proposals[parameterHash ].snapshot[minDeposit];
        require(token.allowance(msg.sender, this) >= deposit);
        token.transferFrom(msg.sender, this, deposit);

        // prevent someone from challenging an unintialized application, rechallenging,
        // or challenging after the challenge period has ended
        require(Proposals[parameterHash].owner != 0);
        require(Proposals[parameterHash].challenged == false);
        require(Proposals[parameterHash].challengeTime> now);

        // update the application's status
        Proposals[parameterHash].challenged = true;
        Proposals[parameterHash].challenger = msg.sender;
        // start a vote
        // poll ID = callVote(voting params);
    }

    // called to change parameter
    // iff the proposal's challenge period has passed without a challenge
    function setParams(string _parameter, uint _value) {
        parameterHash = sha3(_parameter, _value);
        require(Proposals[parameterHash].challengeTime < now);
        require(Proposals[parameterHash].challenged == false);
        // prevents moving a domain to the registry without ever applying
        require(Proposals[parameterHash].owner != 0);
        // prevent applicant from moving to registry multiple times
        Parameters[sha3(_parameter)] = _value;
        delete Proposals[parameterHash].owner;
    }

    // a one-time function for each completed vote
    // if proposal won: new parameter value is set, and applicant is rewarded tokens
    // if prospsal lost: challenger is rewarded tokens
    function processProposal(uint _pollID)
    {
        require(voteProcessed[_pollID] == false);
        // string parameter = ??;
        //uint value = ??
        parameterHash = sha3(parameter, value);
        if (didProposalPass(_pollID)) {
            //??what would happen if didProposalPass() called and vote's still ongoing??
            // setting the value of parameter
            Parameters[sha3(parameter)] = value;
            delete Proposals[parameterHash].owner;
            // give tokens to applicant based on dist and total tokens
        }
        else {
            delete Proposals[parameterHash].owner;
            // give tokens to challenger based on dist and total tokens
        }
        // ensures the result cannot be processed again
        voteProcessed[_pollID] = true;
    }

    function claimParamReward(uint _pollID, uint _salt) {
        // checks if a voter has claimed tokens
        require(voterInfo[msg.sender][_pollID] == false);
        reward = giveTokens(_pollID, _salt);
        // ensures a voter cannot claim tokens again
        transfer(msg.sender, reward);
        voterInfo[msg.sender][_pollID] = true;
    }

     function giveParamTokens(uint _pollID, uint _salt) returns(uint) {
        // number of tokens person used to vote / total number of tokens for winning side
        // scale using distribution number
        // give the tokens
        // string parameter = ??
        parameterHash = sha3(parameter, value);
        uint minDeposit = Proposals[parameterHash].snapshot[minDeposit];
        uint dispensationPct = Proposals[parameterHash].snapshot[dispensationPct];
        uint totalTokens = getTotalNumberOfTokensForWinningOption(_pollID);
        uint voterTokens = getNumCorrectInvestment(_pollID, _salt);

        uint reward = voterTokens*minDeposit*(1-dispensationPct)/totalTokens;
        return reward;
    }

     // private function to initialize a snapshot of parameters for each proposal
     function initializeSnapshotParam(byte32 _hash) {
        Proposals[_hash].snapshot[minDeposit] = get("minDeposit");
        Proposals[_hash].snapshot[challengeLen] = get("challengeLen");
        Proposals[_hash].snapshot[commitVoteLen] = get("commitVoteLen");
        Proposals[_hash].snapshot[revealVoteLen] = get("revealVoteLen");
        Proposals[_hash].snapshot[majority] = get("majority");
        Proposals[_hash].snapshot[dispensationPct] = get("dispensationPct");
    }

    // interface for retrieving config parameter from hashmapping
    /// @param _keyword key for hashmap (only useful when keyword matches variable name)
    function get(string _keyword) returns (uint) {
       return Parameters[sha3(_keyword)];
    }

}


hashes: use uint represenation to avoid confusion

contract HashTest {
  function testSHA3() returns (uint256) {
    address addr1 = 0x43989fb883ba8111221e89123897538475893837;
    address addr2 = 0;
    uint val = 10000;
    uint timestamp = 1448075779;

    return uint256(sha3(addr1, addr2, val, timestamp)); // will return c3ab5ca31a013757f26a88561f0ff5057a97dfcc33f43d6b479abc3ac2d1d595
  }

  function testSHA256() returns (uint256) {
    address addr1 = 0x43989fb883ba8111221e89123897538475893837;
    address addr2 = 0;
    uint val = 10000;
    uint timestamp = 1448075779;

    return uint256(sha256(addr1, addr2, val, timestamp)); // will return 344d8cb0711672efbdfe991f35943847c1058e1ecf515ff63ad936b91fd16231
  }

  function testRIPEMD160() returns (uint160) {
    address addr1 = 0x43989fb883ba8111221e89123897538475893837;
    address addr2 = 0;
    uint val = 10000;
    uint timestamp = 1448075779;

    return uint160(ripemd160(addr1, addr2, val, timestamp)); // will return a398cc72490f72048efa52c4e92067e8499672e7
  }
}

contract HashTest {
  function testSHA3() returns (bytes32) {
    address addr1 = 0x43989fb883ba8111221e89123897538475893837;
    address addr2 = 0;
    uint val = 10000;
    uint timestamp = 1448075779;

    return sha3(addr1, addr2, val, timestamp); // will return c3ab5ca31a013757f26a88561f0ff5057a97dfcc33f43d6b479abc3ac2d1d595
  }

  function testSHA256() returns (bytes32) {
    address addr1 = 0x43989fb883ba8111221e89123897538475893837;
    address addr2 = 0;
    uint val = 10000;
    uint timestamp = 1448075779;

    return sha256(addr1, addr2, val, timestamp); // will return 344d8cb0711672efbdfe991f35943847c1058e1ecf515ff63ad936b91fd16231
  }

  function testRIPEMD160() returns (bytes32) {
    address addr1 = 0x43989fb883ba8111221e89123897538475893837;
    address addr2 = 0;
    uint val = 10000;
    uint timestamp = 1448075779;

    return ripemd160(addr1, addr2, val, timestamp); // will return a398cc72490f72048efa52c4e92067e8499672e7000000000000000000000000
  }
}


SafeMath

SafeMath


Document search behavior

Document search behavior

pragma solidity ^0.4.15;

import "./vendor/grove/GroveLib.sol";

library IntervalTreeLib {
  using GroveLib for GroveLib.Index;

  bool constant TRAVERSED_EARLIER = false;
  bool constant TRAVERSED_LATER = true;

  uint8 constant SEARCH_DONE = 0x00;
  uint8 constant SEARCH_EARLIER = 0x01;
  uint8 constant SEARCH_LATER = 0x10;

  struct Tree {
    // global table of intervals
    mapping (uint => Interval) intervals;
    uint numIntervals;

    // tree nodes
    mapping (uint => Node) nodes;
    uint numNodes;

    // pointer to root of tree
    uint rootNode;
  }

  struct Node {
    uint center;
    uint nodeBefore;
    uint nodeAfter;
    uint count;
    GroveLib.Index beginIndex;
    GroveLib.Index endIndex;

    // references to boundary intervals (GroveLib.Index node IDs)
    bytes32 lowestBeginIndexNode;
    bytes32 highestEndIndexNode;
  }

  struct Interval {
    uint begin;
    uint end;
    bytes32 data;
  }

  function addInterval(Tree storage tree, uint begin, uint end, bytes32 data) internal {
    uint intervalID = _createInterval(tree, begin, end, data);

    // if the tree is empty, create the root
    if (tree.rootNode == 0) {
      var nodeID = _createNode(tree, begin, end);
      tree.rootNode = nodeID;

      var node = tree.nodes[nodeID];
      _addIntervalToNode(node, begin, end, intervalID);

      return;
    }

    // depth-first search tree for place to add interval.
    // for each step of the search:
    //   if the new interval contains the current node's center:
    //     add interval to current node
    //     stop search
    //
    //   if the new interval < center:
    //     recurse "before"
    //   if the new interval > center:
    //     recurse "after"
    uint curID = tree.rootNode;
    Node storage curNode = tree.nodes[curID];
    bool found = false;
    while (!found) {
      // track direction of recursion each step, to update correct pointer
      // upon needing to add a new node
      bool recurseDirection;

      if (end <= curNode.center) {
	// traverse before
	curID = curNode.nodeBefore;
	recurseDirection = TRAVERSED_EARLIER;
      } else if (begin > curNode.center) {
	// traverse after
	curID = curNode.nodeAfter;
	recurseDirection = TRAVERSED_LATER;
      } else {
	// found!
	found = true;
	break;
      }

      // if traversing yields null pointer for child node, must create
      if (curID == 0) {
	curID = _createNode(tree, begin, end);

	// update appropriate pointer
	if (recurseDirection == TRAVERSED_EARLIER) {
	  curNode.nodeBefore = curID;
	} else {
	  curNode.nodeAfter = curID;
	}
      }

      // fetch node definition for new curID + update var
      curNode = tree.nodes[curID];
    }

    // loop exits with curNode set to correct location for interval
    // add it!
    _addIntervalToNode(curNode, begin, end, intervalID);
  }

  /*
   * search
   */
  function intervalsAt(Tree storage tree, uint point)
    constant
    returns (uint count)
  {
    count = search(tree, point).length;
  }

  function intervalAt(Tree storage tree, uint point, uint offset)
    constant
    returns (uint begin, uint end, bytes32 data)
  {
    var results = search(tree, point);

    require(offset < results.length);

    var interval = tree.intervals[results[offset]];

    return (interval.begin, interval.end, interval.data);
  }

  function search(Tree storage tree, uint point)
    constant
    internal
    returns (uint[] memory intervalIDs)
  {
    // can't search empty trees
    require(tree.rootNode != 0x0);

    // HACK repeatedly mallocs new arrays of matching interval IDs
    intervalIDs = new uint[](0);
    uint[] memory tempIDs;
    uint[] memory matchingIDs;
    uint i;  // for list copying loops

    /*
     * search traversal
     *
     * starting at root node
     */
    uint curID = tree.rootNode;
    uint8 searchNext;
    do {
      Node storage curNode = tree.nodes[curID];

      /*
       * search current node
       */
      (matchingIDs, searchNext) = _searchNode(curNode, point);

      /*
       * add matching intervals to results array
       *
       * allocate temp array and copy in both prior and new matches
       */
      if (matchingIDs.length > 0) {
	tempIDs = new uint[](intervalIDs.length + matchingIDs.length);
	for (i = 0; i < intervalIDs.length; i++) {
	  tempIDs[i] = intervalIDs[i];
	}
	for (i = 0; i < matchingIDs.length; i++) {
	  tempIDs[i + intervalIDs.length] = matchingIDs[i];
	}
	intervalIDs = tempIDs;
      }

      /*
       * recurse according to node search results
       */
      if (searchNext == SEARCH_EARLIER) {
	curID = curNode.nodeBefore;
      } else if (searchNext == SEARCH_LATER) { // SEARCH_LATER
	curID = curNode.nodeAfter;
      }

    } while (searchNext != SEARCH_DONE && curID != 0x0);
  }

  /*
   * insert helpers
   */
  function _createInterval(Tree storage tree, uint begin, uint end, bytes32 data)
    internal
    returns (uint intervalID)
  {
    intervalID = ++tree.numIntervals;

    tree.intervals[intervalID] = Interval({
      begin: begin,
      end: end,
      data: data
    });
  }

  function _createNode(Tree storage tree, uint begin, uint end) returns (uint nodeID) {
    nodeID = ++tree.numNodes;
    tree.nodes[nodeID] = Node({
      center: begin + (end - begin) / 2,
      nodeBefore: 0,
      nodeAfter: 0,
      count: 0,
      lowestBeginIndexNode: 0x0,
      highestEndIndexNode: 0x0,
      beginIndex: GroveLib.Index(sha3(this, bytes32(nodeID * 2))),
      endIndex: GroveLib.Index(sha3(this, bytes32(nodeID * 2 + 1)))
    });
  }

  function _addIntervalToNode(Node storage node, uint begin, uint end, uint intervalID) {
    var _intervalID = bytes32(intervalID);
    var _begin = _getBeginIndexKey(begin);
    var _end = _getEndIndexKey(end);

    node.beginIndex.insert(_intervalID, _begin);
    node.endIndex.insert(_intervalID, _end);
    node.count++;

    if (node.count == 1) {
      node.lowestBeginIndexNode = node.beginIndex.root;
      node.highestEndIndexNode = node.endIndex.root;

      return;
    }

    var newLowest = node.beginIndex.getPreviousNode(node.lowestBeginIndexNode);
    if (newLowest != 0x0) {
      node.lowestBeginIndexNode = newLowest;
    }

    var newHighest = node.endIndex.getNextNode(node.highestEndIndexNode);
    if (newHighest != 0x0) {
      node.highestEndIndexNode = newHighest;
    }
  }

  /*
   * search helpers
   */

  /*
   * @dev Searches node for matching intervals and how to search next
   * @param node The node to search
   * @param point The point to search for
   */
  function _searchNode(Node storage node, uint point)
    constant
    internal
    returns (uint[] memory intervalIDs, uint8 searchNext)
  {
    uint[] memory _intervalIDs = new uint[](node.count);
    uint num = 0;

    bytes32 cur;

    if (point == node.center) {
      /*
       * case: point exactly matches the node's center
       *
       * collect (all) matching intervals (every interval in node, by def)
       */
      cur = node.lowestBeginIndexNode;
      while (cur != 0x0) {
	_intervalIDs[num] = uint(node.beginIndex.getNodeId(cur));
	num++;
	cur = _next(node, cur);
      }

      /*
       * search is done:
       * no other nodes in tree have intervals containing point
       */
      searchNext = SEARCH_DONE;
    } else if (point < node.center) {
      /*
       * case: point is earlier than center.
       *
       *
       * collect matching intervals.
       *
       * shortcut:
       *
       *   starting with lowest beginning interval, search sorted begin list
       *   until begin is later than point
       *
       *	       point
       *                 :
       *                 :   center
       *                 :     |
       *        (0) *----:-----|----------o
       *        (1)    *-:-----|---o
       *        (-)      x *---|------o
       *        (-)         *--|--o
       *        (-)          *-|----o
       *
       *
       *    this works because intervals contained in a node are guaranteed to
       *    contain `center`
       */
      cur = node.lowestBeginIndexNode;
      while (cur != 0x0) {
	uint begin = _begin(node, cur);
	if (begin > point) {
	  break;
	}

	_intervalIDs[num] = uint(node.beginIndex.getNodeId(cur));
	num++;

	cur = _next(node, cur);
      }

      /*
       * search proceeds to node containing earlier intervals
       */
      searchNext = SEARCH_EARLIER;
    } else if (point > node.center) {
      /*
       * case: point is later than center.
       *
       *
       * collect matching intervals.
       *
       * shortcut:
       *
       *   starting with highest ending interval, search sorted end list
       *   until end is earlier than or equal to point
       *
       *			    point
       *			    :
       *                     center :
       *                       |    :
       *            *----------|----:-----o (0)
       *                   *---|----:-o     (1)
       *                     *-|----o	    (not matching, done.)
       *               *-------|---o	    (-)
       *                    *--|--o	    (-)
       *
       *
       *    this works because intervals contained in a node are guaranteed to
       *    contain `center`
       */
      cur = node.highestEndIndexNode;
      while (cur != 0x0) {
	uint end = _end(node, cur);
	if (end <= point) {
	  break;
	}

	_intervalIDs[num] = uint(node.endIndex.getNodeId(cur));
	num++;

	cur = _previous(node, cur);
      }

      /*
       * search proceeds to later intervals
       */
      searchNext = SEARCH_LATER;
    }

    /*
     * return correctly-sized array of intervalIDs
     */
    if (num == _intervalIDs.length) {
      intervalIDs = _intervalIDs;
    } else {
      intervalIDs = new uint[](num);
      for (uint i = 0; i < num; i++) {
	intervalIDs[i] = _intervalIDs[i];
      }
    }
  }

  /*
   * Grove linked list traversal
   */
  function _begin(Node storage node, bytes32 indexNode) constant returns (uint) {
    return _getBegin(node.beginIndex.getNodeValue(indexNode));
  }

  function _end(Node storage node, bytes32 indexNode) constant returns (uint) {
    return _getEnd(node.endIndex.getNodeValue(indexNode));
  }

  function _next(Node storage node, bytes32 cur) constant returns (bytes32) {
    return node.beginIndex.getNextNode(cur);
  }

  function _previous(Node storage node, bytes32 cur) constant returns (bytes32) {
    return node.endIndex.getPreviousNode(cur);
  }

  /*
   * uint / int conversions for Grove nodeIDs
   */
  function _getBeginIndexKey(uint begin) constant internal returns (int) {
    // convert to signed int in order-preserving manner
    return int(begin - 0x8000000000000000000000000000000000000000000000000000000000000000);
  }

  function _getEndIndexKey(uint end) constant internal returns (int) {
    // convert to signed int in order-preserving manner
    return int(end - 0x8000000000000000000000000000000000000000000000000000000000000000);
  }

  function _getBegin(int beginIndexKey) constant internal returns (uint) {
    // convert to unsigned int in order-preserving manner
    return uint(beginIndexKey) + 0x8000000000000000000000000000000000000000000000000000000000000000;
  }

  function _getEnd(int endIndexKey) constant internal returns (uint) {
    // convert to unsigned int in order-preserving manner
    return uint(endIndexKey) + 0x8000000000000000000000000000000000000000000000000000000000000000;
  }
}

pragma solidity ^0.4.15;

import "./vendor/grove/GroveLib.sol";

library IntervalTreeLib {
  using GroveLib for GroveLib.Index;

  bool constant TRAVERSED_EARLIER = false;
  bool constant TRAVERSED_LATER = true;

  uint8 constant SEARCH_DONE = 0x00;
  uint8 constant SEARCH_EARLIER = 0x01;
  uint8 constant SEARCH_LATER = 0x10;

  struct Tree {
    // global table of intervals
    mapping (uint => Interval) intervals;
    uint numIntervals;

    // tree nodes
    mapping (uint => Node) nodes;
    uint numNodes;

    // pointer to root of tree
    uint rootNode;
  }

  struct Node {
    uint center;
    uint nodeBefore;
    uint nodeAfter;
    uint count;
    GroveLib.Index beginIndex;
    GroveLib.Index endIndex;

    // references to boundary intervals (GroveLib.Index node IDs)
    bytes32 lowestBeginIndexNode;
    bytes32 highestEndIndexNode;
  }

  struct Interval {
    uint begin;
    uint end;
    bytes32 data;
  }

  function addInterval(Tree storage tree, uint begin, uint end, bytes32 data) internal {
    uint intervalID = _createInterval(tree, begin, end, data);

    // if the tree is empty, create the root
    if (tree.rootNode == 0) {
      var nodeID = _createNode(tree, begin, end);
      tree.rootNode = nodeID;

      var node = tree.nodes[nodeID];
      _addIntervalToNode(node, begin, end, intervalID);

      return;
    }

    // depth-first search tree for place to add interval.
    // for each step of the search:
    //   if the new interval contains the current node's center:
    //     add interval to current node
    //     stop search
    //
    //   if the new interval < center:
    //     recurse "before"
    //   if the new interval > center:
    //     recurse "after"
    uint curID = tree.rootNode;
    Node storage curNode = tree.nodes[curID];
    bool found = false;
    while (!found) {
      // track direction of recursion each step, to update correct pointer
      // upon needing to add a new node
      bool recurseDirection;

      if (end <= curNode.center) {
	// traverse before
	curID = curNode.nodeBefore;
	recurseDirection = TRAVERSED_EARLIER;
      } else if (begin > curNode.center) {
	// traverse after
	curID = curNode.nodeAfter;
	recurseDirection = TRAVERSED_LATER;
      } else {
	// found!
	found = true;
	break;
      }

      // if traversing yields null pointer for child node, must create
      if (curID == 0) {
	curID = _createNode(tree, begin, end);

	// update appropriate pointer
	if (recurseDirection == TRAVERSED_EARLIER) {
	  curNode.nodeBefore = curID;
	} else {
	  curNode.nodeAfter = curID;
	}
      }

      // fetch node definition for new curID + update var
      curNode = tree.nodes[curID];
    }

    // loop exits with curNode set to correct location for interval
    // add it!
    _addIntervalToNode(curNode, begin, end, intervalID);
  }

  /*
   * search
   */
  function intervalsAt(Tree storage tree, uint point)
    constant
    returns (uint)
  {
    return search(tree, point).length;
  }

  function intervalAt(Tree storage tree, uint point, uint offset)
    constant
    returns (uint begin, uint end, bytes32 data)
  {
    var results = search(tree, point);

    require(offset < results.length);

    var interval = tree.intervals[results[offset]];

    return (interval.begin, interval.end, interval.data);
  }

  function search(Tree storage tree, uint point)
    constant
    internal
    returns (uint[] memory intervalIDs)
  {
    // traverse tree, collecting matching intervals in memory array of IDs

    // HACK malloc all the things!
    //   this continually re-allocates ever-growing `intervalIDs` array,
    //   copying each item in array each time.
    intervalIDs = new uint[](0);
    uint[] memory tempIDs;
    uint[] memory addedIDs;

    // track whether search is done, or if we need to recurse in either
    // direction
    uint8 searchNext;

    uint i;

    uint curID = tree.rootNode;
    var curNode = tree.nodes[curID];
    (addedIDs, searchNext) = _searchNode(curNode, point);
    tempIDs = new uint[](intervalIDs.length + addedIDs.length);
    for (i = 0; i < intervalIDs.length; i++) {
      tempIDs[i] = intervalIDs[i];
    }
    for (i = 0; i < addedIDs.length; i++) {
      tempIDs[i + intervalIDs.length] = addedIDs[i];
    }
    intervalIDs = tempIDs;

    while (searchNext != SEARCH_DONE) {
      if (searchNext == SEARCH_EARLIER) {
	curID = curNode.nodeBefore;
      } else { // SEARCH_LATER
	curID = curNode.nodeAfter;
      }
      if (curID == 0x0) {
	break;
      }

      curNode = tree.nodes[curID];
      (addedIDs, searchNext) = _searchNode(curNode, point);

      tempIDs = new uint[](intervalIDs.length + addedIDs.length);
      for (i = 0; i < intervalIDs.length; i++) {
	tempIDs[i] = intervalIDs[i];
      }
      for (i = 0; i < addedIDs.length; i++) {
	tempIDs[i + intervalIDs.length] = addedIDs[i];
      }
      intervalIDs = tempIDs;
    }
  }

  /*
   * insert helpers
   */
  function _createInterval(Tree storage tree, uint begin, uint end, bytes32 data)
    internal
    returns (uint intervalID)
  {
    intervalID = ++tree.numIntervals;

    tree.intervals[intervalID] = Interval({
      begin: begin,
      end: end,
      data: data
    });
  }

  function _createNode(Tree storage tree, uint begin, uint end) returns (uint nodeID) {
    nodeID = ++tree.numNodes;
    tree.nodes[nodeID] = Node({
      center: begin + (end - begin) / 2,
      nodeBefore: 0,
      nodeAfter: 0,
      count: 0,
      lowestBeginIndexNode: 0x0,
      highestEndIndexNode: 0x0,
      beginIndex: GroveLib.Index(sha3(this, bytes32(nodeID * 2))),
      endIndex: GroveLib.Index(sha3(this, bytes32(nodeID * 2 + 1)))
    });
  }

  function _addIntervalToNode(Node storage node, uint begin, uint end, uint intervalID) {
    var _intervalID = bytes32(intervalID);
    var _begin = _getBeginIndexKey(begin);
    var _end = _getEndIndexKey(end);

    node.beginIndex.insert(_intervalID, _begin);
    node.endIndex.insert(_intervalID, _end);
    node.count++;

    if (node.count == 1) {
      node.lowestBeginIndexNode = node.beginIndex.root;
      node.highestEndIndexNode = node.endIndex.root;

      return;
    }

    var newLowest = node.beginIndex.getPreviousNode(node.lowestBeginIndexNode);
    if (newLowest != 0x0) {
      node.lowestBeginIndexNode = newLowest;
    }

    var newHighest = node.endIndex.getNextNode(node.highestEndIndexNode);
    if (newHighest != 0x0) {
      node.highestEndIndexNode = newHighest;
    }
  }

  /*
   * search helpers
   */
  function _searchNode(Node storage node, uint point)
    constant
    internal
    returns (uint[] memory intervalIDs, uint8 searchNext)
  {
    uint[] memory _intervalIDs = new uint[](node.count);
    uint num = 0;

    bytes32 cur;

    if (point == node.center) {
      searchNext = SEARCH_DONE;

      cur = node.lowestBeginIndexNode;
      while (cur != 0x0) {
	_intervalIDs[num] = uint(node.beginIndex.getNodeId(cur));
	num++;
	cur = _next(node, cur);
      }
    } else if (point < node.center) {
      searchNext = SEARCH_EARLIER;

      cur = node.lowestBeginIndexNode;
      while (cur != 0x0) {
	uint begin = _begin(node, cur);
	if (begin > point) {
	  break;
	}

	_intervalIDs[num] = uint(node.beginIndex.getNodeId(cur));
	num++;

	cur = _next(node, cur);
      }
    } else if (point > node.center) {
      searchNext = SEARCH_LATER;

      cur = node.highestEndIndexNode;
      while (cur != 0x0) {
	uint end = _end(node, cur);
	if (end <= point) {
	  break;
	}

	_intervalIDs[num] = uint(node.endIndex.getNodeId(cur));
	num++;

	cur = _previous(node, cur);
      }
    }

    if (num == _intervalIDs.length) {
      intervalIDs = _intervalIDs;
    } else {
      intervalIDs = new uint[](num);
      for (uint i = 0; i < num; i++) {
	intervalIDs[i] = _intervalIDs[i];
      }
    }
  }

  /*
   * Grove linked list traversal
   */
  function _begin(Node storage node, bytes32 indexNode) constant returns (uint) {
    return _getBegin(node.beginIndex.getNodeValue(indexNode));
  }

  function _end(Node storage node, bytes32 indexNode) constant returns (uint) {
    return _getEnd(node.endIndex.getNodeValue(indexNode));
  }

  function _next(Node storage node, bytes32 cur) constant returns (bytes32) {
    return node.beginIndex.getNextNode(cur);
  }

  function _previous(Node storage node, bytes32 cur) constant returns (bytes32) {
    return node.endIndex.getPreviousNode(cur);
  }

  /*
   * uint / int conversions for Grove nodeIDs
   */
  function _getBeginIndexKey(uint begin) constant internal returns (int) {
    // convert to signed int in order-preserving manner
    return int(begin - 0x8000000000000000000000000000000000000000000000000000000000000000);
  }

  function _getEndIndexKey(uint end) constant internal returns (int) {
    // convert to signed int in order-preserving manner
    return int(end - 0x8000000000000000000000000000000000000000000000000000000000000000);
  }

  function _getBegin(int beginIndexKey) constant internal returns (uint) {
    // convert to unsigned int in order-preserving manner
    return uint(beginIndexKey) + 0x8000000000000000000000000000000000000000000000000000000000000000;
  }

  function _getEnd(int endIndexKey) constant internal returns (uint) {
    // convert to unsigned int in order-preserving manner
    return uint(endIndexKey) + 0x8000000000000000000000000000000000000000000000000000000000000000;
  }
}


Adds `getTaskAddress` func

Adds `getTaskAddress` func

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

import "Task.sol";
import "SequenceList.sol";

contract TaskManager {
    SequenceList list = new SequenceList();

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

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

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

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

        bool isOverwrite = list.insert(_id, t);
        registerActionEvent("ADD TASK");
        // TODO needs a verification of insert success
        return t;
    }

    function getTaskAtIndex(uint _idx) constant returns (address, uint) {
        registerActionEvent("GET TASK");
        return list.valueAtIndexHasNext(_idx);
    }

    function getTaskListSize() constant returns (uint) {
        registerActionEvent("GET TASKLIST SIZE");
        return list.size();

    }

    function getTaskKeyAtIndex(uint _idx) constant returns (bytes32) {
        return list.keyAtIndex(_idx);
    }

    function getTaskAddress(bytes32 _id) constant returns (address) {
        return list.value(_id);
    }
}

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

import "Task.sol";
import "SequenceList.sol";

contract TaskManager {
    SequenceList list = new SequenceList();

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

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

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

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

        bool isOverwrite = list.insert(_id, t);
        registerActionEvent("ADD TASK");
        return t;
    }

    function getTaskAtIndex(uint _idx) constant returns (address, uint) {
        registerActionEvent("GET TASK");
        return list.valueAtIndexHasNext(_idx);
    }

    function getTaskListSize() constant returns (uint) {
        registerActionEvent("GET SIZE");
        return list.size();

    }

    function getTaskKeyAtIndex(uint _idx) constant returns (bytes32) {
        return list.keyAtIndex(_idx);
    }
}


TestMathLib.sol: Bring coverage to 100%.

This commit increases MathLib.sol statement and function coverage to 100%.
Branch coverage has not reached 100% as some asserts cannot be reached.

Issue: #27

/*
    Copyright 2017 Phillip A. Elsasser

    Licensed under the Apache License, Version 2.0 (the "License");
    you may not use this file except in compliance with the License.
    You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

    Unless required by applicable law or agreed to in writing, software
    distributed under the License is distributed on an "AS IS" BASIS,
    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    See the License for the specific language governing permissions and
    limitations under the License.
*/

pragma solidity 0.4.18;

import "truffle/Assert.sol";
import "../../contracts/libraries/MathLib.sol";

/// @title TestMathLib tests for all of our math functions
/// @author Phil Elsasser <phil@marketprotcol.io>
contract TestMathLib {

    function testSign() public {
        Assert.equal(MathLib.sign(0), 0, "Sign of 0 should be 0");
        Assert.equal(MathLib.sign(-50), -1, "Sign of a negative should be -1");
        Assert.equal(MathLib.sign(50), 1, "Sign of a positive should be 1");
    }

    function testIsSameSign() public {
        Assert.isTrue(MathLib.isSameSign(0, 0), "Sign of 0 is 0");
        Assert.isTrue(MathLib.isSameSign(-50, -120), "Sign of a negatives should be equal");
        Assert.isTrue(MathLib.isSameSign(1, 100000), "Sign of a positives should be equal");
        Assert.isTrue(!MathLib.isSameSign(1, -100000), "Sign of a positive and negative are not equal");
    }

    function testAbs() public {
        Assert.equal(MathLib.abs(0), 0, "abs of 0 should be 0");
        Assert.equal(MathLib.abs(15), 15, "abs of positive should be same");
        Assert.equal(MathLib.abs(-15), 15, "abs of negative should be positive");
    }

    function testAbsMin() public {
        Assert.equal(MathLib.absMin(0, 250), 0, "0 is always the min");
        Assert.equal(MathLib.absMin(250, 0), 0, "0 is always the min");
        Assert.equal(MathLib.absMin(-250, 0), 0, "0 is always the min");
        Assert.equal(MathLib.absMin(15, -20), 15, "15 smaller than 20");
        Assert.equal(MathLib.absMin(-15, 20), -15, "15 smaller than 20");
        Assert.equal(MathLib.absMin(-15, -20), -15, "15 smaller than 20");
    }

    function testAbsMax() public {
        Assert.equal(MathLib.absMax(0, 250), 250, "250 further than 0");
        Assert.equal(MathLib.absMax(250, 0), 250, "250 further than 0");
        Assert.equal(MathLib.absMax(-250, 0), -250, "-250 further than 0");
        Assert.equal(MathLib.absMax(15, -20), -20, "-20 further from 0 than 15");
        Assert.equal(MathLib.absMax(-15, 20), 20, "+20 further from 0 than -15");
        Assert.equal(MathLib.absMax(-15, -20), -20, "-20 further from 0 than -15");
    }

    function failSubtractWhenALessThanB() public pure returns(uint256) {
         return MathLib.subtract(uint256(1), uint256(2));
    }

    function testSubtract() public {
        Assert.equal(MathLib.subtract(uint(1), uint(1)), 0, "1 - 1 does not equal 0");
        bytes4 abi = bytes4(keccak256("failSubtractWhenALessThanB()"));
        Assert.isFalse(this.call(abi), "Should assert");
    }

    function failSafeAddWhenGreaterThanIntMax() public pure returns(int256) {
         int256 signedIntMax = int256(~((uint256(1) << 255)));
         return MathLib.add(int256(1), signedIntMax);
    }

    function testSafeAdd() public {
        int256 signedIntMin = int256((uint256(1) << 255));
        int256 signedIntMax = int256(~((uint256(1) << 255)));

        Assert.equal(MathLib.add(int256(2), int256(2)), 4, "2 + 2 equals 4");
        Assert.equal(MathLib.add(int256(0), signedIntMax), signedIntMax, "add 0 to int256 max should equal int256 max");
        Assert.equal(MathLib.add(int256(0), signedIntMin), signedIntMin, "add 0 to int256 min should equal int256 min");

        bytes4 abi = bytes4(keccak256("failSafeAddWhenGreaterThanIntMax()"));
        Assert.isFalse(this.call(abi), "Should assert");
        }

    function failDivideFractionalByZero() public pure returns(uint256) {
        return MathLib.divideFractional(2, 6, 0);
    }

    function testDivideFractional() public {
        Assert.equal(MathLib.divideFractional(2, 6, 10), 1, "12 / 10 = 1");
        Assert.equal(MathLib.divideFractional(3, 5, 10), 1, "15 / 10 = 1");
        Assert.equal(MathLib.divideFractional(3, 6, 10), 1, "18 / 10 = 1");
        Assert.equal(MathLib.divideFractional(4, 6, 10), 2, "24 / 10 = 2");

        bytes4 abi = bytes4(keccak256("failDivideFractionalByZero()"));
        Assert.isFalse(this.call(abi), "Should assert");
    }

    function testCalculateNeededCollateral() public {
        uint priceFloor = 250;
        uint priceCap = 350;
        uint qtyDecimalPlaces = 100;
        uint price = 275;
        int longQty = 2;
        int shortQty = -5;
        uint neededCollateralForLongPos = MathLib.calculateNeededCollateral(
            priceFloor,
            priceCap,
            qtyDecimalPlaces,
            longQty,
            price
        );

        // for a long position we need to look at the priceFloor from the price, this represents a longs max loss
        // so 275-250 is max loss per 1 lot, 25 * longQty * qtyDecimalPlaces should equal 5000
        Assert.equal(neededCollateralForLongPos, 5000, "max loss of 25 and qty of 2 with 100 decimals should be 5000 units");

        uint neededCollateralForShortPos = MathLib.calculateNeededCollateral(
            priceFloor,
            priceCap,
            qtyDecimalPlaces,
            shortQty,
            price
        );
        // for a short position we need to look at the priceCeiling from the price, this represents a shorts max loss
        // so 350 - 275 = 75 max loss per unit * 5 units * 100 decimal places = 62500 collateral units
        Assert.equal(neededCollateralForShortPos, 37500, "max loss of 75 and qty of 5 with 100 decimals should be 37500 units");

        // neededCollateral for a long position and price equal to priceFloor returns zero
        Assert.equal(MathLib.calculateNeededCollateral(priceFloor, priceCap, qtyDecimalPlaces, longQty, priceFloor),
                     0, "collateral for a long position and price equal to priceFloor should be 0");

        // neededCollateral for a long position and price less than priceFloor returns zero
        Assert.equal(MathLib.calculateNeededCollateral(priceFloor, priceCap, qtyDecimalPlaces, longQty, priceFloor-1),
                     0, "collateral for a long position and price less than priceFloor should be 0");

        // neededCollateral for a short position and price equal to priceCap returns zero
        Assert.equal(MathLib.calculateNeededCollateral(priceFloor, priceCap, qtyDecimalPlaces, shortQty, priceCap),
                     0, "collateral for a short position and price equal to priceCap should be 0");

        // neededCollateral for a short position and price greater than priceCap returns zero
        Assert.equal(MathLib.calculateNeededCollateral(priceFloor, priceCap, qtyDecimalPlaces, shortQty, priceCap+1),
                     0, "collateral for a short position and price greater than priceCap should be 0");
    }
}

/*
    Copyright 2017 Phillip A. Elsasser

    Licensed under the Apache License, Version 2.0 (the "License");
    you may not use this file except in compliance with the License.
    You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

    Unless required by applicable law or agreed to in writing, software
    distributed under the License is distributed on an "AS IS" BASIS,
    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    See the License for the specific language governing permissions and
    limitations under the License.
*/

pragma solidity 0.4.18;

import "truffle/Assert.sol";
import "../../contracts/libraries/MathLib.sol";

/// @title TestMathLib tests for all of our math functions
/// @author Phil Elsasser <phil@marketprotcol.io>
contract TestMathLib {

    function testSign() public {
        Assert.equal(MathLib.sign(0), 0, "Sign of 0 should be 0");
        Assert.equal(MathLib.sign(-50), -1, "Sign of a negative should be -1");
        Assert.equal(MathLib.sign(50), 1, "Sign of a positive should be 1");
    }

    function testIsSameSign() public {
        Assert.isTrue(MathLib.isSameSign(0, 0), "Sign of 0 is 0");
        Assert.isTrue(MathLib.isSameSign(-50, -120), "Sign of a negatives should be equal");
        Assert.isTrue(MathLib.isSameSign(1, 100000), "Sign of a positives should be equal");
        Assert.isTrue(!MathLib.isSameSign(1, -100000), "Sign of a positive and negative are not equal");
    }

    function testAbs() public {
        Assert.equal(MathLib.abs(0), 0, "abs of 0 should be 0");
        Assert.equal(MathLib.abs(15), 15, "abs of positive should be same");
        Assert.equal(MathLib.abs(-15), 15, "abs of negative should be positive");
    }

    function testAbsMin() public {
        Assert.equal(MathLib.absMin(0, 250), 0, "0 is always the min");
        Assert.equal(MathLib.absMin(250, 0), 0, "0 is always the min");
        Assert.equal(MathLib.absMin(-250, 0), 0, "0 is always the min");
        Assert.equal(MathLib.absMin(15, -20), 15, "15 smaller than 20");
        Assert.equal(MathLib.absMin(-15, 20), -15, "15 smaller than 20");
        Assert.equal(MathLib.absMin(-15, -20), -15, "15 smaller than 20");
    }

    function testAbsMax() public {
        Assert.equal(MathLib.absMax(0, 250), 250, "250 further than 0");
        Assert.equal(MathLib.absMax(250, 0), 250, "250 further than 0");
        Assert.equal(MathLib.absMax(-250, 0), -250, "-250 further than 0");
        Assert.equal(MathLib.absMax(15, -20), -20, "-20 further from 0 than 15");
        Assert.equal(MathLib.absMax(-15, 20), 20, "+20 further from 0 than -15");
        Assert.equal(MathLib.absMax(-15, -20), -20, "-20 further from 0 than -15");
    }

    function testCalculateNeededCollateral() public {
        uint priceFloor = 250;
        uint priceCap = 350;
        uint qtyDecimalPlaces = 100;
        uint price = 275;
        int longQty = 2;
        int shortQty = -5;
        uint neededCollateralForLongPos = MathLib.calculateNeededCollateral(
            priceFloor,
            priceCap,
            qtyDecimalPlaces,
            longQty,
            price
        );

        // for a long position we need to look at the priceFloor from the price, this represents a longs max loss
        // so 275-250 is max loss per 1 lot, 25 * longQty * qtyDecimalPlaces should equal 5000
        Assert.equal(neededCollateralForLongPos, 5000, "max loss of 25 and qty of 2 with 100 decimals should be 5000 units");

        uint neededCollateralForShortPos = MathLib.calculateNeededCollateral(
            priceFloor,
            priceCap,
            qtyDecimalPlaces,
            shortQty,
            price
        );
        // for a short position we need to look at the priceCeiling from the price, this represents a shorts max loss
        // so 350 - 275 = 75 max loss per unit * 5 units * 100 decimal places = 62500 collateral units
        Assert.equal(neededCollateralForShortPos, 37500, "max loss of 75 and qty of 5 with 100 decimals should be 37500 units");

        // neededCollateral for a long position and price equal to priceFloor returns zero
        Assert.equal(MathLib.calculateNeededCollateral(priceFloor, priceCap, qtyDecimalPlaces, longQty, priceFloor),
                     0, "collateral for a long position and price equal to priceFloor should be 0");

        // neededCollateral for a long position and price less than priceFloor returns zero
        Assert.equal(MathLib.calculateNeededCollateral(priceFloor, priceCap, qtyDecimalPlaces, longQty, priceFloor-1),
                     0, "collateral for a long position and price less than priceFloor should be 0");

        // neededCollateral for a short position and price equal to priceCap returns zero
        Assert.equal(MathLib.calculateNeededCollateral(priceFloor, priceCap, qtyDecimalPlaces, shortQty, priceCap),
                     0, "collateral for a short position and price equal to priceCap should be 0");

        // neededCollateral for a short position and price greater than priceCap returns zero
        Assert.equal(MathLib.calculateNeededCollateral(priceFloor, priceCap, qtyDecimalPlaces, shortQty, priceCap+1),
                     0, "collateral for a short position and price greater than priceCap should be 0");
    }
}