Documentation

Documentation

pragma solidity ^0.4.8;
import "./Owned.sol";

/*
    Open issues:
    - the formula is not yet super accurate, especially for very small/very high ratios
    - need to add overflow protection
    - possibly support changing the CRR precision in the future
    - change exp to use a predefined constant array (for ni) instead of calculating it each call
*/

contract BancorFormula is Owned {
    uint8 constant PRECISION = 32;  // fractional bits

    string public version = '0.1';
    address public newFormula;

    function BancorFormula() {
    }

    function setNewFormula(address _formula) public onlyOwner {
        newFormula = _formula;
    }

    /*
        given a token supply, reserve, CRR and a deposit amount (in the reserve token), calculates the return for a given change (in the main token)

        _supply             token total supply
        _reserveBalance     total reserve
        _reserveRatio       constant reserve ratio, 1-99
        _depositAmount      deposit amount, in reserve token
    */
    function calculatePurchaseReturn(uint256 _supply, uint256 _reserveBalance, uint16 _reserveRatio, uint256 _depositAmount) public constant returns (uint256 amount) {
        if (_supply == 0 || _reserveBalance == 0 || _reserveRatio < 1 || _reserveRatio > 99 || _depositAmount == 0) // validate input
            throw;
        // limiting input to 128bit to provide *some* overflow protection while keeping the interface generic 256bit
        // TODO: will need to revisit this
        if (_supply > uint128(-1) || _reserveBalance > uint128(-1) || _depositAmount > uint128(-1))
            throw;

        var (resN, resD) = power(uint128(_depositAmount + _reserveBalance), uint128(_reserveBalance), _reserveRatio, 100);
        return (_supply * resN / resD) - _supply;
    }

    /*
        given a token supply, reserve, CRR and a sell amount (in the main token), calculates the return for a given change (in the reserve token)

        _supply             token total supply
        _reserveBalance     total reserve
        _reserveRatio       constant reserve ratio, 1-99
        _sellAmount         sell amount, in the token itself
    */
    function calculateSaleReturn(uint256 _supply, uint256 _reserveBalance, uint16 _reserveRatio, uint256 _sellAmount) public constant returns (uint256 amount) {
        if (_supply == 0 || _reserveBalance == 0 || _reserveRatio < 1 || _reserveRatio > 99 || _sellAmount == 0) // validate input
            throw;
        // limiting input to 128bit to provide *some* overflow protection while keeping the interface generic 256bit
        // TODO: will need to revisit this
        if (_supply > uint128(-1) || _reserveBalance > uint128(-1) || _sellAmount > uint128(-1))
            throw;

        var (resN, resD) = power(uint128(_sellAmount + _supply), uint128(_supply), 100, _reserveRatio);
        return (_reserveBalance * resN / resD) - _reserveBalance;
    }

    function power(uint128 _baseN, uint128 _baseD, uint32 _expN, uint32 _expD) private returns (uint256 resN, uint256 resD) {
        return (fixedExp(ln(_baseN, _baseD) * _expN / _expD), uint256(1) << PRECISION);
	}

    function ln(uint128 _numerator, uint128 _denominator) private returns (uint256) {
        return fixedLoge(uint256(_numerator) << PRECISION) - fixedLoge(uint256(_denominator) << PRECISION);
    }

    function fixedLoge(uint256 _x) private returns (uint256) {
        /*
        Might be room enough to choose an even higher number, e.g.
        ln(2) * ( 2 ^ 37), which is 47632711549.11315
        Much better accuracy, and less rounding errors
        */

        return (fixedLog2(_x) * 2977044471) >> 32; // 2977044471.819572 = ln(2) * (2 ^ 32)
    }

    function fixedLog2(uint256 _x) private returns (uint256) {
        uint256 fixedOne = uint256(1) << PRECISION;
        uint256 fixedTwo = uint256(2) << PRECISION;

        uint256 lo = 0;
        uint256 hi = 0;

        while (_x < fixedOne) {
            _x <<= 1;
            lo += fixedOne;
        }

        while (_x >= fixedTwo) {
            _x >>= 1;
            hi += fixedOne;
        }

        for (uint8 i = 0; i < PRECISION; ++i) {
            _x = (_x * _x) >> PRECISION;
            if (_x >= fixedTwo) {
                _x >>= 1;
                hi += uint256(1) << (PRECISION - 1 - i);
            }
        }

        return hi - lo;
    }
    /*
     fixedExp
     Calculates e^x according to maclauren summation:
      e^x = 1+x+x^2/2!...+x^n/n!

     _x : An input assumed to already be upshifted for accuracy

     returns e^(x>>32) << 32 , that is, upshifted for accuracy
    */
    function fixedExp(uint256 _x) constant returns (uint256) {
        uint256 fixedOne = uint256(1) << PRECISION;
        uint256 xi = fixedOne;
        uint256 res = 0xde1bc4d19efcac82445da75b00000000 * xi;

        xi = (xi * _x) >> PRECISION;
        res += xi * 0xde1bc4d19efcb0000000000000000000;
        xi = (xi * _x) >> PRECISION;
        res += xi * 0x6f0de268cf7e58000000000000000000;
        xi = (xi * _x) >> PRECISION;
        res += xi * 0x2504a0cd9a7f72000000000000000000;
        xi = (xi * _x) >> PRECISION;
        res += xi * 0x9412833669fdc800000000000000000;
        xi = (xi * _x) >> PRECISION;
        res += xi * 0x1d9d4d714865f500000000000000000;
        xi = (xi * _x) >> PRECISION;
        res += xi * 0x4ef8ce836bba8c0000000000000000;
        xi = (xi * _x) >> PRECISION;
        res += xi * 0xb481d807d1aa68000000000000000;
        xi = (xi * _x) >> PRECISION;
        res += xi * 0x16903b00fa354d000000000000000;
        xi = (xi * _x) >> PRECISION;
        res += xi * 0x281cdaac677b3400000000000000;
        xi = (xi * _x) >> PRECISION;
        res += xi * 0x402e2aad725eb80000000000000;
        xi = (xi * _x) >> PRECISION;
        res += xi * 0x5d5a6c9f31fe24000000000000;
        xi = (xi * _x) >> PRECISION;
        res += xi * 0x7c7890d442a83000000000000;
        xi = (xi * _x) >> PRECISION;
        res += xi * 0x9931ed540345280000000000;
        xi = (xi * _x) >> PRECISION;
        res += xi * 0xaf147cf24ce150000000000;
        xi = (xi * _x) >> PRECISION;
        res += xi * 0xbac08546b867d000000000;
        xi = (xi * _x) >> PRECISION;
        res += xi * 0xbac08546b867d00000000;
        xi = (xi * _x) >> PRECISION;
        res += xi * 0xafc441338061b8000000;
        xi = (xi * _x) >> PRECISION;
        res += xi * 0x9c3cabbc0056e000000;
        xi = (xi * _x) >> PRECISION;
        res += xi * 0x839168328705c80000;
        xi = (xi * _x) >> PRECISION;
        res += xi * 0x694120286c04a0000;
        xi = (xi * _x) >> PRECISION;
        res += xi * 0x50319e98b3d2c400;
        xi = (xi * _x) >> PRECISION;
        res += xi * 0x3a52a1e36b82020;
        xi = (xi * _x) >> PRECISION;
        res += xi * 0x289286e0fce002;
        xi = (xi * _x) >> PRECISION;
        res += xi * 0x1b0c59eb53400;
        xi = (xi * _x) >> PRECISION;
        res += xi * 0x114f95b55400;
        xi = (xi * _x) >> PRECISION;
        res += xi * 0xaa7210d200;
        xi = (xi * _x) >> PRECISION;
        res += xi * 0x650139600;
        xi = (xi * _x) >> PRECISION;
        res += xi * 0x39b78e80;
        xi = (xi * _x) >> PRECISION;
        res += xi * 0x1fd8080;
        xi = (xi * _x) >> PRECISION;
        res += xi * 0x10fbc0;
        xi = (xi * _x) >> PRECISION;
        res += xi * 0x8c40;
        xi = (xi * _x) >> PRECISION;
        res += xi * 0x462;
        xi = (xi * _x) >> PRECISION;
        res += xi * 0x22;

        return res / 0xde1bc4d19efcac82445da75b00000000;
    }

    function() {
        throw;
    }
}

pragma solidity ^0.4.8;
import "./Owned.sol";

/*
    Open issues:
    - the formula is not yet super accurate, especially for very small/very high ratios
    - need to add overflow protection
    - possibly support changing the CRR precision in the future
    - change exp to use a predefined constant array (for ni) instead of calculating it each call
*/

contract BancorFormula is Owned {
    uint8 constant PRECISION = 32;  // fractional bits

    string public version = '0.1';
    address public newFormula;

    function BancorFormula() {
    }

    function setNewFormula(address _formula) public onlyOwner {
        newFormula = _formula;
    }

    /*
        given a token supply, reserve, CRR and a deposit amount (in the reserve token), calculates the return for a given change (in the main token)

        _supply             token total supply
        _reserveBalance     total reserve
        _reserveRatio       constant reserve ratio, 1-99
        _depositAmount      deposit amount, in reserve token
    */
    function calculatePurchaseReturn(uint256 _supply, uint256 _reserveBalance, uint16 _reserveRatio, uint256 _depositAmount) public constant returns (uint256 amount) {
        if (_supply == 0 || _reserveBalance == 0 || _reserveRatio < 1 || _reserveRatio > 99 || _depositAmount == 0) // validate input
            throw;
        // limiting input to 128bit to provide *some* overflow protection while keeping the interface generic 256bit
        // TODO: will need to revisit this
        if (_supply > uint128(-1) || _reserveBalance > uint128(-1) || _depositAmount > uint128(-1))
            throw;

        var (resN, resD) = power(uint128(_depositAmount + _reserveBalance), uint128(_reserveBalance), _reserveRatio, 100);
        return (_supply * resN / resD) - _supply;
    }

    /*
        given a token supply, reserve, CRR and a sell amount (in the main token), calculates the return for a given change (in the reserve token)

        _supply             token total supply
        _reserveBalance     total reserve
        _reserveRatio       constant reserve ratio, 1-99
        _sellAmount         sell amount, in the token itself
    */
    function calculateSaleReturn(uint256 _supply, uint256 _reserveBalance, uint16 _reserveRatio, uint256 _sellAmount) public constant returns (uint256 amount) {
        if (_supply == 0 || _reserveBalance == 0 || _reserveRatio < 1 || _reserveRatio > 99 || _sellAmount == 0) // validate input
            throw;
        // limiting input to 128bit to provide *some* overflow protection while keeping the interface generic 256bit
        // TODO: will need to revisit this
        if (_supply > uint128(-1) || _reserveBalance > uint128(-1) || _sellAmount > uint128(-1))
            throw;

        var (resN, resD) = power(uint128(_sellAmount + _supply), uint128(_supply), 100, _reserveRatio);
        return (_reserveBalance * resN / resD) - _reserveBalance;
    }

    function power(uint128 _baseN, uint128 _baseD, uint32 _expN, uint32 _expD) private returns (uint256 resN, uint256 resD) {
        return (fixedExp(ln(_baseN, _baseD) * _expN / _expD), uint256(1) << PRECISION);
	}

    function ln(uint128 _numerator, uint128 _denominator) private returns (uint256) {
        return fixedLoge(uint256(_numerator) << PRECISION) - fixedLoge(uint256(_denominator) << PRECISION);
    }

    function fixedLoge(uint256 _x) private returns (uint256) {
        /**
        Might be room enough to choose an even higher number, e.g.
        ln(2) * ( 2 ^ 37), which is 47632711549.11315
        Much better accuracy, and less rounding errors
        **/

        return (fixedLog2(_x) * 2977044471) >> 32; // 2977044471.819572 = ln(2) * (2 ^ 32)
    }

    function fixedLog2(uint256 _x) private returns (uint256) {
        uint256 fixedOne = uint256(1) << PRECISION;
        uint256 fixedTwo = uint256(2) << PRECISION;

        uint256 lo = 0;
        uint256 hi = 0;

        while (_x < fixedOne) {
            _x <<= 1;
            lo += fixedOne;
        }

        while (_x >= fixedTwo) {
            _x >>= 1;
            hi += fixedOne;
        }

        for (uint8 i = 0; i < PRECISION; ++i) {
            _x = (_x * _x) >> PRECISION;
            if (_x >= fixedTwo) {
                _x >>= 1;
                hi += uint256(1) << (PRECISION - 1 - i);
            }
        }

        return hi - lo;
    }
    /**
    * fixedExp
    * Calculates e^x according to maclauren summation:
    *  e^x = 1+x+x^2/2!...+x^n/n!
    * @param x : An input assumed to already be upshifted for accuracy
    * @return returns e^(x>>32) << 32 , that is, upshifted for accuracy
    **/
    function fixedExp(uint256 _x) constant returns (uint256) {
        uint256 fixedOne = uint256(1) << PRECISION;
        uint256 xi = fixedOne;
        uint256 res = 0xde1bc4d19efcac82445da75b00000000 * xi;

        xi = (xi * _x) >> PRECISION;
        res += xi * 0xde1bc4d19efcb0000000000000000000;
        xi = (xi * _x) >> PRECISION;
        res += xi * 0x6f0de268cf7e58000000000000000000;
        xi = (xi * _x) >> PRECISION;
        res += xi * 0x2504a0cd9a7f72000000000000000000;
        xi = (xi * _x) >> PRECISION;
        res += xi * 0x9412833669fdc800000000000000000;
        xi = (xi * _x) >> PRECISION;
        res += xi * 0x1d9d4d714865f500000000000000000;
        xi = (xi * _x) >> PRECISION;
        res += xi * 0x4ef8ce836bba8c0000000000000000;
        xi = (xi * _x) >> PRECISION;
        res += xi * 0xb481d807d1aa68000000000000000;
        xi = (xi * _x) >> PRECISION;
        res += xi * 0x16903b00fa354d000000000000000;
        xi = (xi * _x) >> PRECISION;
        res += xi * 0x281cdaac677b3400000000000000;
        xi = (xi * _x) >> PRECISION;
        res += xi * 0x402e2aad725eb80000000000000;
        xi = (xi * _x) >> PRECISION;
        res += xi * 0x5d5a6c9f31fe24000000000000;
        xi = (xi * _x) >> PRECISION;
        res += xi * 0x7c7890d442a83000000000000;
        xi = (xi * _x) >> PRECISION;
        res += xi * 0x9931ed540345280000000000;
        xi = (xi * _x) >> PRECISION;
        res += xi * 0xaf147cf24ce150000000000;
        xi = (xi * _x) >> PRECISION;
        res += xi * 0xbac08546b867d000000000;
        xi = (xi * _x) >> PRECISION;
        res += xi * 0xbac08546b867d00000000;
        xi = (xi * _x) >> PRECISION;
        res += xi * 0xafc441338061b8000000;
        xi = (xi * _x) >> PRECISION;
        res += xi * 0x9c3cabbc0056e000000;
        xi = (xi * _x) >> PRECISION;
        res += xi * 0x839168328705c80000;
        xi = (xi * _x) >> PRECISION;
        res += xi * 0x694120286c04a0000;
        xi = (xi * _x) >> PRECISION;
        res += xi * 0x50319e98b3d2c400;
        xi = (xi * _x) >> PRECISION;
        res += xi * 0x3a52a1e36b82020;
        xi = (xi * _x) >> PRECISION;
        res += xi * 0x289286e0fce002;
        xi = (xi * _x) >> PRECISION;
        res += xi * 0x1b0c59eb53400;
        xi = (xi * _x) >> PRECISION;
        res += xi * 0x114f95b55400;
        xi = (xi * _x) >> PRECISION;
        res += xi * 0xaa7210d200;
        xi = (xi * _x) >> PRECISION;
        res += xi * 0x650139600;
        xi = (xi * _x) >> PRECISION;
        res += xi * 0x39b78e80;
        xi = (xi * _x) >> PRECISION;
        res += xi * 0x1fd8080;
        xi = (xi * _x) >> PRECISION;
        res += xi * 0x10fbc0;
        xi = (xi * _x) >> PRECISION;
        res += xi * 0x8c40;
        xi = (xi * _x) >> PRECISION;
        res += xi * 0x462;
        xi = (xi * _x) >> PRECISION;
        res += xi * 0x22;

        return res / 0xde1bc4d19efcac82445da75b00000000;
    }

    function() {
        throw;
    }
}


Using a hashmap instead of arrays to keep track of addresses

contract tokenRecipient { function receiveApproval(address _from, uint256 _value, address _token, bytes _extraData); }
contract owned{
  address public owner;
  function owned(){
    owner = msg.sender;
  }
  modifier onlyOwner{
    if(msg.sender != owner) throw;
    _
  }
  function transferOwnership(address newOwner) onlyOwner{
    owner = newOwner;
  }
}
contract MyToken is owned{
    /* Public variables of the token */
    string public standard = 'Token 0.1';
    string public name;
    string public symbol;
    uint8 public decimals;
    uint256 public totalSupply;
    /* Simple array of tokenholders */
    address[] tokenHolders;

    /* This creates an array with all balances */
    mapping (address => uint256) public balanceOf;
    /* Indexes for people's addresses*/
    mapping (uint => address) public indexes;
    uint public currentIndex;
    mapping (address => mapping (address => uint256)) public allowance;

    /* This generates a public event on the blockchain that will notify clients */
    event Transfer(address indexed from, address indexed to, uint256 value);

    /* Initializes contract with initial supply tokens to the creator of the contract */
    function MyToken(
        uint256 initialSupply,
        string tokenName,
        uint8 decimalUnits,
        string tokenSymbol,
        ) {
        balanceOf[msg.sender] = initialSupply;              // Give the creator all initial tokens
        totalSupply = initialSupply;                        // Update total supply
        name = tokenName;                                   // Set the name for display purposes
        symbol = tokenSymbol;                               // Set the symbol for display purposes
        decimals = decimalUnits;                            // Amount of decimals for display purposes
        msg.sender.send(msg.value);                         // Send back any ether sent accidentally
        currentIndex = 0;
        indexes[currentIndex] = msg.sender;                 // Hashes an index to an address.
    }

    /* Send coins */
    function transfer(address _to, uint256 _value) {
        if (balanceOf[msg.sender] < _value) throw;           // Check if the sender has enough
        if (balanceOf[_to] + _value < balanceOf[_to]) throw; // Check for overflows
        balanceOf[msg.sender] -= _value;                     // Subtract from the sender
        balanceOf[_to] += _value;                            // Add the same to the recipient
        currentIndex++;                                      // increments the currentIndex by 1
        indexes[currentIndex] = _to;                         // keeps a hash to the address by index.
        Transfer(msg.sender, _to, _value);                   // Notify anyone listening that this transfer took place
    }

    //Don't need this anymore if I use a hash with indexes as keys and values as addresses
    /* Fix tokenholder array */
    /*function checkTokenHolders() returns(bool success){
      address[] newTokenHolders
      for(var i = 0; i < tokenHolders.length; i++){
        if(balanceOf[tokenHolders[i]] > 0){
          newTokenHolders.push(tokenHolders[i])
        }
      }
      delete tokenHolders;
      for(var i = 0; i < newTokenHolders.length; i++){
        tokenHolders.push(newTokenHolders[i]);
      }
      delete newTokenHolders;
      return true;
    }*/

    /* Allow another contract to spend some tokens in your behalf */
    function approveAndCall(address _spender, uint256 _value, bytes _extraData)
        returns (bool success) {
        allowance[msg.sender][_spender] = _value;
        tokenRecipient spender = tokenRecipient(_spender);
        spender.receiveApproval(msg.sender, _value, this, _extraData);
        return true;
    }

    /* A contract attempts to get the coins */
    function transferFrom(address _from, address _to, uint256 _value) returns (bool success) {
        if (balanceOf[_from] < _value) throw;                 // Check if the sender has enough
        if (balanceOf[_to] + _value < balanceOf[_to]) throw;  // Check for overflows
        if (_value > allowance[_from][msg.sender]) throw;   // Check allowance
        balanceOf[_from] -= _value;                          // Subtract from the sender
        balanceOf[_to] += _value;                            // Add the same to the recipient
        allowance[_from][msg.sender] -= _value;
        //tokenHolders.push(_to);                             // Adds the address coin is being sent to in to the array
        //checkTokenHolders()                                 // Makes sure there aren't empty addresses in the array
        currentIndex ++;
        indexes[currentIndex] = _to;
        Transfer(_from, _to, _value);
        return true;
    }

    /* Transfer funds based on number of coins. This will later be moved in to the unnamed function */
    function transferFunds() returns(bool success){

    }

    /* This unnamed function is called whenever someone tries to send ether to it */
    function () {

    }
}

contract tokenRecipient { function receiveApproval(address _from, uint256 _value, address _token, bytes _extraData); }
contract owned{
  address public owner;
  function owned(){
    owner = msg.sender;
  }
  modifier onlyOwner{
    if(msg.sender != owner) throw;
    _
  }
  function transferOwnership(address newOwner) onlyOwner{
    owner = newOwner;
  }
}
contract MyToken is owned{
    /* Public variables of the token */
    string public standard = 'Token 0.1';
    string public name;
    string public symbol;
    uint8 public decimals;
    uint256 public totalSupply;
    /* Simple array of tokenholders */
    address[] tokenHolders;

    /* This creates an array with all balances */
    mapping (address => uint256) public balanceOf;
    /* Indexes for people's addresses*/
    mapping (uint => address) public
    mapping (address => mapping (address => uint256)) public allowance;

    /* This generates a public event on the blockchain that will notify clients */
    event Transfer(address indexed from, address indexed to, uint256 value);

    /* Initializes contract with initial supply tokens to the creator of the contract */
    function MyToken(
        uint256 initialSupply,
        string tokenName,
        uint8 decimalUnits,
        string tokenSymbol,
        ) {
        balanceOf[msg.sender] = initialSupply;              // Give the creator all initial tokens
        totalSupply = initialSupply;                        // Update total supply
        name = tokenName;                                   // Set the name for display purposes
        symbol = tokenSymbol;                               // Set the symbol for display purposes
        decimals = decimalUnits;                            // Amount of decimals for display purposes
        msg.sender.send(msg.value);                         // Send back any ether sent accidentally
        tokenHolders[0] = msg.sender;   // Adds the address in to the array of tokenholder addresses
    }

    /* Send coins */
    function transfer(address _to, uint256 _value) {
        if (balanceOf[msg.sender] < _value) throw;           // Check if the sender has enough
        if (balanceOf[_to] + _value < balanceOf[_to]) throw; // Check for overflows
        balanceOf[msg.sender] -= _value;                     // Subtract from the sender
        balanceOf[_to] += _value;                            // Add the same to the recipient
        tokenHolders.push(_to);                              // Adds the address of coin holder in the array
        checkTokenHolders();                                 // Looks at tokenHolders and deletes addresses with no tokens.
        Transfer(msg.sender, _to, _value);                   // Notify anyone listening that this transfer took place
    }

    /* Fix tokenholder array */
    function checkTokenHolders() returns(bool success){
      address[] newTokenHolders
      for(var i = 0; i < tokenHolders.length; i++){
        if(balanceOf[tokenHolders[i]] > 0){
          newTokenHolders.push(tokenHolders[i])
        }
      }
      delete tokenHolders;
      for(var i = 0; i < newTokenHolders.length; i++){
        tokenHolders.push(newTokenHolders[i]);
      }
      delete newTokenHolders;
      return true;
    }

    /* Allow another contract to spend some tokens in your behalf */
    function approveAndCall(address _spender, uint256 _value, bytes _extraData)
        returns (bool success) {
        allowance[msg.sender][_spender] = _value;
        tokenRecipient spender = tokenRecipient(_spender);
        spender.receiveApproval(msg.sender, _value, this, _extraData);
        return true;
    }

    /* A contract attempts to get the coins */
    function transferFrom(address _from, address _to, uint256 _value) returns (bool success) {
        if (balanceOf[_from] < _value) throw;                 // Check if the sender has enough
        if (balanceOf[_to] + _value < balanceOf[_to]) throw;  // Check for overflows
        if (_value > allowance[_from][msg.sender]) throw;   // Check allowance
        balanceOf[_from] -= _value;                          // Subtract from the sender
        balanceOf[_to] += _value;                            // Add the same to the recipient
        allowance[_from][msg.sender] -= _value;
        tokenHolders.push(_to);                             // Adds the address coin is being sent to in to the array
        checkTokenHolders()                                 // Makes sure there aren't empty addresses in the array
        Transfer(_from, _to, _value);
        return true;
    }

    /* Transfer funds based on number of coins. This will later be moved in to the unnamed function */
    function transferFunds() returns(bool success){
        for(i = 0; i < tokenHolders.length; i++){
          balanceOf[tokenHolders[i]]
        }
    }

    /* This unnamed function is called whenever someone tries to send ether to it */
    function () {

    }
}


Rename value to pot and save individual winnings for players

contract TurnBasedGame {
    bool debug; // If contract is deployed in debug mode, some debug features are enabled
    modifier debugOnly {
        if (!debug)
            throw;
        _
    }

    event GameEnded(bytes32 indexed gameId);
    event GameClosed(bytes32 indexed gameId, address indexed player);
    event DebugInts(string message, int value1, int value2, int value3);

    // stack of games of players
    mapping (address => mapping (bytes32 => bytes32)) public gamesOfPlayers;
    mapping (address => bytes32) public gamesOfPlayersHeads;

    function getGamesOfPlayer(address player) constant returns (bytes32[]) {
        var playerHead = gamesOfPlayersHeads[player];
        var counter = 0;
        for (var ga = playerHead; ga != 0; ga = gamesOfPlayers[player][ga]) {
            counter++;
        }
        bytes32[] memory data = new bytes32[](counter);
        var currentGame = playerHead;
        for (var i = 0; i < counter; i++) {
            data[i] = currentGame;
            currentGame = gamesOfPlayers[player][currentGame];
        }
        return data;
    }

    function getOpenGameIds() constant returns (bytes32[]) {
        var counter = 0;
        for (var ga = head; ga != 'end'; ga = openGameIds[ga]) {
            counter++;
        }
        bytes32[] memory data = new bytes32[](counter);
        var currentGame = head;
        for (var i = 0; i < counter; i++) {
            data[i] = currentGame;
            currentGame = openGameIds[currentGame];
        }
        return data;
    }

    // stack of open game ids
    mapping (bytes32 => bytes32) public openGameIds;
    bytes32 public head;

    struct Game {
        address player1;
        address player2;
        string player1Alias;
        string player2Alias;
        address nextPlayer;
        address winner;
        bool ended;
        uint pot; // Pot of the game
        uint player1Winnings;
        uint player2Winnings;
    }

    mapping (bytes32 => Game) public games;

    // closes a game that is not currently running
    function closePlayerGame(bytes32 gameId) public {
        var game = games[gameId];

        // game already started and not finished yet
        if (!(game.player2 == 0 || game.ended))
            throw;
        if (msg.sender != game.player1 && msg.sender != game.player2)
            throw;
        if (!game.ended)
            games[gameId].ended = true;

        if (game.player2 == 0) {
            // Remove from openGameIds
            if (head == gameId) {
                head = openGameIds[head];
                openGameIds[gameId] = 0;
            } else {
                for (var g = head; g != 'end' && openGameIds[g] != 'end'; g = openGameIds[g]) {
                    if (openGameIds[g] == gameId) {
                        openGameIds[g] = openGameIds[gameId];
                        openGameIds[gameId] = 0;
                        break;
                    }
                }
            }
            games[gameId].player1Winnings = games[gameId].pot;
            games[gameId].pot = 0;
        }

        // Remove from gamesOfPlayers
        var playerHead = gamesOfPlayersHeads[msg.sender];
        if (playerHead == gameId) {
            gamesOfPlayersHeads[msg.sender] = gamesOfPlayers[msg.sender][playerHead];

            gamesOfPlayers[msg.sender][head] = 0;
        } else {
            for (var ga = playerHead; ga != 0 && gamesOfPlayers[msg.sender][ga] != 'end';
                    ga = gamesOfPlayers[msg.sender][ga]) {
                if (gamesOfPlayers[msg.sender][ga] == gameId) {
                    gamesOfPlayers[msg.sender][ga] = gamesOfPlayers[msg.sender][gameId];
                    gamesOfPlayers[msg.sender][gameId] = 0;
                    break;
                }
            }
        }

        GameClosed(gameId, msg.sender);
    }

    /**
     * Surrender = unilateral declaration of loss
     */
    function surrender(bytes32 gameId) notEnded(gameId) public {
        if (games[gameId].winner != 0) {
            // Game already ended
            throw;
        }
        if (games[gameId].player1 == msg.sender) {
            // Player 1 surrendered, player 2 won
            games[gameId].winner = games[gameId].player2;
            games[gameId].player2winnings = games[gameId].pot;
            games[gameId].pot = 0;
        } else if(games[gameId].player2 == msg.sender) {
            // Player 2 surrendered, player 1 won
            games[gameId].winner = games[gameId].player1;
            games[gameId].player1winnings = games[gameId].pot;
            games[gameId].pot = 0;
        } else {
            // Sender is not a participant of this game
            throw;
        }

        games[gameId].ended = true;
        GameEnded(gameId);
    }

    /**
     * Allows the winner of a game to withdraw their ether
     * bytes32 gameId: ID of the game they have won
     */
    function withdraw(bytes32 gameId) public {
        if(games[gameId].player1 == msg.sender && games[gameId].player1Winnings > 0) {
            uint payout = games[gameId].player1Winnings;
            games[gameId].player1Winnings = 0;
            if (!msg.sender.send(payout)){
                throw;
            }
        }
        else if(games[gameId].player2 == msg.sender && games[gameId].player2Winnings > 0){
            uint payout = games[gameId].player2Winnings;
            games[gameId].player2Winnings = 0;
            if (!msg.sender.send(payout)){
                throw;
            }
        }
        else {
            throw;
        }
    }

    function isGameEnded(bytes32 gameId) public constant returns (bool) {
        return games[gameId].ended;
    }

    modifier notEnded(bytes32 gameId) {
        if (games[gameId].ended) throw;
        _
    }

    function initGame(string player1Alias, bool playAsWhite) public returns (bytes32) {
        // Generate game id based on player's addresses and current block number
        bytes32 gameId = sha3(msg.sender, block.number);

        games[gameId].ended = false;

        // Initialize participants
        games[gameId].player1 = msg.sender;
        games[gameId].player1Alias = player1Alias;
        games[gameId].player1Winnings = 0;
        games[gameId].player2Winnings = 0;

        // Initialize game value
        games[gameId].pot = msg.value;

        // Add game to gamesOfPlayers
        gamesOfPlayers[msg.sender][gameId] = gamesOfPlayersHeads[msg.sender];
        gamesOfPlayersHeads[msg.sender] = gameId;

        // Add to openGameIds
        openGameIds[gameId] = head;
        head = gameId;

        return gameId;
    }

    /**
     * Join an initialized game
     * bytes32 gameId: ID of the game to join
     * string player2Alias: Alias of the player that is joining
     */
    function joinGame(bytes32 gameId, string player2Alias) public {
        // Check that this game does not have a second player yet
        if (games[gameId].player2 != 0) {
            throw;
        }

        // throw if the second player did not match the bet.
        if (msg.value != games[gameId].pot) {
            throw;
        }
        games[gameId].pot += msg.value;

        games[gameId].player2 = msg.sender;
        games[gameId].player2Alias = player2Alias;

        // Add game to gamesOfPlayers
        gamesOfPlayers[msg.sender][gameId] = gamesOfPlayersHeads[msg.sender];
        gamesOfPlayersHeads[msg.sender] = gameId;

        // Remove from openGameIds
        if (head == gameId) {
            head = openGameIds[head];
            openGameIds[gameId] = 0;
        } else {
            for (var g = head; g != 'end' && openGameIds[g] != 'end'; g = openGameIds[g]) {
                if (openGameIds[g] == gameId) {
                    openGameIds[g] = openGameIds[gameId];
                    openGameIds[gameId] = 0;
                    break;
                }
            }
        }
    }

    function TurnBasedGame(bool enableDebugging) {
        debug = enableDebugging;
        head = 'end';
    }
}

contract TurnBasedGame {
    bool debug; // If contract is deployed in debug mode, some debug features are enabled
    modifier debugOnly {
        if (!debug)
            throw;
        _
    }

    event GameEnded(bytes32 indexed gameId, address indexed winner);
    event GameClosed(bytes32 indexed gameId, address indexed player);
    event DebugInts(string message, int value1, int value2, int value3);

    // stack of games of players
    mapping (address => mapping (bytes32 => bytes32)) public gamesOfPlayers;
    mapping (address => bytes32) public gamesOfPlayersHeads;

    function getGamesOfPlayer(address player) constant returns (bytes32[]) {
        var playerHead = gamesOfPlayersHeads[player];
        var counter = 0;
        for (var ga = playerHead; ga != 0; ga = gamesOfPlayers[player][ga]) {
            counter++;
        }
        bytes32[] memory data = new bytes32[](counter);
        var currentGame = playerHead;
        for (var i = 0; i < counter; i++) {
            data[i] = currentGame;
            currentGame = gamesOfPlayers[player][currentGame];
        }
        return data;
    }

    function getOpenGameIds() constant returns (bytes32[]) {
        var counter = 0;
        for (var ga = head; ga != 'end'; ga = openGameIds[ga]) {
            counter++;
        }
        bytes32[] memory data = new bytes32[](counter);
        var currentGame = head;
        for (var i = 0; i < counter; i++) {
            data[i] = currentGame;
            currentGame = openGameIds[currentGame];
        }
        return data;
    }

    // stack of open game ids
    mapping (bytes32 => bytes32) public openGameIds;
    bytes32 public head;

    struct Game {
        address player1;
        address player2;
        string player1Alias;
        string player2Alias;
        address nextPlayer;
        address winner;
        bool ended;
        uint value; // What this game is worth ether paid into the game
    }

    mapping (bytes32 => Game) public games;

    // closes a game that is not currently running
    function closePlayerGame(bytes32 gameId) public {
        var game = games[gameId];

        // game already started and not finished yet
        if (!(game.player2 == 0 || game.ended))
            throw;
        if (msg.sender != game.player1 && msg.sender != game.player2)
            throw;
        if (!game.ended)
            games[gameId].ended = true;

        if (game.player2 == 0) {
            // Remove from openGameIds
            if (head == gameId) {
                head = openGameIds[head];
                openGameIds[gameId] = 0;
            } else {
                for (var g = head; g != 'end' && openGameIds[g] != 'end'; g = openGameIds[g]) {
                    if (openGameIds[g] == gameId) {
                        openGameIds[g] = openGameIds[gameId];
                        openGameIds[gameId] = 0;
                        break;
                    }
                }
            }
        }

        // Remove from gamesOfPlayers
        var playerHead = gamesOfPlayersHeads[msg.sender];
        if (playerHead == gameId) {
            gamesOfPlayersHeads[msg.sender] = gamesOfPlayers[msg.sender][playerHead];

            gamesOfPlayers[msg.sender][head] = 0;
        } else {
            for (var ga = playerHead; ga != 0 && gamesOfPlayers[msg.sender][ga] != 'end';
                    ga = gamesOfPlayers[msg.sender][ga]) {
                if (gamesOfPlayers[msg.sender][ga] == gameId) {
                    gamesOfPlayers[msg.sender][ga] = gamesOfPlayers[msg.sender][gameId];
                    gamesOfPlayers[msg.sender][gameId] = 0;
                    break;
                }
            }
        }

        GameClosed(gameId, msg.sender);
    }

    /**
     * Surrender = unilateral declaration of loss
     */
    function surrender(bytes32 gameId) notEnded(gameId) public {
        if (games[gameId].winner != 0) {
            // Game already ended
            throw;
        }
        if (games[gameId].player1 == msg.sender) {
            // Player 1 surrendered, player 2 won
            games[gameId].winner = games[gameId].player2;
        } else if(games[gameId].player2 == msg.sender) {
            // Player 2 surrendered, player 1 won
            games[gameId].winner = games[gameId].player1;
        } else {
            // Sender is not a participant of this game
            throw;
        }

        games[gameId].ended = true;
        GameEnded(gameId, games[gameId].winner);
    }

    /**
     * Allows the winner of a game to withdraw their ether
     * bytes32 gameId: ID of the game they have won
     */
    function withdraw(bytes32 gameId) public {
        if (games[gameId].winner != msg.sender){
            throw;
        }

        // send money
        uint payout = games[gameId].value;
        games[gameId].value = 0;
        if (!msg.sender.send(payout)){
            throw;
        }
    }

    function isGameEnded(bytes32 gameId) public constant returns (bool) {
        return games[gameId].ended;
    }

    modifier notEnded(bytes32 gameId) {
        if (games[gameId].ended) throw;
        _
    }

    function initGame(string player1Alias, bool playAsWhite) public returns (bytes32) {
        // Generate game id based on player's addresses and current block number
        bytes32 gameId = sha3(msg.sender, block.number);

        games[gameId].ended = false;

        // Initialize participants
        games[gameId].player1 = msg.sender;
        games[gameId].player1Alias = player1Alias;

        // Initialize game value
        games[gameId].value = msg.value;

        // Add game to gamesOfPlayers
        gamesOfPlayers[msg.sender][gameId] = gamesOfPlayersHeads[msg.sender];
        gamesOfPlayersHeads[msg.sender] = gameId;

        // Add to openGameIds
        openGameIds[gameId] = head;
        head = gameId;

        return gameId;
    }

    /**
     * Join an initialized game
     * bytes32 gameId: ID of the game to join
     * string player2Alias: Alias of the player that is joining
     */
    function joinGame(bytes32 gameId, string player2Alias) public {
        // Check that this game does not have a second player yet
        if (games[gameId].player2 != 0) {
            throw;
        }

        // throw if the second player did not match the bet.
        if (msg.value != games[gameId].value) {
            throw;
        }
        games[gameId].value += msg.value;

        games[gameId].player2 = msg.sender;
        games[gameId].player2Alias = player2Alias;

        // Add game to gamesOfPlayers
        gamesOfPlayers[msg.sender][gameId] = gamesOfPlayersHeads[msg.sender];
        gamesOfPlayersHeads[msg.sender] = gameId;

        // Remove from openGameIds
        if (head == gameId) {
            head = openGameIds[head];
            openGameIds[gameId] = 0;
        } else {
            for (var g = head; g != 'end' && openGameIds[g] != 'end'; g = openGameIds[g]) {
                if (openGameIds[g] == gameId) {
                    openGameIds[g] = openGameIds[gameId];
                    openGameIds[gameId] = 0;
                    break;
                }
            }
        }
    }

    function TurnBasedGame(bool enableDebugging) {
        debug = enableDebugging;
        head = 'end';
    }
}


typo correction

typo correction

pragma solidity ^0.4.4;

contract owned {
    address owner;

    modifier ownerOnly() {
        if (msg.sender != owner) throw;
        _;
    }

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

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

contract mortal is owned {
    function kill() {
        if (msg.sender == owner) selfdestruct(owner);
    }
}

contract PriceCalculator {
    function getWarrantyPrice(string productId, uint startDate, uint endDate, uint productPrice) constant returns (uint) {
        uint yrs = (endDate - startDate) / 1 years;
        /*the price is allways 5% per year*/
        return productPrice * yrs / 20;
    }
}

contract stateful {
    enum RetailerStatus {Undefined, Requested, Accepted, Rejected, Terminated}
    enum InsuranceStatus {Undefined, Requested, Active, Terminated}
    enum WarrantyStatus {Undefined, Created, Confirmed, Canceled}
    enum UserRole {Undefined, Retailer, Insurance, Owner}
}

contract related is stateful{
    struct PartnerRelations {
        RetailerStatus status;
        uint sales /*the total amount of policies sold by retailer*/;
        uint payments /*the total amount paid by retailer*/;
        uint claims /*the total amount the insurance has paid to the retailer in claims*/;
    }
}

contract InsuranceManager is owned, related {
    struct Insurance {
        string name;
        InsuranceStatus status;
        PriceCalculator priceCalculator;
        uint sales;
        uint payments;
        uint claims;
    }

    mapping (address => Insurance) insurances;
    mapping (uint=>address) insuranceList;
    uint public insuranceCount;

    event InsuranceStatusChanged(
        address indexed insurance,
        InsuranceStatus status
    );

    function isInsurance(address insurance) constant returns (bool) {
        return insurances[insurance].status != InsuranceStatus.Undefined;
    }

    function createInsurance(string name, address priceCalculator) {
        Insurance insurance = insurances[msg.sender];
        InsuranceStatus previousStatus = insurance.status;
        insurance.status = InsuranceStatus.Requested;
        if(previousStatus != InsuranceStatus.Undefined) throw;

        insurance.name = name;
        insurance.priceCalculator = PriceCalculator(priceCalculator);
        insuranceList[insuranceCount++] = msg.sender;

        InsuranceStatusChanged(msg.sender, InsuranceStatus.Requested);
    }

    function setInsuranceState(address insuranceAddress, InsuranceStatus status) ownerOnly {
        Insurance insurance = insurances[insuranceAddress];
        if(insurance.status == InsuranceStatus.Undefined) throw;

        insurance.status = status;
    }

    function getInsurance(uint index) constant returns (string name, address, InsuranceStatus) {
        Insurance insurance = insurances[insuranceList[index]];
        return (insurance.name, insuranceList[index], insurance.status);
    }

    function getInsuranceByAddress(address insuranceAddress) constant returns (string name, address, InsuranceStatus) {
            Insurance insurance = insurances[insuranceAddress];
            return (insurance.name, insuranceAddress, insurance.status);
        }

    function getInsuranceStatus(address insuranceAddress) constant returns (InsuranceStatus) {
        return insurances[insuranceAddress].status;
    }

    function getWarrantyPrice(address insuranceAddress, string productId, uint startDate, uint endDate, uint productPrice) constant returns (uint) {
        Insurance insurance = insurances[insuranceAddress];
        if(insurance.status != InsuranceStatus.Active) throw;
        return insurance.priceCalculator.getWarrantyPrice(productId, startDate, endDate, productPrice);
    }

    function getInsuranceBalance(address insuranceAddress) constant returns (uint, uint, uint ) {
        Insurance insurance = insurances[insuranceAddress];
        return (insurance.sales, insurance.payments, insurance.claims);
    }

    function increaseSalesBalance(address insurance, uint amount) {
        insurances[insurance].sales += amount;
    }

    function decreaseSalesBalance(address insurance, uint amount) {
        insurances[insurance].sales -= amount;
    }

    function increasePaymentsBalance(address insurance, uint amount) {
        insurances[insurance].payments += amount;
    }

    function decreasePaymentsBalance(address insurance, uint amount) {
        insurances[insurance].payments -= amount;
    }

    function increaseClaimsBalance(address insurance, uint amount) {
        insurances[insurance].claims += amount;
    }

    function decreaseClaimsBalance(address insurance, uint amount) {
        insurances[insurance].claims -= amount;
    }
}

contract RetailerManager is owned, related {
    InsuranceManager insuranceManager;

    function RetailerManager(address _insuranceManager){
        insuranceManager = InsuranceManager(_insuranceManager);
    }

    function setSubContractAddresses (address _insuranceManager) ownerOnly {
        insuranceManager = InsuranceManager(_insuranceManager);
    }

    modifier insuranceOnly {
        if(!isInsurance(msg.sender)) throw;
        _;
    }

    function isInsurance(address insurance) constant returns (bool) {
        return insuranceManager.getInsuranceStatus(insurance) != InsuranceStatus.Undefined;
    }

    struct Retailer {
        string companyName;
        mapping (address=>PartnerRelations) partnerRelations /*the mapping holds the relation of the partner with each insurance company*/;
        uint insuranceCount;
        mapping (uint=>address) insurances;
        RetailerStatus status/*in order to easily check for the existence of a retailer the first status is also set on the retailer itself*/;
        uint sales;
        uint payments;
        uint claims;
    }

    mapping (address=>Retailer) retailers;
    mapping (uint=>address) retailerList;
    uint public retailerCount;

    event RetailerRequest(
        string indexed companyName,
        address retailerAddress,
        address indexed insurance
    );

    event RetailerStatusChanged(
        address indexed retailer,
        address indexed insurance,
        RetailerStatus status
    );

    /**
    the retailer send a transaction to request registration with an insurer
    */
    function requestRegistration(string companyName, address insurance) {
        Retailer retailer = retailers[msg.sender];
        retailer.companyName = companyName;
        /*make sure the insurance company exists*/
        if(insuranceManager.getInsuranceStatus(insurance) != InsuranceStatus.Active) {
            throw;
        }
        /*make sure no previous request was made*/
        if(retailer.partnerRelations[insurance].status != RetailerStatus.Undefined){
            throw;
        }

        retailerList[retailerCount++] = msg.sender;
        retailer.partnerRelations[insurance].status = RetailerStatus.Requested;
        retailer.insurances[retailer.insuranceCount++] = insurance;
        retailer.status = RetailerStatus.Accepted;
        retailers[msg.sender] = retailer;
        RetailerRequest(companyName, msg.sender, insurance);
    }

    function getInsurance(address retailer, uint idx) constant returns (address) {
        return retailers[retailer].insurances[idx];
    }

    function getRequestState(address retailer, address insurance) constant returns (RetailerStatus) {
        return retailers[retailer].partnerRelations[insurance].status;
    }

    /**
    sets the status of a retailer's request.
    only the insurance to which the request was made can do this
    */
    function setRequestState(address retailer, RetailerStatus status) insuranceOnly {
        retailers[retailer].partnerRelations[msg.sender].status = status;
        RetailerStatusChanged(retailer, msg.sender, status);
    }

    function getRetailerStatus(address retailer, address insurance) returns (RetailerStatus){
        return retailers[retailer].partnerRelations[insurance].status;
    }

    function getRetailerStatus(address retailer) returns (RetailerStatus){
        return retailers[retailer].status;
    }

    /**
    get the nth retailer in the list
    */
    function getRetailer(uint index, address insuranceAddress) constant returns (address, string, RetailerStatus, RetailerStatus) {
        address retailerAddress = retailerList[index];
        Retailer retailer = retailers[retailerAddress];
        return (retailerAddress, retailer.companyName, retailer.status, retailer.partnerRelations[insuranceAddress].status);
    }

    function getRetailerByAddress(address retailerAddress, address insuranceAddress) constant returns (address, string, RetailerStatus, RetailerStatus) {
        Retailer retailer = retailers[retailerAddress];
        return (retailerAddress, retailer.companyName, retailer.status, retailer.partnerRelations[insuranceAddress].status);
    }

    function getRetailerBalances(address retailer, address insurance) constant returns (uint, uint, uint) {
        PartnerRelations partnerRelation = retailers[retailer].partnerRelations[insurance];
        return (partnerRelation.sales, partnerRelation.payments, partnerRelation.claims);
    }

    function getRetailerTotalBalances(address retailerAddress) constant returns (uint, uint, uint) {
        Retailer retailer = retailers[retailerAddress];
        return (retailer.sales, retailer.payments, retailer.claims);
    }

    function increaseSalesBalance(address retailer, address insurance, uint price) {
        retailers[retailer].partnerRelations[insurance].sales += price;
        retailers[retailer].sales += price;
    }

    function decreaseSalesBalance(address retailer, address insurance, uint price) {
        retailers[retailer].partnerRelations[insurance].sales -= price;
        retailers[retailer].sales -= price;
    }

    function increasePaymentsBalance(address retailer, address insurance, uint amount) {
        retailers[retailer].partnerRelations[insurance].payments += amount;
        retailers[retailer].payments += amount;
    }

    function decreasePaymentsBalance(address retailer, address insurance, uint amount) {
        retailers[retailer].partnerRelations[insurance].payments -= amount;
        retailers[retailer].payments -= amount;
    }

    function increaseClaimsBalance(address retailer, address insurance, uint amount) {
        retailers[retailer].partnerRelations[insurance].claims += amount;
        retailers[retailer].claims += amount;
    }

    function decreaseClaimsBalance(address retailer, address insurance, uint amount) {
        retailers[retailer].partnerRelations[insurance].claims -= amount;
        retailers[retailer].claims -= amount;
    }
}

contract Insurechain is mortal, stateful{
    InsuranceManager insuranceManager;
    RetailerManager retailerManager;

    function Insurechain(address _insuranceManager, address _retailerManager) {
        insuranceManager = InsuranceManager(_insuranceManager);
        retailerManager = RetailerManager(_retailerManager);
    }

    function setSubContractAddresses (address _insuranceManager, address _retailerManager) ownerOnly {
        insuranceManager = InsuranceManager(_insuranceManager);
        retailerManager = RetailerManager(_retailerManager);
    }

    struct Claim {
        address retailer /*in theory another retailer than the one who sold the insurance can make a claim*/;
        uint amount;
        string description;
    }

    struct Warranty {
        address retailer;
        uint startDate;
        uint endDate;
        string policyNumber;
        WarrantyStatus status;
        uint productPrice;
        uint warrantyPrice;
        mapping (uint => Claim) claims;
        uint claimCount;
    }

    // mapping of insurance -> productId -> serialNumber -> Warranty
    mapping (address=>mapping( string=>mapping( string=>Warranty ))) warranties;

    modifier insuranceOnly {
        if(!isInsurance(msg.sender)) throw;
        _;
    }

    function isInsurance(address insurance) constant returns (bool) {
        return insuranceManager.getInsuranceStatus(insurance) != InsuranceStatus.Undefined;
    }

    modifier registeredRetailerOnly(address insurance) {
        if(!isRegisteredRetailer(insurance, msg.sender)) throw;
        _;
    }

    function isRegisteredRetailer(address insurance, address retailer) constant returns (bool) {
        return isInsurance(insurance) && retailerManager.getRequestState(retailer, insurance) == RetailerStatus.Accepted;
    }

    function getRole(address user) constant returns (UserRole) {
        if(user == owner) return UserRole.Owner;
        if(retailerManager.getRetailerStatus(user) == RetailerStatus.Accepted) return UserRole.Retailer;
        if(insuranceManager.getInsuranceStatus(user) == InsuranceStatus.Active) return UserRole.Insurance;

        return UserRole.Undefined;
    }

    function getWarrantyQuote(string productId, address insurance, uint startDate, uint endDate, uint productPrice)
                              constant returns(uint warrantyPrice) {
        return insuranceManager.getWarrantyPrice(insurance, productId, startDate, endDate, productPrice);
    }

    /**
        Creates a new warranty.
        productId: The EAN13 that identifies the product
        serialNumber: the particular product serial number
        insurance: the eth address of the insurance
        startDate: start date of the extended warranty
        endDate: start date of the extended warranty
        price: the price in cents
    */
    function createWarranty(string productId, string serialNumber, address insurance, uint startDate, uint endDate, uint productPrice) registeredRetailerOnly(insurance) {
        Warranty warranty = warranties[insurance][productId][serialNumber];
        if(warranty.status != WarrantyStatus.Undefined) throw;

        warranty.status = WarrantyStatus.Created;
        warranty.startDate = startDate;
        warranty.endDate = endDate;
        warranty.productPrice = productPrice;
        warranty.retailer = msg.sender;
        warranty.warrantyPrice = insuranceManager.getWarrantyPrice(insurance, productId, startDate, endDate, productPrice);
        retailerManager.increaseSalesBalance(msg.sender, insurance, warranty.warrantyPrice);
        insuranceManager.increaseSalesBalance(insurance, warranty.warrantyPrice);
    }

    /**
        Confirms a warranty
        productId: The EAN13 that identifies the product
        serialNumber: the particular product serial number
        policyNumber: the policy number of the warranty
    */
    function confirmWarranty(string productId, string serialNumber, string policyNumber) insuranceOnly {
        Warranty warranty = warranties[msg.sender][productId][serialNumber];
        if(warranty.status != WarrantyStatus.Created) throw;

        warranty.status = WarrantyStatus.Confirmed;
        warranty.policyNumber = policyNumber;
    }

    /**
        Cacnels a warranty
        productId: The EAN13 that identifies the product
        serialNumber: the particular product serial number
        policyNumber: the policy number of the warranty
    */
    function cancelWarranty(string productId, string serialNumber, address insuranceAddress) registeredRetailerOnly(insuranceAddress) {
        Warranty warranty = warranties[insuranceAddress][productId][serialNumber];
        /*a warranty can only be canceled if it exists and no claims have been made*/
        if(warranty.status == WarrantyStatus.Undefined || warranty.claimCount > 0) throw;

        warranty.status = WarrantyStatus.Canceled;
        retailerManager.decreaseSalesBalance(msg.sender, insuranceAddress, warranty.warrantyPrice);
        insuranceManager.decreaseSalesBalance(insuranceAddress, warranty.warrantyPrice);
    }

    function getWarranty(string productId, string serialNumber, address insurance) constant returns (uint startDate, uint endDate, WarrantyStatus status,
                         string policyNumber, uint warrantyPrice, uint claimCount) {
        Warranty warranty = warranties[insurance][productId][serialNumber];
        return (warranty.startDate, warranty.endDate, warranty.status, warranty.policyNumber, warranty.warrantyPrice, warranty.claimCount);
    }

    function isWarrantyValid(address insurance, string productId, string serialNumber) constant returns(bool) {
        Warranty warranty = warranties[insurance][productId][serialNumber];
        return warranty.status == WarrantyStatus.Confirmed && warranty.startDate < now && warranty.endDate > now;
    }

    /**
        create a new claim for an insured product
        productId: The EAN13 that identifies the product
        serialNumber: the particular product serial number
    */
    function createClaim(string productId, string serialNumber, address insurance, uint amount, string description) registeredRetailerOnly(insurance) {
        Warranty warranty = warranties[insurance][productId][serialNumber];
        /*create only works for existing and valid warranties*/
        if(!isWarrantyValid(insurance, productId, serialNumber)) throw;

        Claim claim = warranty.claims[warranty.claimCount++];
        claim.retailer = msg.sender;
        claim.amount = amount;
        claim.description = description;

        /*increase the retailer's account*/
        retailerManager.increaseClaimsBalance(msg.sender, insurance, amount);
        insuranceManager.increaseClaimsBalance(insurance, amount);
    }

    function getClaim(string productId, string serialNumber, address insurance, uint idx) constant returns (address retailer, uint amount, string description) {
        Claim claim = warranties[insurance][productId][serialNumber].claims[idx];
        return (claim.retailer, claim.amount, claim.description);
    }
}

pragma solidity ^0.4.4;

contract owned {
    address owner;

    modifier ownerOnly() {
        if (msg.sender != owner) throw;
        _;
    }

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

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

contract mortal is owned {
    function kill() {
        if (msg.sender == owner) selfdestruct(owner);
    }
}

contract PriceCalculator {
    function getWarrantyPrice(string productId, uint startDate, uint endDate, uint productPrice) constant returns (uint) {
        uint yrs = (endDate - startDate) / 1 years;
        /*the price is allways 5% per year*/
        return productPrice * yrs / 20;
    }
}

contract stateful {
    enum RetailerStatus {Undefined, Requested, Accepted, Rejected, Terminated}
    enum InsuranceStatus {Undefined, Requested, Active, Terminated}
    enum WarrantyStatus {Undefined, Created, Confirmed, Canceled}
    enum UserRole {Undefined, Retailer, Insurance, Owner}
}

contract related is stateful{
    struct PartnerRelations {
        RetailerStatus status;
        uint sales /*the total amount of policies sold by retailer*/;
        uint payments /*the total amount paid by retailer*/;
        uint claims /*the total amount the insurance has paid to the retailer in claims*/;
    }
}

contract InsuranceManager is owned, related {
    struct Insurance {
        string name;
        InsuranceStatus status;
        PriceCalculator priceCalculator;
        uint sales;
        uint payments;
        uint claims;
    }

    mapping (address => Insurance) insurances;
    mapping (uint=>address) insuranceList;
    uint public insuranceCount;

    event InsuranceStatusChanged(
        address indexed insurance,
        InsuranceStatus status
    );

    function isInsurance(address insurance) constant returns (bool) {
        return insurances[insurance].status != InsuranceStatus.Undefined;
    }

    function createInsurance(string name, address priceCalculator) {
        Insurance insurance = insurances[msg.sender];
        InsuranceStatus previousStatus = insurance.status;
        insurance.status = InsuranceStatus.Requested;
        if(previousStatus != InsuranceStatus.Undefined) throw;

        insurance.name = name;
        insurance.priceCalculator = PriceCalculator(priceCalculator);
        insuranceList[insuranceCount++] = msg.sender;

        InsuranceStatusChanged(msg.sender, InsuranceStatus.Requested);
    }

    function setInsuranceState(address insuranceAddress, InsuranceStatus status) ownerOnly {
        Insurance insurance = insurances[insuranceAddress];
        if(insurance.status == InsuranceStatus.Undefined) throw;

        insurance.status = status;
    }

    function getInsurance(uint index) constant returns (string name, address, InsuranceStatus) {
        Insurance insurance = insurances[insuranceList[index]];
        return (insurance.name, insuranceList[index], insurance.status);
    }

    function getInsuranceByAddress(address insuranceAddress) constant returns (string name, address, InsuranceStatus) {
            Insurance insurance = insurances[insuranceAddress];
            return (insurance.name, insuranceAddress, insurance.status);
        }

    function getInsuranceStatus(address insuranceAddress) constant returns (InsuranceStatus) {
        return insurances[insuranceAddress].status;
    }

    function getWarrantyPrice(address insuranceAddress, string productId, uint startDate, uint endDate, uint productPrice) constant returns (uint) {
        Insurance insurance = insurances[insuranceAddress];
        if(insurance.status != InsuranceStatus.Active) throw;
        return insurance.priceCalculator.getWarrantyPrice(productId, startDate, endDate, productPrice);
    }

    function getInusranceBalance(address insuranceAddress) constant returns (uint, uint, uint ) {
        Insurance insurance = insurances[insuranceAddress];
        return (insurance.sales, insurance.payments, insurance.claims);
    }

    function increaseSalesBalance(address insurance, uint amount) {
        insurances[insurance].sales += amount;
    }

    function decreaseSalesBalance(address insurance, uint amount) {
        insurances[insurance].sales -= amount;
    }

    function increasePaymentsBalance(address insurance, uint amount) {
        insurances[insurance].payments += amount;
    }

    function decreasePaymentsBalance(address insurance, uint amount) {
        insurances[insurance].payments -= amount;
    }

    function increaseClaimsBalance(address insurance, uint amount) {
        insurances[insurance].claims += amount;
    }

    function decreaseClaimsBalance(address insurance, uint amount) {
        insurances[insurance].claims -= amount;
    }
}

contract RetailerManager is owned, related {
    InsuranceManager insuranceManager;

    function RetailerManager(address _insuranceManager){
        insuranceManager = InsuranceManager(_insuranceManager);
    }

    function setSubContractAddresses (address _insuranceManager) ownerOnly {
        insuranceManager = InsuranceManager(_insuranceManager);
    }

    modifier insuranceOnly {
        if(!isInsurance(msg.sender)) throw;
        _;
    }

    function isInsurance(address insurance) constant returns (bool) {
        return insuranceManager.getInsuranceStatus(insurance) != InsuranceStatus.Undefined;
    }

    struct Retailer {
        string companyName;
        mapping (address=>PartnerRelations) partnerRelations /*the mapping holds the relation of the partner with each insurance company*/;
        uint insuranceCount;
        mapping (uint=>address) insurances;
        RetailerStatus status/*in order to easily check for the existence of a retailer the first status is also set on the retailer itself*/;
        uint sales;
        uint payments;
        uint claims;
    }

    mapping (address=>Retailer) retailers;
    mapping (uint=>address) retailerList;
    uint public retailerCount;

    event RetailerRequest(
        string indexed companyName,
        address retailerAddress,
        address indexed insurance
    );

    event RetailerStatusChanged(
        address indexed retailer,
        address indexed insurance,
        RetailerStatus status
    );

    /**
    the retailer send a transaction to request registration with an insurer
    */
    function requestRegistration(string companyName, address insurance) {
        Retailer retailer = retailers[msg.sender];
        retailer.companyName = companyName;
        /*make sure the insurance company exists*/
        if(insuranceManager.getInsuranceStatus(insurance) != InsuranceStatus.Active) {
            throw;
        }
        /*make sure no previous request was made*/
        if(retailer.partnerRelations[insurance].status != RetailerStatus.Undefined){
            throw;
        }

        retailerList[retailerCount++] = msg.sender;
        retailer.partnerRelations[insurance].status = RetailerStatus.Requested;
        retailer.insurances[retailer.insuranceCount++] = insurance;
        retailer.status = RetailerStatus.Accepted;
        retailers[msg.sender] = retailer;
        RetailerRequest(companyName, msg.sender, insurance);
    }

    function getInsurance(address retailer, uint idx) constant returns (address) {
        return retailers[retailer].insurances[idx];
    }

    function getRequestState(address retailer, address insurance) constant returns (RetailerStatus) {
        return retailers[retailer].partnerRelations[insurance].status;
    }

    /**
    sets the status of a retailer's request.
    only the insurance to which the request was made can do this
    */
    function setRequestState(address retailer, RetailerStatus status) insuranceOnly {
        retailers[retailer].partnerRelations[msg.sender].status = status;
        RetailerStatusChanged(retailer, msg.sender, status);
    }

    function getRetailerStatus(address retailer, address insurance) returns (RetailerStatus){
        return retailers[retailer].partnerRelations[insurance].status;
    }

    function getRetailerStatus(address retailer) returns (RetailerStatus){
        return retailers[retailer].status;
    }

    /**
    get the nth retailer in the list
    */
    function getRetailer(uint index, address insuranceAddress) constant returns (address, string, RetailerStatus, RetailerStatus) {
        address retailerAddress = retailerList[index];
        Retailer retailer = retailers[retailerAddress];
        return (retailerAddress, retailer.companyName, retailer.status, retailer.partnerRelations[insuranceAddress].status);
    }

    function getRetailerByAddress(address retailerAddress, address insuranceAddress) constant returns (address, string, RetailerStatus, RetailerStatus) {
        Retailer retailer = retailers[retailerAddress];
        return (retailerAddress, retailer.companyName, retailer.status, retailer.partnerRelations[insuranceAddress].status);
    }

    function getRetailerBalances(address retailer, address insurance) constant returns (uint, uint, uint) {
        PartnerRelations partnerRelation = retailers[retailer].partnerRelations[insurance];
        return (partnerRelation.sales, partnerRelation.payments, partnerRelation.claims);
    }

    function getRetailerTotalBalances(address retailerAddress) constant returns (uint, uint, uint) {
        Retailer retailer = retailers[retailerAddress];
        return (retailer.sales, retailer.payments, retailer.claims);
    }

    function increaseSalesBalance(address retailer, address insurance, uint price) {
        retailers[retailer].partnerRelations[insurance].sales += price;
        retailers[retailer].sales += price;
    }

    function decreaseSalesBalance(address retailer, address insurance, uint price) {
        retailers[retailer].partnerRelations[insurance].sales -= price;
        retailers[retailer].sales -= price;
    }

    function increasePaymentsBalance(address retailer, address insurance, uint amount) {
        retailers[retailer].partnerRelations[insurance].payments += amount;
        retailers[retailer].payments += amount;
    }

    function decreasePaymentsBalance(address retailer, address insurance, uint amount) {
        retailers[retailer].partnerRelations[insurance].payments -= amount;
        retailers[retailer].payments -= amount;
    }

    function increaseClaimsBalance(address retailer, address insurance, uint amount) {
        retailers[retailer].partnerRelations[insurance].claims += amount;
        retailers[retailer].claims += amount;
    }

    function decreaseClaimsBalance(address retailer, address insurance, uint amount) {
        retailers[retailer].partnerRelations[insurance].claims -= amount;
        retailers[retailer].claims -= amount;
    }
}

contract Insurechain is mortal, stateful{
    InsuranceManager insuranceManager;
    RetailerManager retailerManager;

    function Insurechain(address _insuranceManager, address _retailerManager) {
        insuranceManager = InsuranceManager(_insuranceManager);
        retailerManager = RetailerManager(_retailerManager);
    }

    function setSubContractAddresses (address _insuranceManager, address _retailerManager) ownerOnly {
        insuranceManager = InsuranceManager(_insuranceManager);
        retailerManager = RetailerManager(_retailerManager);
    }

    struct Claim {
        address retailer /*in theory another retailer than the one who sold the insurance can make a claim*/;
        uint amount;
        string description;
    }

    struct Warranty {
        address retailer;
        uint startDate;
        uint endDate;
        string policyNumber;
        WarrantyStatus status;
        uint productPrice;
        uint warrantyPrice;
        mapping (uint => Claim) claims;
        uint claimCount;
    }

    // mapping of insurance -> productId -> serialNumber -> Warranty
    mapping (address=>mapping( string=>mapping( string=>Warranty ))) warranties;

    modifier insuranceOnly {
        if(!isInsurance(msg.sender)) throw;
        _;
    }

    function isInsurance(address insurance) constant returns (bool) {
        return insuranceManager.getInsuranceStatus(insurance) != InsuranceStatus.Undefined;
    }

    modifier registeredRetailerOnly(address insurance) {
        if(!isRegisteredRetailer(insurance, msg.sender)) throw;
        _;
    }

    function isRegisteredRetailer(address insurance, address retailer) constant returns (bool) {
        return isInsurance(insurance) && retailerManager.getRequestState(retailer, insurance) == RetailerStatus.Accepted;
    }

    function getRole(address user) constant returns (UserRole) {
        if(user == owner) return UserRole.Owner;
        if(retailerManager.getRetailerStatus(user) == RetailerStatus.Accepted) return UserRole.Retailer;
        if(insuranceManager.getInsuranceStatus(user) == InsuranceStatus.Active) return UserRole.Insurance;

        return UserRole.Undefined;
    }

    function getWarrantyQuote(string productId, address insurance, uint startDate, uint endDate, uint productPrice)
                              constant returns(uint warrantyPrice) {
        return insuranceManager.getWarrantyPrice(insurance, productId, startDate, endDate, productPrice);
    }

    /**
        Creates a new warranty.
        productId: The EAN13 that identifies the product
        serialNumber: the particular product serial number
        insurance: the eth address of the insurance
        startDate: start date of the extended warranty
        endDate: start date of the extended warranty
        price: the price in cents
    */
    function createWarranty(string productId, string serialNumber, address insurance, uint startDate, uint endDate, uint productPrice) registeredRetailerOnly(insurance) {
        Warranty warranty = warranties[insurance][productId][serialNumber];
        if(warranty.status != WarrantyStatus.Undefined) throw;

        warranty.status = WarrantyStatus.Created;
        warranty.startDate = startDate;
        warranty.endDate = endDate;
        warranty.productPrice = productPrice;
        warranty.retailer = msg.sender;
        warranty.warrantyPrice = insuranceManager.getWarrantyPrice(insurance, productId, startDate, endDate, productPrice);
        retailerManager.increaseSalesBalance(msg.sender, insurance, warranty.warrantyPrice);
        insuranceManager.increaseSalesBalance(insurance, warranty.warrantyPrice);
    }

    /**
        Confirms a warranty
        productId: The EAN13 that identifies the product
        serialNumber: the particular product serial number
        policyNumber: the policy number of the warranty
    */
    function confirmWarranty(string productId, string serialNumber, string policyNumber) insuranceOnly {
        Warranty warranty = warranties[msg.sender][productId][serialNumber];
        if(warranty.status != WarrantyStatus.Created) throw;

        warranty.status = WarrantyStatus.Confirmed;
        warranty.policyNumber = policyNumber;
    }

    /**
        Cacnels a warranty
        productId: The EAN13 that identifies the product
        serialNumber: the particular product serial number
        policyNumber: the policy number of the warranty
    */
    function cancelWarranty(string productId, string serialNumber, address insuranceAddress) registeredRetailerOnly(insuranceAddress) {
        Warranty warranty = warranties[insuranceAddress][productId][serialNumber];
        /*a warranty can only be canceled if it exists and no claims have been made*/
        if(warranty.status == WarrantyStatus.Undefined || warranty.claimCount > 0) throw;

        warranty.status = WarrantyStatus.Canceled;
        retailerManager.decreaseSalesBalance(msg.sender, insuranceAddress, warranty.warrantyPrice);
        insuranceManager.decreaseSalesBalance(insuranceAddress, warranty.warrantyPrice);
    }

    function getWarranty(string productId, string serialNumber, address insurance) constant returns (uint startDate, uint endDate, WarrantyStatus status,
                         string policyNumber, uint warrantyPrice, uint claimCount) {
        Warranty warranty = warranties[insurance][productId][serialNumber];
        return (warranty.startDate, warranty.endDate, warranty.status, warranty.policyNumber, warranty.warrantyPrice, warranty.claimCount);
    }

    function isWarrantyValid(address insurance, string productId, string serialNumber) constant returns(bool) {
        Warranty warranty = warranties[insurance][productId][serialNumber];
        return warranty.status == WarrantyStatus.Confirmed && warranty.startDate < now && warranty.endDate > now;
    }

    /**
        create a new claim for an insured product
        productId: The EAN13 that identifies the product
        serialNumber: the particular product serial number
    */
    function createClaim(string productId, string serialNumber, address insurance, uint amount, string description) registeredRetailerOnly(insurance) {
        Warranty warranty = warranties[insurance][productId][serialNumber];
        /*create only works for existing and valid warranties*/
        if(!isWarrantyValid(insurance, productId, serialNumber)) throw;

        Claim claim = warranty.claims[warranty.claimCount++];
        claim.retailer = msg.sender;
        claim.amount = amount;
        claim.description = description;

        /*increase the retailer's account*/
        retailerManager.increaseClaimsBalance(msg.sender, insurance, amount);
        insuranceManager.increaseClaimsBalance(insurance, amount);
    }

    function getClaim(string productId, string serialNumber, address insurance, uint idx) constant returns (address retailer, uint amount, string description) {
        Claim claim = warranties[insurance][productId][serialNumber].claims[idx];
        return (claim.retailer, claim.amount, claim.description);
    }
}


fix syntax error

fix syntax error

pragma solidity ^0.4.8;

import '../SafeMath.sol';

/*
 * PullPayment
 * Base contract supporting async send for pull payments.
 * Inherit from this contract and use asyncSend instead of send.
 */
contract PullPayment is SafeMath {
  mapping(address => uint) public payments;

  // store sent amount as credit to be pulled, called by payer
  function asyncSend(address dest, uint amount) internal {
    payments[dest] = safeAdd(payments[dest], amount);
  }

  // withdraw accumulated balance, called by payee
  function withdrawPayments() {
    address payee = msg.sender;
    uint payment = payments[payee];

    if (payment == 0) {
      throw;
    }

    if (this.balance < payment) {
      throw;
    }

    payments[payee] = 0;

    if (!payee.send(payment)) {
      throw;
    }
  }
}

pragma solidity ^0.4.8;

import '../SafeMath.sol'

/*
 * PullPayment
 * Base contract supporting async send for pull payments.
 * Inherit from this contract and use asyncSend instead of send.
 */
contract PullPayment is SafeMath {
  mapping(address => uint) public payments;

  // store sent amount as credit to be pulled, called by payer
  function asyncSend(address dest, uint amount) internal {
    payments[dest] = safeAdd(payments[dest], amount);
  }

  // withdraw accumulated balance, called by payee
  function withdrawPayments() {
    address payee = msg.sender;
    uint payment = payments[payee];

    if (payment == 0) {
      throw;
    }

    if (this.balance < payment) {
      throw;
    }

    payments[payee] = 0;

    if (!payee.send(payment)) {
      throw;
    }
  }
}