StandingOrderDapp-2 Sanity check inputs to standingorder

pragma solidity ^0.4.4;

import 'zeppelin/ownership/Ownable.sol';

contract StandingOrder is Ownable {

    address public payee;        // The payee gets the money
    uint public startTime;       // Time the order was created
    uint public paymentInterval; // How often can payee claim paymentAmount
    uint public paymentAmount;   // How much can payee claim per period
    uint public claimedFunds;    // How much funds have been claimed already
    string public ownerLabel;    // Label managed by contract owner
    string public payeeLabel;    // Label managed by payee

    function StandingOrder(address _payee, uint _paymentInterval, uint _paymentAmount, string _label) payable {
        // Sanity check parameters
        if (_paymentInterval < 1)
            throw;
        if (_paymentAmount < 1)
            throw;

        payee = _payee;
        paymentInterval = _paymentInterval;
        paymentAmount = _paymentAmount;
        ownerLabel = _label;
        payeeLabel = _label;
        startTime = now;
    }

    modifier onlyPayee() {
        if (msg.sender != payee) {
            throw;
        }
        _;
    }

    /* Allow adding funds to existing order */
    function() payable {
        // TODO: Log entry
    }

    /* How much funds are owned by Payee but not yet withdrawn */
    function getUnclaimedFunds() constant returns (uint) {
        // sanity check
        if (now < startTime) {
            // bad miner trying to mess with block time?
            return 0;
        }

        // Calculate theoretical amount that payee should own right now
        uint age = now - startTime;
        if (age == 0) {
            // order has just been created
            return 0;
        }

        uint completeIntervals = age / paymentInterval;
        // implicitly rounding down
        uint totalAmount = completeIntervals * paymentAmount;

        // subtract already withdrawn funds
        uint entitledAmount = totalAmount - claimedFunds;

        /* entitledAmount might be more than available balance. In this case
         * available balance is the limit */
        uint availableAmount = min(entitledAmount, this.balance);

        return availableAmount;
    }

    /* How much funds are still owned by owner (not yet reserved for payee) */
    function getOwnerFunds() constant returns (uint) {
        return this.balance - getUnclaimedFunds();
    }

    /* Collect payment */
    function collectFunds() {
        // only payee can collect funds
        if (msg.sender != payee) {
            throw;
        }

        uint amount = getUnclaimedFunds();

        if (amount <= 0) {
            // nothing to collect :-(
            throw;
        }

        claimedFunds += amount;
        if (payee.send(amount) == false)
        throw;
    }

    /* Returns remaining funds to owner.
     * Note that this does not return unclaimed funds - They
     * can only be claimed by payee!
     * The Standingorder is not yet cancelled, at any time owner can
     * fund it again!
     */
    function WithdrawOwnerFunds() onlyOwner {
        uint ownerFunds = getOwnerFunds();
        if (ownerFunds <= 0)
        throw;

        if (owner.send(ownerFunds) == false)
        throw;
        // TODO: Log event
    }

    /* Completely cancel this standingOrder */
    function Cancel() onlyOwner {

        // only possible when no funds are left in the contract
        if (this.balance > 0) {
            throw;
        }

        selfdestruct(owner);
    }

    function SetOwnerLabel(string _label) onlyOwner {
        ownerLabel = _label;
    }

    function SetPayeeLabel(string _label) onlyPayee {
        payeeLabel = _label;
    }

    function min(uint a, uint b) returns (uint) {
        if (a < b) return a;
        else return b;
    }
}

contract StandingOrderFactory {

    // keep track who issued standing orders
    mapping (address => StandingOrder[]) public standingOrdersByOwner;
    // keep track of payees of standing orders
    mapping (address => StandingOrder[]) public standingOrdersByPayee;

    // Events
    event LogOrderCreated(
    address orderAddress,
    address indexed owner,
    address indexed payee
    );

    // Create a new standing order. Allow to fund contract while creating, therefor "payable"
    function createStandingOrder(address payee, uint rate, uint interval, string label) returns (StandingOrder) {
        // StandingOrder so = (new StandingOrder).value(msg.value)(msg.sender, payee, interval, rate);
        StandingOrder so = new StandingOrder(payee, interval, rate, label);
        // Now the factory is the owner. Give ownershop to real owner.
        so.transferOwnership(msg.sender);
        standingOrdersByOwner[msg.sender].push(so);
        standingOrdersByPayee[payee].push(so);
        LogOrderCreated(so, msg.sender, payee);
        return so;
    }

    function getNumOrdersByOwner() constant returns (uint) {
        return standingOrdersByOwner[msg.sender].length;
    }

    function getOwnOrderByIndex(uint index) constant returns (StandingOrder) {
        return standingOrdersByOwner[msg.sender][index];
    }

    function getNumOrdersByPayee() constant returns (uint) {
        return standingOrdersByPayee[msg.sender].length;
    }

    function getPaidOrderByIndex(uint index) constant returns (StandingOrder) {
        return standingOrdersByPayee[msg.sender][index];
    }
}

pragma solidity ^0.4.4;

import 'zeppelin/ownership/Ownable.sol';

contract StandingOrder is Ownable {

    address public payee;
    uint public startTime;
    uint public paymentInterval;
    uint public paymentAmount;
    uint public claimedFunds;   // How much funds have been claimed already
    string public ownerLabel;   // Label managed by contract owner
    string public payeeLabel;   // Label managed by payee

    function StandingOrder(address _payee, uint _paymentInterval, uint _paymentAmount, string _label) payable {
        payee = _payee;
        paymentInterval = _paymentInterval;
        paymentAmount = _paymentAmount;
        ownerLabel = _label;
        payeeLabel = _label;
        startTime = now;
    }

    modifier onlyPayee() {
        if (msg.sender != payee) {
            throw;
        }
        _;
    }

    /* Allow adding funds to existing order */
    function() payable {
        // TODO: Log entry
    }

    /* How much funds are owned by Payee but not yet withdrawn */
    function getUnclaimedFunds() constant returns (uint) {
        // sanity check
        if (now < startTime) {
            // bad miner trying to mess with block time?
            return 0;
        }

        // Calculate theoretical amount that payee should own right now
        uint age = now - startTime;
        if (age == 0) {
            // order has just been created
            return 0;
        }

        uint completeIntervals = age / paymentInterval;
        // implicitly rounding down
        uint totalAmount = completeIntervals * paymentAmount;

        // subtract already withdrawn funds
        uint entitledAmount = totalAmount - claimedFunds;

        /* entitledAmount might be more than available balance. In this case
         * available balance is the limit */
        uint availableAmount = min(entitledAmount, this.balance);

        return availableAmount;
    }

    /* How much funds are still owned by owner (not yet reserved for payee) */
    function getOwnerFunds() constant returns (uint) {
        return this.balance - getUnclaimedFunds();
    }

    /* Collect payment */
    function collectFunds() {
        // only payee can collect funds
        if (msg.sender != payee) {
            throw;
        }

        uint amount = getUnclaimedFunds();

        if (amount <= 0) {
            // nothing to collect :-(
            throw;
        }

        claimedFunds += amount;
        if (payee.send(amount) == false)
        throw;
    }

    /* Returns remaining funds to owner.
     * Note that this does not return unclaimed funds - They
     * can only be claimed by payee!
     * The Standingorder is not yet cancelled, at any time owner can
     * fund it again!
     */
    function WithdrawOwnerFunds() onlyOwner {
        uint ownerFunds = getOwnerFunds();
        if (ownerFunds <= 0)
        throw;

        if (owner.send(ownerFunds) == false)
        throw;
        // TODO: Log event
    }

    /* Completely cancel this standingOrder */
    function Cancel() onlyOwner {

        // only possible when no funds are left in the contract
        if (this.balance > 0) {
            throw;
        }

        selfdestruct(owner);
    }

    function SetOwnerLabel(string _label) onlyOwner {
        ownerLabel = _label;
    }

    function SetPayeeLabel(string _label) onlyPayee {
        payeeLabel = _label;
    }

    function min(uint a, uint b) returns (uint) {
        if (a < b) return a;
        else return b;
    }
}

contract StandingOrderFactory {

    // keep track who issued standing orders
    mapping (address => StandingOrder[]) public standingOrdersByOwner;
    // keep track of payees of standing orders
    mapping (address => StandingOrder[]) public standingOrdersByPayee;

    // Events
    event LogOrderCreated(
    address orderAddress,
    address indexed owner,
    address indexed payee
    );

    // Create a new standing order. Allow to fund contract while creating, therefor "payable"
    function createStandingOrder(address payee, uint rate, uint interval, string label) returns (StandingOrder) {
        // StandingOrder so = (new StandingOrder).value(msg.value)(msg.sender, payee, interval, rate);
        StandingOrder so = new StandingOrder(payee, interval, rate, label);
        // Now the factory is the owner. Give ownershop to real owner.
        so.transferOwnership(msg.sender);
        standingOrdersByOwner[msg.sender].push(so);
        standingOrdersByPayee[payee].push(so);
        LogOrderCreated(so, msg.sender, payee);
        return so;
    }

    function getNumOrdersByOwner() constant returns (uint) {
        return standingOrdersByOwner[msg.sender].length;
    }

    function getOwnOrderByIndex(uint index) constant returns (StandingOrder) {
        return standingOrdersByOwner[msg.sender][index];
    }

    function getNumOrdersByPayee() constant returns (uint) {
        return standingOrdersByPayee[msg.sender].length;
    }

    function getPaidOrderByIndex(uint index) constant returns (StandingOrder) {
        return standingOrdersByPayee[msg.sender][index];
    }
}


Fix unapprove

Fix unapprove

/*Most, basic default, standardised Token contract.
Allows the creation of a token with a finite issued amount to the creator.

Based on standardised APIs: https://github.com/ethereum/wiki/wiki/Standardized_Contract_APIs
.*/

import "Token";

contract Standard_Token is Token {

    function Standard_Token(uint256 _initial_amount) {
        balances[msg.sender] = _initial_amount;
        total_supply = _initial_amount;
    }

    function transfer(address _to, uint256 _value) returns (bool success) {
        if (balances[msg.sender] >= _value) {
            balances[msg.sender] -= _value;
            balances[_to] += _value;
            Transfer(msg.sender, _to, _value);
            return true;
        } else { return false; }
    }

    function transferFrom(address _from, address _to, uint256 _value) returns (bool success) {
        if (balances[_from] >= _value && allowed[_from][_to] >= _value) {
            balances[_from] -= _value;
            balances[_to] += _value;
            allowed[_from][_to] -= _value;
            Transfer(_from, _to, _value);
            return true;
        } else { return false; }
    }

    function balanceOf(address _owner) constant returns (uint256 balance) {
        return balances[_owner];
    }

    function unapprove(address _spender) returns (bool success) {
        allowed[msg.sender][_spender] = 0;
        Unapproved(msg.sender, _spender);
    }

    function approve(address _spender, uint256 _value) returns (bool success) {
        allowed[msg.sender][_spender] += _value;
        Approved(msg.sender, _spender, _value);
        return true;
    }

    function totalSupply() constant returns (uint256 _total) {
        return total_supply;
    }

    mapping (address => uint) balances;
    mapping (address => mapping (address => uint256)) allowed;
    uint256 total_supply;
}

/*Most, basic default, standardised Token contract.
Allows the creation of a token with a finite issued amount to the creator.

Based on standardised APIs: https://github.com/ethereum/wiki/wiki/Standardized_Contract_APIs
.*/

import "Token";

contract Standard_Token is Token {

    function Standard_Token(uint256 _initial_amount) {
        balances[msg.sender] = _initial_amount;
        total_supply = _initial_amount;
    }

    function transfer(address _to, uint256 _value) returns (bool success) {
        if (balances[msg.sender] >= _value) {
            balances[msg.sender] -= _value;
            balances[_to] += _value;
            Transfer(msg.sender, _to, _value);
            return true;
        } else { return false; }
    }

    function transferFrom(address _from, address _to, uint256 _value) returns (bool success) {
        if (balances[_from] >= _value && allowed[_from][_to] >= _value) {
            balances[_from] -= _value;
            balances[_to] += _value;
            allowed[_from][_to] -= _value;
            Transfer(_from, _to, _value);
            return true;
        } else { return false; }
    }

    function balanceOf(address _owner) constant returns (uint256 balance) {
        return balances[_owner];
    }

    function unapprove(address _spender) returns (bool success) {
        allowed[msg.sender][_spender] = 0;
        Unnaproved(msg.sender, _spender);
    }

    function approve(address _spender, uint256 _value) returns (bool success) {
        allowed[msg.sender][_spender] += _value;
        Approved(msg.sender, _spender, _value);
        return true;
    }

    function totalSupply() constant returns (uint256 _total) {
        return total_supply;
    }

    mapping (address => uint) balances;
    mapping (address => mapping (address => uint256)) allowed;
    uint256 total_supply;
}


add burn in refund fonction

add burn in refund fonction

pragma solidity ^0.4.8;
import "./SafeMath.sol";
import "./RLC.sol";
import "./PullPayment.sol";
import "./Pausable.sol";

/*
  Crowdsale Smart Contract for the iEx.ec project

  This smart contract collects ETH and BTC, and in return emits RLC tokens to the backers

  Thanks to BeyondTheVoid and TokenMarket who helped us shaping this code.

*/

contract Crowdsale is SafeMath, PullPayment, Pausable {

  struct Backer {
  	  uint weiReceived;	// Amount of ETH given
	  string btc_address;  //store the btc address for full tracability
	  uint satoshiReceived;	// Amount of BTC given
	  uint rlcToSend;   	// rlc to distribute when the min cap is reached
	  uint rlcSent;
	}

	RLC 	public rlc;         // RLC contract reference
	address public owner;       // Contract owner (iEx.ec team)
	address public multisigETH; // Multisig contract that will receive the ETH
	address public BTCproxy;	// addess of the BTC Proxy

	uint public RLCPerETH;      // Number of RLC per ETH
	uint public RLCPerSATOSHI;  // Number of RLC per SATOSHI
	uint public ETHReceived;    // Number of ETH received
	uint public BTCReceived;    // Number of BTC received
	uint public RLCSentToETH;   // Number of RLC sent to ETH contributors
	uint public RLCSentToBTC;   // Number of RLC sent to BTC contributors
	uint public startBlock;     // Crowdsale start block
	uint public endBlock;       // Crowdsale end block
	uint public minCap;         // Minimum number of RLC to sell
	uint public maxCap;         // Maximum number of RLC to sell
	bool public maxCapReached;  // Max cap has been reached
	uint public minInvestETH;   // Minimum amount to invest
	uint public minInvestBTC;   // Minimum amount to invest
	bool public crowdsaleClosed;// Is crowdsale still on going

  address public bounty;		// address at which the bounty RLC will be sent
  address public reserve; 	// address at which the contingency reserve will be sent
  address public team;		// address at which the team RLC will be sent

  uint public rlc_bounty;		// amount of bounties RLC
  uint public rlc_reserve;	// amount of the contingency reserve
  uint public rlc_team;		// amount of the team RLC
	mapping(address => Backer) public backers; //backersETH indexed by their ETH address

    // Auth modifier, if the msg.sender isn't the expected address, throw.
	modifier onlyBy(address a){
	    if (msg.sender != a) throw;
	    _;
	}

	modifier minCapNotReached() {
		if ((now<endBlock) || RLCSentToETH + RLCSentToBTC > minCap ) throw;
		_;
	}

	modifier respectTimeFrame() {
		if ((now < startBlock) || (now > endBlock )) throw;
		_;
	}

	modifier onlyPayloadSize(uint size) {
	    assert(msg.data.length == size + 4);
	    _;
	  }
	/*
	 *  /!\ FUNCTION FOR TEST ONLY - WILL BE REMOVE IN THE FINAL CONTRACT
	 */
	function closeCrowdsaleForRefund() {
		endBlock = now;
	}
	// same than finalise() without modifier
	function finalizeTEST() onlyBy(owner) {
		//moves the remaining ETH to the multisig address
		if (!multisigETH.send(this.balance)) throw;
		//moves RLC to the team, reserve and bounty address
	    if (!rlc.transfer(team,rlc_team)) throw;
	    if (!rlc.transfer(reserve,rlc_reserve)) throw;
	    if (!rlc.transfer(bounty,rlc_bounty)) throw;
	    uint RLCEmitted = rlc_reserve + rlc_bounty + rlc_team + RLCSentToBTC + RLCSentToETH;
	    if (RLCEmitted < rlc.totalSupply())
			rlc.burn(rlc.totalSupply() - RLCEmitted);
	    rlc.burn(rlc.totalSupply() - RLCEmitted);
		crowdsaleClosed = true;
	}
	/*
	 * /!\ END TEST FUNCTION
	 */

	/*
	 * Event
	 */
	event ReceivedETH(address addr, uint value);
	event ReceivedBTC(address addr, string from, uint value, string txid);
	event RefundBTC(string to, uint value);
	event Logs(address indexed from, uint amount, string value);

	/*
	*	Constructor
	*/
	function Crowdsale(address _token, address _btcproxy) {

	  //set the different variables
	  owner = msg.sender;
	  BTCproxy = _btcproxy; // to change
	  rlc = RLC(_token); 	// RLC contract address
	  multisigETH = 0x8cd6B3D8713df6aA35894c8beA200c27Ebe92550;
	  team = 0x1000000000000000000000000000000000000000;
	  reserve = 0x2000000000000000000000000000000000000000;
	  bounty = 0x3000000000000000000000000000000000000000;
	  RLCSentToETH = 0;
	  RLCSentToBTC = 0;
	  minInvestETH = 100 finney; // 0.1 ether
	  minInvestBTC = 1000000;     // approx 10 USD or 0.01000000 BTC
	  startBlock = 0 ;            	// should wait for the call of the function start
	  endBlock =  0;  				// should wait for the call of the function start
	  RLCPerETH = 200000000000;    // FIXME  will be update
	  RLCPerSATOSHI = 50000;         // 5000 RLC par BTC == 50,000 RLC per satoshi
	  minCap=12000000000000000;
	  maxCap=60000000000000000;
	  rlc_bounty=1700000000000000;		// max 6000000 RLC
	  rlc_reserve=1700000000000000;		// max 6000000 RLC
	  rlc_team=12000000000000000;
	}

	/*
	* The fallback function corresponds to a donation in ETH
	*/
	function() payable {
		if (now > endBlock) throw;
	  receiveETH(msg.sender);
	}

	function start() onlyBy(owner) {
	  startBlock = now ;
	  endBlock =  now + 30 days;
	}

	/*
	*	Receives a donation in ETH
	*/
	function receiveETH(address beneficiary) internal stopInEmergency  respectTimeFrame  {

	  //don't accept funding under a predefined treshold
	  if (msg.value < minInvestETH) throw;
      //compute the number of RLC to send
      uint rlcToSend = bonus(safeMul(msg.value,RLCPerETH)/(1 ether));

      // check if we are not reaching the maxCap by accepting this donation
      if (safeAdd(rlcToSend, safeAdd(RLCSentToETH, RLCSentToBTC)) > maxCap) throw;

	  //update the backer
	  Backer backer = backers[beneficiary];

	  if (!rlc.transfer(beneficiary, rlcToSend)) throw;     // Do the transfer right now

	  backer.rlcSent = safeAdd(backer.rlcSent, rlcToSend);
	  backer.weiReceived = safeAdd(backer.weiReceived, msg.value); // Update the total wei collcted during the crowdfunding
	  ETHReceived = safeAdd(ETHReceived, msg.value); // Update the total wei collcted during the crowdfunding
	  RLCSentToETH = safeAdd(RLCSentToETH, rlcToSend);

	  emitRLC(rlcToSend);
	  // send the corresponding contribution event
	  ReceivedETH(beneficiary,ETHReceived);
	}

	/*
	* receives a donation in BTC
	*/
	function receiveBTC(address beneficiary, string btc_address, uint value, string txid) stopInEmergency respectTimeFrame onlyBy(BTCproxy) returns (bool res){

	  if (value < minInvestBTC) throw;  // the verif is made by btcproxy

    //compute the number of RLC to send
    uint rlcToSend = bonus(safeMul(value,RLCPerSATOSHI));
	  if (safeAdd(rlcToSend, safeAdd(RLCSentToETH, RLCSentToBTC)) > maxCap) {
	  	RefundBTC(btc_address , value);
	  	return false;
	  }

	  //update the backer
	  Backer backer = backers[beneficiary];

	  if (!rlc.transfer(beneficiary, rlcToSend)) throw;     // Do the transfer right now

	  backer.rlcSent = safeAdd(backer.rlcSent , rlcToSend);
	  backer.btc_address = btc_address;
	  backer.satoshiReceived = safeAdd(backer.satoshiReceived, value);
	  BTCReceived =  safeAdd(BTCReceived, value);// Update the total satoshi collected during the crowdfunding
	  RLCSentToBTC = safeAdd(RLCSentToBTC, rlcToSend);
	  emitRLC(rlcToSend);
	  ReceivedBTC(beneficiary, btc_address, BTCReceived, txid);
	  return true;
	}

	/*
	  Compute the varaible part
	*/
	function emitRLC(uint amount) internal {
		rlc_bounty = safeAdd(rlc_bounty, amount/10);
		rlc_team = safeAdd(rlc_team, amount/20);
		rlc_reserve = safeAdd(rlc_reserve, amount/10);
		Logs(msg.sender ,amount, "emitRLC");
	}

	/*
	  Compute the RLC bonus according to the investment period
	*/
  function bonus(uint amount) internal constant returns (uint) {
    if (now < safeAdd(startBlock, 10 days)) return (safeAdd(amount, amount/5));   // bonus 20%
    if (now < safeAdd(startBlock, 20 days)) return (safeAdd(amount, amount/10));  // bonus 10%
    return amount;
  }

	/*
	 * When mincap is not reach backer can call the approveAndCall function of the RLC token contract
	 * with this crowdsale contract on parameter with all the RLC they get in order to be refund
	 */
  function receiveApproval(address _from, uint256 _value, address _token, bytes _extraData, bytes _extraData2) minCapNotReached public {
      if (msg.sender != address(rlc)) throw;
      if (_extraData.length != 0) throw;  // no extradata needed
      if (_extraData2.length != 0) throw;  // no extradata needed
      if (_value != backers[_from].rlcSent) throw; // compare value from backer balance
      if (!rlc.transferFrom(_from, address(this), _value)) throw ; // get the token back to the crowdsale contract
      if (!rlc.burn(_value)) throw ;	// token are burnt
		  uint ETHToSend = backers[_from].weiReceived;
		  backers[_from].weiReceived=0;
		  uint BTCToSend = backers[_from].satoshiReceived;
		  backers[_from].satoshiReceived = 0;
		  if (ETHToSend > 0) {
		  	asyncSend(_from,ETHToSend);
		  }
		  if (BTCToSend > 0)
		  	RefundBTC(backers[_from].btc_address ,BTCToSend); // event message to manually refund BTC
  }

  /*
   * Update the rate RLC per ETH, computed externally by using the BTCETH index on kraken every 10min
   */
  function setRLCPerETH(uint rate) onlyBy(BTCproxy) {
    RLCPerETH=rate;
  }

	/*
	* Finalize the crowdsale, should be called after the refund period
	*/
	function finalize() onlyBy(owner) {
		// check
		if (RLCSentToETH + RLCSentToBTC < maxCap - 50000000000 && now < endBlock) throw; // cannot finalise before 30 day until maxcap is reached
		if (RLCSentToETH + RLCSentToBTC < minCap && now < endBlock + 15 days) throw ;  // if mincap is not reached donator have 15days to get refund
		//moves the remaining ETH to the multisig address
		if (!multisigETH.send(this.balance)) throw;
		//moves RLC to the team, reserve and bounty address
		if (rlc_reserve > 6000000000000000){
			if(!rlc.transfer(reserve,6000000000000000)) throw; // max cap 6000000RLC
			rlc_reserve = 6000000000000000;
		} else {
			if(!rlc.transfer(reserve,rlc_reserve)) throw;
		}
		if (rlc_bounty > 6000000000000000){
			if(!rlc.transfer(bounty,6000000000000000)) throw; // max cap 6000000RLC
			rlc_bounty = 6000000000000000;
		} else {
			if(!rlc.transfer(bounty,rlc_bounty)) throw;
		}
    if (!rlc.transfer(team,rlc_team)) throw;
    uint RLCEmitted = rlc_reserve + rlc_bounty + rlc_team + RLCSentToBTC + RLCSentToETH;
    if (RLCEmitted < rlc.totalSupply())					// necessary check for reserve and bounty maxcap
		  rlc.burn(rlc.totalSupply() - RLCEmitted);
    rlc.unlock();
		crowdsaleClosed = true;
	}
}

pragma solidity ^0.4.8;
import "./SafeMath.sol";
import "./RLC.sol";
import "./PullPayment.sol";
import "./Pausable.sol";

/*
  Crowdsale Smart Contract for the iEx.ec project

  This smart contract collects ETH and BTC, and in return emits RLC tokens to the backers

  Thanks to BeyondTheVoid and TokenMarket who helped us shaping this code.

*/

contract Crowdsale is SafeMath, PullPayment, Pausable {

  struct Backer {
  	  uint weiReceived;	// Amount of ETH given
	  string btc_address;  //store the btc address for full tracability
	  uint satoshiReceived;	// Amount of BTC given
	  uint rlcToSend;   	// rlc to distribute when the min cap is reached
	  uint rlcSent;
	}

	RLC 	public rlc;         // RLC contract reference
	address public owner;       // Contract owner (iEx.ec team)
	address public multisigETH; // Multisig contract that will receive the ETH
	address public BTCproxy;	// addess of the BTC Proxy

	uint public RLCPerETH;      // Number of RLC per ETH
	uint public RLCPerSATOSHI;  // Number of RLC per SATOSHI
	uint public ETHReceived;    // Number of ETH received
	uint public BTCReceived;    // Number of BTC received
	uint public RLCSentToETH;   // Number of RLC sent to ETH contributors
	uint public RLCSentToBTC;   // Number of RLC sent to BTC contributors
	uint public startBlock;     // Crowdsale start block
	uint public endBlock;       // Crowdsale end block
	uint public minCap;         // Minimum number of RLC to sell
	uint public maxCap;         // Maximum number of RLC to sell
	bool public maxCapReached;  // Max cap has been reached
	uint public minInvestETH;   // Minimum amount to invest
	uint public minInvestBTC;   // Minimum amount to invest
	bool public crowdsaleClosed;// Is crowdsale still on going

  address public bounty;		// address at which the bounty RLC will be sent
  address public reserve; 	// address at which the contingency reserve will be sent
  address public team;		// address at which the team RLC will be sent

  uint public rlc_bounty;		// amount of bounties RLC
  uint public rlc_reserve;	// amount of the contingency reserve
  uint public rlc_team;		// amount of the team RLC
	mapping(address => Backer) public backers; //backersETH indexed by their ETH address

    // Auth modifier, if the msg.sender isn't the expected address, throw.
	modifier onlyBy(address a){
	    if (msg.sender != a) throw;
	    _;
	}

	modifier minCapNotReached() {
		if ((now<endBlock) || RLCSentToETH + RLCSentToBTC > minCap ) throw;
		_;
	}

	modifier respectTimeFrame() {
		if ((now < startBlock) || (now > endBlock )) throw;
		_;
	}

	modifier onlyPayloadSize(uint size) {
	    assert(msg.data.length == size + 4);
	    _;
	  }
	/*
	 *  /!\ FUNCTION FOR TEST ONLY - WILL BE REMOVE IN THE FINAL CONTRACT
	 */
	function closeCrowdsaleForRefund() {
		endBlock = now;
	}
	// same than finalise() without modifier
	function finalizeTEST() onlyBy(owner) {
		//moves the remaining ETH to the multisig address
		if (!multisigETH.send(this.balance)) throw;
		//moves RLC to the team, reserve and bounty address
	    if (!rlc.transfer(team,rlc_team)) throw;
	    if (!rlc.transfer(reserve,rlc_reserve)) throw;
	    if (!rlc.transfer(bounty,rlc_bounty)) throw;
	    uint RLCEmitted = rlc_reserve + rlc_bounty + rlc_team + RLCSentToBTC + RLCSentToETH;
	    if (RLCEmitted < rlc.totalSupply())
			rlc.burn(rlc.totalSupply() - RLCEmitted);
	    rlc.burn(rlc.totalSupply() - RLCEmitted);
		crowdsaleClosed = true;
	}
	/*
	 * /!\ END TEST FUNCTION
	 */

	/*
	 * Event
	 */
	event ReceivedETH(address addr, uint value);
	event ReceivedBTC(address addr, string from, uint value, string txid);
	event RefundBTC(string to, uint value);
	event Logs(address indexed from, uint amount, string value);

	/*
	*	Constructor
	*/
	function Crowdsale(address _token, address _btcproxy) {

	  //set the different variables
	  owner = msg.sender;
	  BTCproxy = _btcproxy; // to change
	  rlc = RLC(_token); 	// RLC contract address
	  multisigETH = 0x8cd6B3D8713df6aA35894c8beA200c27Ebe92550;
	  team = 0x1000000000000000000000000000000000000000;
	  reserve = 0x2000000000000000000000000000000000000000;
	  bounty = 0x3000000000000000000000000000000000000000;
	  RLCSentToETH = 0;
	  RLCSentToBTC = 0;
	  minInvestETH = 100 finney; // 0.1 ether
	  minInvestBTC = 1000000;     // approx 10 USD or 0.01000000 BTC
	  startBlock = 0 ;            	// should wait for the call of the function start
	  endBlock =  0;  				// should wait for the call of the function start
	  RLCPerETH = 200000000000;    // FIXME  will be update
	  RLCPerSATOSHI = 50000;         // 5000 RLC par BTC == 50,000 RLC per satoshi
	  minCap=12000000000000000;
	  maxCap=60000000000000000;
	  rlc_bounty=1700000000000000;		// max 6000000 RLC
	  rlc_reserve=1700000000000000;		// max 6000000 RLC
	  rlc_team=12000000000000000;
	}

	/*
	* The fallback function corresponds to a donation in ETH
	*/
	function() payable {
		if (now > endBlock) throw;
	  receiveETH(msg.sender);
	}

	function start() onlyBy(owner) {
	  startBlock = now ;
	  endBlock =  now + 30 days;
	}

	/*
	*	Receives a donation in ETH
	*/
	function receiveETH(address beneficiary) internal stopInEmergency  respectTimeFrame  {

	  //don't accept funding under a predefined treshold
	  if (msg.value < minInvestETH) throw;
      //compute the number of RLC to send
      uint rlcToSend = bonus(safeMul(msg.value,RLCPerETH)/(1 ether));

      // check if we are not reaching the maxCap by accepting this donation
      if (safeAdd(rlcToSend, safeAdd(RLCSentToETH, RLCSentToBTC)) > maxCap) throw;

	  //update the backer
	  Backer backer = backers[beneficiary];

	  if (!rlc.transfer(beneficiary, rlcToSend)) throw;     // Do the transfer right now

	  backer.rlcSent = safeAdd(backer.rlcSent, rlcToSend);
	  backer.weiReceived = safeAdd(backer.weiReceived, msg.value); // Update the total wei collcted during the crowdfunding
	  ETHReceived = safeAdd(ETHReceived, msg.value); // Update the total wei collcted during the crowdfunding
	  RLCSentToETH = safeAdd(RLCSentToETH, rlcToSend);

	  emitRLC(rlcToSend);
	  // send the corresponding contribution event
	  ReceivedETH(beneficiary,ETHReceived);
	}

	/*
	* receives a donation in BTC
	*/
	function receiveBTC(address beneficiary, string btc_address, uint value, string txid) stopInEmergency respectTimeFrame onlyBy(BTCproxy) returns (bool res){

	  if (value < minInvestBTC) throw;  // the verif is made by btcproxy

    //compute the number of RLC to send
    uint rlcToSend = bonus(safeMul(value,RLCPerSATOSHI));
	  if (safeAdd(rlcToSend, safeAdd(RLCSentToETH, RLCSentToBTC)) > maxCap) {
	  	RefundBTC(btc_address , value);
	  	return false;
	  }

	  //update the backer
	  Backer backer = backers[beneficiary];

	  if (!rlc.transfer(beneficiary, rlcToSend)) throw;     // Do the transfer right now

	  backer.rlcSent = safeAdd(backer.rlcSent , rlcToSend);
	  backer.btc_address = btc_address;
	  backer.satoshiReceived = safeAdd(backer.satoshiReceived, value);
	  BTCReceived =  safeAdd(BTCReceived, value);// Update the total satoshi collected during the crowdfunding
	  RLCSentToBTC = safeAdd(RLCSentToBTC, rlcToSend);
	  emitRLC(rlcToSend);
	  ReceivedBTC(beneficiary, btc_address, BTCReceived, txid);
	  return true;
	}

	/*
	  Compute the varaible part
	*/
	function emitRLC(uint amount) internal {
		rlc_bounty = safeAdd(rlc_bounty, amount/10);
		rlc_team = safeAdd(rlc_team, amount/20);
		rlc_reserve = safeAdd(rlc_reserve, amount/10);
		Logs(msg.sender ,amount, "emitRLC");
	}

	/*
	  Compute the RLC bonus according to the investment period
	*/
  function bonus(uint amount) internal constant returns (uint) {
    if (now < safeAdd(startBlock, 10 days)) return (safeAdd(amount, amount/5));   // bonus 20%
    if (now < safeAdd(startBlock, 20 days)) return (safeAdd(amount, amount/10));  // bonus 10%
    return amount;
  }

	/*
	 * When mincap is not reach backer can call the approveAndCall function of the RLC token contract
	 * with this crowdsale contract on parameter with all the RLC they get in order to be refund
	 */
  function receiveApproval(address _from, uint256 _value, address _token, bytes _extraData, bytes _extraData2) minCapNotReached public {
      if (msg.sender != address(rlc)) throw;
      if (_extraData.length != 0) throw;  // no extradata needed
      if (_extraData2.length != 0) throw;  // no extradata needed
      if (_value != backers[_from].rlcSent) throw; // compare value from backer balance
      if (!rlc.transferFrom(_from, address(this), _value)) throw ; // get the token back to the crowdsale contract
		  uint ETHToSend = backers[_from].weiReceived;
		  backers[_from].weiReceived=0;
		  uint BTCToSend = backers[_from].satoshiReceived;
		  backers[_from].satoshiReceived = 0;
		  if (ETHToSend > 0) {
		  	asyncSend(_from,ETHToSend);
		  }
		  if (BTCToSend > 0)
		  	RefundBTC(backers[_from].btc_address ,BTCToSend); // event message to manually refund BTC
  }

  /*
   * Update the rate RLC per ETH, computed externally by using the BTCETH index on kraken every 10min
   */
  function setRLCPerETH(uint rate) onlyBy(BTCproxy) {
    RLCPerETH=rate;
  }

	/*
	* Finalize the crowdsale, should be called after the refund period
	*/
	function finalize() onlyBy(owner) {
		// check
		if (RLCSentToETH + RLCSentToBTC < maxCap - 50000000000 && now < endBlock) throw; // cannot finalise before 30 day until maxcap is reached
		if (RLCSentToETH + RLCSentToBTC < minCap && now < endBlock + 15 days) throw ;  // if mincap is not reached donator have 15days to get refund
		//moves the remaining ETH to the multisig address
		if (!multisigETH.send(this.balance)) throw;
		//moves RLC to the team, reserve and bounty address
		if (rlc_reserve > 6000000000000000){
			if(!rlc.transfer(reserve,6000000000000000)) throw; // max cap 6000000RLC
			rlc_reserve = 6000000000000000;
		} else {
			if(!rlc.transfer(reserve,rlc_reserve)) throw;
		}
		if (rlc_bounty > 6000000000000000){
			if(!rlc.transfer(bounty,6000000000000000)) throw; // max cap 6000000RLC
			rlc_bounty = 6000000000000000;
		} else {
			if(!rlc.transfer(bounty,rlc_bounty)) throw;
		}
    if (!rlc.transfer(team,rlc_team)) throw;
    uint RLCEmitted = rlc_reserve + rlc_bounty + rlc_team + RLCSentToBTC + RLCSentToETH;
    if (RLCEmitted < rlc.totalSupply())					// necessary check for reserve and bounty maxcap
		  rlc.burn(rlc.totalSupply() - RLCEmitted);
    rlc.unlock();
		crowdsaleClosed = true;
	}
}


add create for paswordchallange

add create for paswordchallange

contract Factory {

    event created(address addr);

    address[] parties;

    function getParties() constant returns (address[]){
        return parties;
    }

    function createParty() returns (address addr){
        var party = new Party();
        parties.push(party);
        created(party);
        return party;
    }

    function createPasswordChallenge(bytes20 response, bytes32 salt) returns (address addr){
        var challenge = new PasswordChallenge(response, salt);
        created(challenge);
        return challenge;
    }

}

contract Factory {

    event created(address addr);

    address[] parties;

    function createParty()  returns (address addr){
        var party = new Party();
        parties.push(party);
        created(party);
        return party;
    }

}


Added refund formula

Added refund formula

pragma solidity ^0.4.10;
import "./base/StandardToken.sol";
import "./lib/Arithmetic.sol";

/// @title The main Rocket Pool Token (RPL) crowdsale contract
/// @author David Rugendyke

 // Tokens allocated proportionately to each sender according to amount of ETH contributed as a fraction of the total amount of ETH contributed by all senders.
 // credit for original idea and base contract goes to hiddentao - https://github.com/hiddentao/ethereum-token-sales

contract RocketPoolToken is StandardToken {

    /**** Properties ***********/

    string public name = 'Rocket Pool Token';
    string public symbol = 'RPL';
    uint256 public constant decimals = 18;
    string public version = "1.0";
    uint256 public totalSupply = 50**6;         // 50 Million
    uint256 private calcBase = 1**decimals;     // Use this as our base unit to remove the decimal place by multiplying and dividing by it since solidity doesn't support reals yet

    // Important Addresses
    address public depositAddress;        // Deposit address for ETH for ICO owner

    // Crowdsale Params
    bool public isFinalized;              // True when ICO finalized and successful
    uint256 public targetEth;             // Target ETH to raise
    uint256 public maxEthAllocation;      // Max ETH allowed per account
    uint256 public fundingStartBlock;     // When to start allowing funding
    uint256 public fundingEndBlock;       // When to stop allowing funding
    uint256 public txGasLimit;            // The max allowed gas for a contribution

    // Calculated values
    mapping (address => uint256) contributions;          // ETH contributed per address
    uint256 contributedTotal;                            // Total ETH contributed

    /*** Events ****************/

    event CreateRPLToken(string _name);
    event Contribute(address _sender, uint256 _value);
    event FinaliseSale(address _sender);
    event RefundContribution(address _sender, uint256 _value);
    event ClaimTokens(address _sender, uint256 _value);

    /**** Methods ***********/

    // Constructor
    /// @dev RPL Token Init
    /// @param _minEth The target ether amount required for the crowdsale
    /// @param _maxEthAllocation The max ether allowed per account
    /// @param _depositAddress The address that will receive the funds when the crowdsale is finalised
    /// @param _fundingStartBlock The start block for the crowdsale
    /// @param _fundingEndBlock The end block for the crowdsale
    function RocketPoolToken(uint256 _minEth, uint256 _maxEthAllocation, address _depositAddress, uint256 _fundingStartBlock, uint256 _fundingEndBlock, uint256 _txGasLimit) {
        // Initialise params
        isFinalized = false;
        targetEth = _minEth;
        maxEthAllocation = _maxEthAllocation;
        depositAddress = _depositAddress;
        fundingStartBlock = _fundingStartBlock;
        fundingEndBlock = _fundingEndBlock;
        txGasLimit = _txGasLimit;
        // Fire event
        CreateRPLToken(name);
    }

    /// @dev Accepts ETH from a contributor
    function() payable external {
        // Did they send anything?
        assert(msg.value > 0);
        // Check if we're ok to receive contributions, have we started?
        assert(block.number > fundingStartBlock);
        // Already ended?
        assert(block.number < fundingEndBlock);
        // It's within the tx gas range
        assert(tx.gasprice <= txGasLimit);
        // Max sure the user has not exceeded their ether allocation
        assert((contributions[msg.sender] + msg.value) <= maxEthAllocation);
        // Add to contributions
        contributions[msg.sender] += msg.value;
        contributedTotal += msg.value;
        // Fire event
        Contribute(msg.sender, msg.value);
    }

    /// @dev Finalizes the funding and sends the ETH to deposit address
    function finaliseFunding() external {
        // Finalise the crowdsale funds
        assert(isFinalized);
        // Wrong sender?
        assert(msg.sender == depositAddress);
        // Not yet finished?
        assert(block.number > fundingEndBlock);
        // Not enough raised?
        assert(contributedTotal >= targetEth);
        // We're done now
        isFinalized = true;
        // Send to deposit address - revert all state changes if it doesn't make it
        if (!depositAddress.send(targetEth)) throw;
        // Fire event
        FinaliseSale(msg.sender);
    }

    /// @dev Allows contributors to claim their tokens and/or a refund. If funding failed then they get back all their Ether, otherwise they get back any excess Ether
    function claimTokensAndRefund() external {
        // Must have previously contributed
        assert(contributions[msg.sender] > 0);
        // Crowdfund completed
        assert(block.number > fundingEndBlock);
        // If not enough funding
        if (contributedTotal < targetEth) {
            // Refund my full contribution
            if (!msg.sender.send(contributions[msg.sender])) throw;
            // Fire event
            RefundContribution(msg.sender, contributions[msg.sender]);
        } else {
            // Calculate what percent of the ether raised came from me
            uint256 percEtherContributed = Arithmetic.overflowResistantFraction(contributions[msg.sender], calcBase, contributedTotal);
            // Calculate how many tokens I get
            balances[msg.sender] = Arithmetic.overflowResistantFraction(percEtherContributed, totalSupply, calcBase);
            // Calculate the refund this user will receive
            if (!msg.sender.send(Arithmetic.overflowResistantFraction(percEtherContributed, (contributedTotal - targetEth), calcBase)))) throw;
            // Fire event
            ClaimTokens(msg.sender, balances[msg.sender]);
      }
      // All done
      contributions[msg.sender] = 0;
    }
}

pragma solidity ^0.4.10;
import "./base/StandardToken.sol";
import "./lib/Arithmetic.sol";

/// @title The main Rocket Pool Token (RPL) crowdsale contract
/// @author David Rugendyke

 // Tokens allocated proportionately to each sender according to amount of ETH contributed as a fraction of the total amount of ETH contributed by all senders.
 // credit for original idea and base contract goes to hiddentao - https://github.com/hiddentao/ethereum-token-sales

contract RocketPoolToken is StandardToken {

    /**** Properties ***********/

    string public name = 'Rocket Pool Token';
    string public symbol = 'RPL';
    uint256 public constant decimals = 18;
    string public version = "1.0";
    uint256 public totalSupply = 50**6;     // 50 Million
    uint256 private calcBase = 1**decimals; // Use this as our base unit to remove the decimal place by multiplying and dividing by it since solidity doesn't support reals yet

    // Important Addresses
    address public depositAddress;        // Deposit address for ETH for ICO owner

    // Crowdsale Params
    bool public isFinalized;              // True when ICO finalized and successful
    uint256 public targetEth;             // Target ETH to raise
    uint256 public maxEthPerTx;           // Max ETH allowed per contribution
    uint256 public fundingStartBlock;     // When to start allowing funding
    uint256 public fundingEndBlock;       // When to stop allowing funding
    uint256 public txGasLimit;            // The max allowed gas for a contribution

    // Calculated values
    mapping (address => uint256) contributions;          // ETH contributed per address
    uint256 contributedTotal;                            // Total ETH contributed

    /*** Events ****************/

    event CreateFairToken(string _name);
    event Contribute(address _sender, uint256 _value);
    event FinalizeSale(address _sender);
    event RefundContribution(address _sender, uint256 _value);
    event ClaimTokens(address _sender, uint256 _value);

    /**** Methods ***********/

    // Constructor
    /// @dev RPL Token Init
    /// @param _minEth The target ether amount required for the crowdsale
    /// @param _depositAddress The address that will receive the funds when the crowdsale is finalised
    /// @param _fundingStartBlock The start block for the crowdsale
    /// @param _fundingEndBlock The end block for the crowdsale
    function RocketPoolToken(uint256 _minEth, uint256 _maxEthPerTx, address _depositAddress, uint256 _fundingStartBlock, uint256 _fundingEndBlock, uint256 _txGasLimit) {
        // Initialise params
        isFinalized = false;
        targetEth = _minEth;
        maxEthPerTx = _maxEthPerTx;
        depositAddress = _depositAddress;
        fundingStartBlock = _fundingStartBlock;
        fundingEndBlock = _fundingEndBlock;
        txGasLimit = _txGasLimit;
        // Fire event
        CreateFairToken(name);
    }

    /// @dev Accepts ETH from a contributor
    function() payable external {
        // Check if we're ok to receive contributions, have we started?
        assert(block.number > fundingStartBlock);
        // Already ended?
        assert(block.number < fundingEndBlock);
        // There is actual eth attached to msg and its within the limit per tx
        assert(msg.value > 0 && msg.value <= maxEthPerTx);
        // It's within the tx gas range
        assert(tx.gasprice <= txGasLimit);
        // Add to contributions
        contributions[msg.sender] += msg.value;
        contributedTotal += msg.value;
        // Fire event
        Contribute(msg.sender, msg.value);
    }

    /// @dev Finalizes the funding and sends the ETH to deposit address
    function finaliseFunding() external {
        // Finalise the crowdsale funds
        assert(isFinalized) ;
        // Wrong sender?
        assert(msg.sender == depositAddress);
        // Not yet finished?
        assert(block.number > fundingEndBlock);
        // Not enough raised?
        assert(contributedTotal >= targetEth);
        // We're done now
        isFinalized = true;
        // Send to deposit address - revert all state changes if it doesn't make it
        if (!depositAddress.send(targetEth)) throw;
        // Fire event
        FinalizeSale(msg.sender);
    }

    /// @dev Allows contributors to claim their tokens and/or a refund. If funding failed then they get back all their Ether, otherwise they get back any excess Ether
    function claimTokensAndRefund() external {
        // Must have previously contributed
        assert(contributions[msg.sender] > 0);
        // Crowdfund completed
        assert(block.number > fundingEndBlock);
        // If not enough funding
        if (contributedTotal < targetEth) {
            // Refund my full contribution
            if (!msg.sender.send(contributions[msg.sender])) throw;
            // Fire event
            RefundContribution(msg.sender, contributions[msg.sender]);
        } else {
            // Calculate what percent of the ether raised came from me
            uint256 percEtherContributed = Arithmetic.overflowResistantFraction(contributions[msg.sender], calcBase, contributedTotal);
            // Calculate how many tokens I get
            balances[msg.sender] = Arithmetic.overflowResistantFraction(percEtherContributed, totalSupply, calcBase);
            // Refund excess ETH
            // if (!msg.sender.send(contributions[msg.sender] - (safeMult(targetEth, contributions[msg.sender]) / contributedTotal))) throw;
            // Fire event
            ClaimTokens(msg.sender, balances[msg.sender]);
      }
      // All done
      contributions[msg.sender] = 0;
    }
}


add function addAssessorToPool

add function addAssessorToPool

import "math.sol";
import "userRegistry.sol";
import "concept.sol";
import "user.sol";
import "conceptRegistry.sol";

contract Assessment
{
  address assessee; //The address of the user being assessed
  address[] assessors;
  address[] finalAssessors; //The assessors who actually give an assessment
  mapping (address => uint) assessorState;
  address[] assessorPool; //The addresses of the user's that the assessors are randomly selected from
  address concept;
  address userRegistry;
  address conceptRegistry;
  address math = 0x90B66E80448eb60938FAed4A738dE0D5b630B2Fd;
  uint public startTime;
  uint public size;
  uint cost;
  uint poolSizeRemaining;
  mapping(address => string[]) public data; //IFFS hashes of data that can be passed between the assessors and the assessee for the assessment to occur
  mapping(address => bytes32) commits;
  mapping(address => uint) stake;
  uint done = 0;
  mapping(address => int8) scores; //could save gas by making this an int8
  mapping(int => bool) inRewardCluster;
  int finalScore;
  event DataSet(address _dataSetter, uint _index);

  /*
  @type: modifier
  @name: onlyThis
  @purpose: to only allow the this contract to call a function to which this modifier is applied
  */
  modifier onlyThis()
  {
    if(msg.sender != address(this)) //Checks if msg.sender is this contract
    {
      throw; //Throws out the function call if it isn't
    }
    _;
  }

  /*
  @type: modifier
  @name: onlyAssessorAssessee
  @purpose: to only allow the assessors and assessee to call a function to which this modifier is applied
  */
  modifier onlyAssessorAssessee()
  {
    if(msg.sender != assessee && assessorState[msg.sender] == 0) //Checks if msg.sender has the same address as either the assessee or an assessor
    {
      throw; //Throws the function call if not
    }
    _;
  }

  /*
  @type: modifier
  @name: onlyConceptAssessment
  @purpose: to only allow the this contract or the Concept contract that spawned it to call a function to which this modifier is applied
  */
  modifier onlyConceptAssessment()
  {
    if(msg.sender != address(this) && msg.sender != concept) //Checks if msg.sender has the same address as this contract or the Concept that spawned it
    {
      throw; //Throws the function call if not
    }
    _;
  }

  modifier onlyConcept()
  {
    if(msg.sender != concept)
    {
      throw;
    }
    _;
  }

  function Assessment(address assesseeAddress, address userRegistryAddress, address conceptRegistryAddress, uint assessmentSize, uint assessmentCost)
  {
    assessee = assesseeAddress;
    concept = msg.sender;
    userRegistry = userRegistryAddress;
    conceptRegistry = conceptRegistryAddress;
    startTime = block.timestamp;
    size = assessmentSize;
    cost = assessmentCost;
    poolSizeRemaining = size*20;
    User(assessee).notification(concept, 0); //Assessment made
  }

  function cancelAssessment() onlyConceptAssessment()
  {
    Concept(concept).setBalance(assessee, UserRegistry(userRegistry).getBalance(assessee) + cost*size);
    User(assessee).notification(concept, 3); //Assessment Cancled and you have been refunded
    for(uint i = 0; i < assessors.length; i++)
    {
      Concept(concept).setBalance(assessors[i], UserRegistry(userRegistry).getBalance(assessors[i]) + cost);
      User(assessors[i]).notification(concept, 3); //Assessment Cancled and you have been refunded
    }
    suicide(conceptRegistry);
  }

  function addAssessorToPool(address assessor) onlyConcept()
  {
    User(assessor).notification(concept, 1); //Called As A Potential Assessor
    assessorState[assessor] = 1;
  }

  /*
  @type: function
  @purpose: To recursively set the pool to draw assessors from in the assessment
  @param: address conceptAddress = the concept that assessors are currently being drawn from
  @param: address assessment = the address of the assessment that assessors are being drawn for
  @param: uint seed = the seed number for random number generation
  @param: uint size = the desired size of the assessment
  @returns: nothing
  */
  function setAssessorPool(address conceptAddress, uint seed) onlyConceptAssessment()
  {
    if(Concept(ConceptRegistry(conceptRegistry).mewAddress()).getOwnerLength() < poolSizeRemaining) //Checks if the requested pool size is greater than the number of users in the system
    {
      for(uint i = 0; i < Concept(ConceptRegistry(conceptRegistry).mewAddress()).getOwnerLength(); i++) //If so, all users in the system are added to the pool
      {
        assessorPool.push(Concept(ConceptRegistry(conceptRegistry).mewAddress()).owners(i));
        User(Concept(ConceptRegistry(conceptRegistry).mewAddress()).owners(i)).notification(concept, 1); //Called As A Potential Assessor
        assessorState[Concept(ConceptRegistry(conceptRegistry).mewAddress()).owners(i)] = 1;
      }
    }
    else
    {
    Concept(concept).getAssessors(poolSizeRemaining, seed, address(this));
  }
  }

  function confirmAssessor()
  {
    if(block.number - startTime <= 15 && assessorState[msg.sender] == 1 && assessors.length < size && UserRegistry(userRegistry).getBalance(msg.sender) >= cost)
    {
      assessors.push(msg.sender);
      assessorState[msg.sender] = 2;
      stake[msg.sender] = cost;
      Concept(concept).setBalance(msg.sender,UserRegistry(userRegistry).getBalance(msg.sender) - cost);
      User(msg.sender).notification(concept, 2); //Confirmed for assessing, stake has been taken
    }
    if(assessors.length == size)
    {
      notifyStart();
    }
    else if(block.number - startTime > 15 && assessors.length < size)
    {
      cancelAssessment();
    }
  }

  function notifyStart() onlyThis()
  {
    for(uint i = 0; i < assessors.length; i++)
    {
      User(assessors[i]).notification(concept, 4); //Assessment Has Started
    }
    User(assessee).notification(concept, 4); //Assessment Has Started
  }

  function setData(string newData) onlyAssessorAssessee()
  {
    data[msg.sender].push(newData);
    DataSet(msg.sender, data[msg.sender].length - 1);
  }

  function commit(bytes32 hash)
  {
    if(assessorState[msg.sender] == 2)
    {
      commits[msg.sender] = hash;
      assessorState[msg.sender] == 3;
      done++;
      if(done <= size/2)
      {
        startTime = block.number;
      }
    }
    if(done > size/2)
    {
      for(uint i = 0; i < assessors.length; i++)
      {
        if(assessorState[assessors[i]] == 2)
        {
          //burn da stakes
        }
        if(stake[assessors[i]] == 0)
        {
          assessorState[assessors[i]] = 4;
          done++;
        }
      }
    }
    if(done == size)
    {
      for(uint j = 0; j < assessors.length; j++)
      {
        if(assessorState[assessors[j]] == 3)
        {
          User(assessors[j]).notification(concept, 5); //Send in Score
        }
      }
      startTime = block.number;
      done = 0;
    }
  }

  function reveal(int8 score, bytes16 salt, address assessor)
  {
    if(block.number - startTime <= 10)
    {
      bytes32 hash = sha3(score,salt);
      if(commits[assessor] == hash)
      {
        if(msg.sender == assessor)
        {
          scores[msg.sender] = score;
          assessorState[assessor] = 5;
          done++;
        }
        else
        {
          Concept(concept).setBalance(msg.sender,UserRegistry(userRegistry).getBalance(msg.sender) + stake[assessor]);
          stake[assessor] = 0;
          assessorState[assessor] = 4;
        }
      }
      else if(msg.sender == assessor)
      {
        stake[assessor] = 0;
        assessorState[assessor] = 4;
        done++;
      }
    }
    else
    {
      for(uint i = 0; i < assessors.length; i++)
      {
        if(assessorState[assessors[i]] == 3)
        {
          stake[assessors[i]] = 0;
          assessorState[assessors[i]] = 4;
          done++;
        }
      }
    }
    if(done == size)
    {
      calculateResult();
    }
  }

  function calculateResult() onlyThis()
  {
    mapping(uint => int[]) clusters;
    for(uint j = 0; j < size; j++)
    {
      if(assessorState[assessors[i]] == 5)
      {
        finalAssessors.push(assessors[i]);
      }
    }
    int[] memory score = new int[] (finalAssessors.length);
    uint largestClusterIndex = 0;
    int averageScore;
    for(uint i = 0; i < finalAssessors.length; i++)
    {
      score[i] = scores[finalAssessors[i]];
    }
    int meanAbsoluteDeviation = Math(math).calculateMAD(score,int(finalAssessors.length));
    for(uint l = 0; l < score.length; l++)
    {
      for(uint m = 0; m < score.length; m++)
      {
        if(score[l] - score[m] <= meanAbsoluteDeviation)
        {
          clusters[l].push(score[m]);
        }
      }
      if(clusters[l].length > clusters[largestClusterIndex].length)
      {
        largestClusterIndex = l;
      }
    }
    for(uint o = 0; o < clusters[largestClusterIndex].length; o++)
    {
      averageScore += clusters[largestClusterIndex][o];
      inRewardCluster[clusters[largestClusterIndex][o]] = true;
    }
    averageScore /= int(clusters[largestClusterIndex].length);
    finalScore = averageScore;
    payout(clusters[largestClusterIndex].length);
  }

  function payout(uint largestSize) onlyThis()
  {
    for(uint i = 0; i < size; i++)
    {
      int score = scores[assessors[i]];
      int scoreDistance = ((score - finalScore)*100)/finalScore;
      if(scoreDistance < 0)
      {
        scoreDistance *= -1;
      }
      uint payoutValue = 1; //Figure out new payout algorithm
      if(inRewardCluster[score] == true)
      {
        Concept(concept).setBalance(assessors[i], UserRegistry(userRegistry).getBalance(assessors[i]) + payoutValue);
        User(assessors[i]).notification(concept, 15); //You Have Received Payment For Your Assessment
      }
      if(inRewardCluster[score] == false)
      {
        Concept(concept).setBalance(assessors[i], UserRegistry(userRegistry).getBalance(assessors[i]) - payoutValue);
        User(assessors[i]).notification(concept, 16); //You Have Received A Fine For Your Assessment
      }
    }
    Concept(concept).finishAssessment(finalScore, assessee, address(this));();
  }

}

import "math.sol";
import "userRegistry.sol";
import "concept.sol";
import "user.sol";
import "conceptRegistry.sol";

contract Assessment
{
  address assessee; //The address of the user being assessed
  address[] assessors;
  address[] finalAssessors; //The assessors who actually give an assessment
  mapping (address => uint) assessorState;
  address[] assessorPool; //The addresses of the user's that the assessors are randomly selected from
  address concept;
  address userRegistry;
  address conceptRegistry;
  address math = 0x90B66E80448eb60938FAed4A738dE0D5b630B2Fd;
  uint public startTime;
  uint public size;
  uint cost;
  uint poolSizeRemaining;
  mapping(address => string[]) public data; //IFFS hashes of data that can be passed between the assessors and the assessee for the assessment to occur
  mapping(address => bytes32) commits;
  mapping(address => uint) stake;
  uint done = 0;
  mapping(address => int8) scores;
  mapping(int => bool) inRewardCluster;
  int8 finalScore;
  event DataSet(address _dataSetter, uint _index);

  /*
  @type: modifier
  @name: onlyThis
  @purpose: to only allow the this contract to call a function to which this modifier is applied
  */
  modifier onlyThis()
  {
    if(msg.sender != address(this)) //Checks if msg.sender is this contract
    {
      throw; //Throws out the function call if it isn't
    }
    _;
  }

  /*
  @type: modifier
  @name: onlyAssessorAssessee
  @purpose: to only allow the assessors and assessee to call a function to which this modifier is applied
  */
  modifier onlyAssessorAssessee()
  {
    if(msg.sender != assessee && assessorState[msg.sender] == 0) //Checks if msg.sender has the same address as either the assessee or an assessor
    {
      throw; //Throws the function call if not
    }
    _;
  }

  /*
  @type: modifier
  @name: onlyConceptAssessment
  @purpose: to only allow the this contract or the Concept contract that spawned it to call a function to which this modifier is applied
  */
  modifier onlyConceptAssessment()
  {
    if(msg.sender != address(this) && msg.sender != concept) //Checks if msg.sender has the same address as this contract or the Concept that spawned it
    {
      throw; //Throws the function call if not
    }
    _;
  }

  function Assessment(address assesseeAddress, address userRegistryAddress, address conceptRegistryAddress, uint assessmentSize, uint assessmentCost)
  {
    assessee = assesseeAddress;
    concept = msg.sender;
    userRegistry = userRegistryAddress;
    conceptRegistry = conceptRegistryAddress;
    startTime = block.timestamp;
    size = assessmentSize;
    cost = assessmentCost;
    poolSizeRemaining = size*20;
    User(assessee).notification(concept, 0); //Assessment made
  }

  function cancelAssessment() onlyConceptAssessment()
  {
    Concept(concept).setBalance(assessee, UserRegistry(userRegistry).getBalance(assessee) + cost*size);
    User(assessee).notification(concept, 3); //Assessment Cancled and you have been refunded
    for(uint i = 0; i < assessors.length; i++)
    {
      Concept(concept).setBalance(assessors[i], UserRegistry(userRegistry).getBalance(assessors[i]) + cost);
      User(assessors[i]).notification(concept, 3); //Assessment Cancled and you have been refunded
    }
    suicide(conceptRegistry);
  }

  /*
  @type: function
  @purpose: To recursively set the pool to draw assessors from in the assessment
  @param: address conceptAddress = the concept that assessors are currently being drawn from
  @param: address assessment = the address of the assessment that assessors are being drawn for
  @param: uint seed = the seed number for random number generation
  @param: uint size = the desired size of the assessment
  @returns: nothing
  */
  function setAssessorPool(address conceptAddress, uint seed) onlyConceptAssessment()
  {
    if(Concept(ConceptRegistry(conceptRegistry).mewAddress()).getOwnerLength() < poolSizeRemaining) //Checks if the requested pool size is greater than the number of users in the system
    {
      for(uint i = 0; i < Concept(ConceptRegistry(conceptRegistry).mewAddress()).getOwnerLength(); i++) //If so, all users in the system are added to the pool
      {
        assessorPool.push(Concept(ConceptRegistry(conceptRegistry).mewAddress()).owners(i));
        User(Concept(ConceptRegistry(conceptRegistry).mewAddress()).owners(i)).notification(concept, 1); //Called As A Potential Assessor
        assessorState[Concept(ConceptRegistry(conceptRegistry).mewAddress()).owners(i)] = 1;
      }
      poolSizeRemaining = 0;
    }
    assessors = Concept(concept).getAssessors(poolSizeRemaining, seed);
    for(uint j=0; j<poolSizeRemaining; j++)
    {
      User(assessors[i]).notification(concept, 1); //Called As A Potential Assessor
      assessorState[assessors[i]] = 1;
    }
  }

  function confirmAssessor()
  {
    if(block.number - startTime <= 15 && assessorState[msg.sender] == 1 && assessors.length < size && UserRegistry(userRegistry).getBalance(msg.sender) >= cost)
    {
      assessors.push(msg.sender);
      assessorState[msg.sender] = 2;
      stake[msg.sender] = cost;
      Concept(concept).setBalance(msg.sender,UserRegistry(userRegistry).getBalance(msg.sender) - cost);
      User(msg.sender).notification(concept, 2); //Confirmed for assessing, stake has been taken
    }
    if(assessors.length == size)
    {
      notifyStart();
    }
    else if(block.number - startTime > 15 && assessors.length < size)
    {
      cancelAssessment();
    }
  }

  function notifyStart() onlyThis()
  {
    for(uint i = 0; i < assessors.length; i++)
    {
      User(assessors[i]).notification(concept, 4); //Assessment Has Started
    }
    User(assessee).notification(concept, 4); //Assessment Has Started
  }

  function setData(string newData) onlyAssessorAssessee()
  {
    data[msg.sender].push(newData);
    DataSet(msg.sender, data[msg.sender].length - 1);
  }

  function commit(bytes32 hash)
  {
    if(assessorState[msg.sender] == 2)
    {
      commits[msg.sender] = hash;
      assessorState[msg.sender] == 3;
      done++;
      if(done <= size/2)
      {
        startTime = block.number;
      }
    }
    if(done > size/2)
    {
      for(uint i = 0; i < assessors.length; i++)
      {
        if(assessorState[assessors[i]] == 2)
        {
          //burn da stakes
        }
        if(stake[assessors[i]] == 0)
        {
          assessorState[assessors[i]] = 4;
          done++;
        }
      }
    }
    if(done == size)
    {
      for(uint j = 0; j < assessors.length; j++)
      {
        if(assessorState[assessors[j]] == 3)
        {
          User(assessors[j]).notification(concept, 5); //Send in Score
        }
      }
      startTime = block.number;
      done = 0;
    }
  }

  function reveal(int score, bytes16 salt, address assessor)
  {
    if(block.number - startTime <= 10)
    {
      bytes32 hash = sha3(score,salt);
      if(commits[assessor] == hash)
      {
        if(msg.sender == assessor)
        {
          scores[msg.sender] = score;
          assessorState[assessor] = 5;
          done++;
        }
        else
        {
          Concept(concept).setBalance(msg.sender,UserRegistry(userRegistry).getBalance(msg.sender) + stake[assessor]);
          stake[assessor] = 0;
          assessorState[assessor] = 4;
        }
      }
      else if(msg.sender == assessor)
      {
        stake[assessor] = 0;
        assessorState[assessor] = 4;
        done++;
      }
    }
    else
    {
      for(uint i = 0; i < assessors.length; i++)
      {
        if(assessorState[assessors[i]] == 3)
        {
          stake[assessors[i]] = 0;
          assessorState[assessors[i]] = 4;
          done++;
        }
      }
    }
    if(done == size)
    {
      calculateResult();
    }
  }

  function calculateResult() onlyThis()
  {
    mapping(uint => int[]) clusters;
    for(uint j = 0; j < size; j++)
    {
      if(assessorState[assessors[i]] == 5)
      {
        finalAssessors.push(assessors[i]);
      }
    }
    int[] memory score = new int[] (finalAssessors.length);
    uint largestClusterIndex = 0;
    int averageScore;
    for(uint i = 0; i < finalAssessors.length; i++)
    {
      score[i] = scores[finalAssessors[i]];
    }
    int meanAbsoluteDeviation = Math(math).calculateMAD(score,int(finalAssessors.length));
    for(uint l = 0; l < score.length; l++)
    {
      for(uint m = 0; m < score.length; m++)
      {
        if(score[l] - score[m] <= meanAbsoluteDeviation)
        {
          clusters[l].push(score[m]);
        }
      }
      if(clusters[l].length > clusters[largestClusterIndex].length)
      {
        largestClusterIndex = l;
      }
    }
    for(uint o = 0; o < clusters[largestClusterIndex].length; o++)
    {
      averageScore += clusters[largestClusterIndex][o];
      inRewardCluster[clusters[largestClusterIndex][o]] = true;
    }
    averageScore /= int(clusters[largestClusterIndex].length);
    finalScore = averageScore;
    payout(clusters[largestClusterIndex].length);
  }

  function payout(uint largestSize) onlyThis()
  {
    for(uint i = 0; i < size; i++)
    {
      int score = scores[assessors[i]];
      int scoreDistance = ((score - finalScore)*100)/finalScore;
      if(scoreDistance < 0)
      {
        scoreDistance *= -1;
      }
      uint payoutValue = 1; //Figure out new payout algorithm
      if(inRewardCluster[score] == true)
      {
        Concept(concept).setBalance(assessors[i], UserRegistry(userRegistry).getBalance(assessors[i]) + payoutValue);
        User(assessors[i]).notification(concept, 15); //You Have Received Payment For Your Assessment
      }
      if(inRewardCluster[score] == false)
      {
        Concept(concept).setBalance(assessors[i], UserRegistry(userRegistry).getBalance(assessors[i]) - payoutValue);
        User(assessors[i]).notification(concept, 16); //You Have Received A Fine For Your Assessment
      }
    }
    Concept(concept).finishAssessment(finalScore, assessee, address(this));();
  }

}


Added investor supply contract

Added investor supply contract

pragma solidity ^0.4.18;

import 'common/Object.sol';
import 'token/ERC20.sol';

contract InvestorSupply is Object {
    ERC20 constant public utility;

    mapping(bytes32 => uint256) supplyOf;
    mapping(bytes32 => mapping(address => uint256)) accountSupplyOf;

    function supply(string _market) view returns (uint256)
    { return supplyOf[keccak256(market)]; }

    function refill(string _market, uint256 _value) {
        require(utility.transferFrom(msg.sender, this, _value));
        supplyOf[keccak256(market)] += _value;
        accountSupplyOf[keccak256(market)][msg.sender] += _value;
    }

    function withdraw(string _market, uint256 _value) {
        require(accountSupplyOf[keccak256(market)][msg.sender] >= _value);
        supplyOf[keccak256(market)] -= _value;
        accountSupplyOf[keccak256(market)][msg.sender] -= _value;
    }
}

error: pathspec 'contracts/market/InvestorSupply.sol' did not match any file(s) known to git


example contract allowing to tokenize minting rights

pragma solidity 0.4.11;
import "token.sol";
import "mint.sol";

/// @title Raiden token contract
/// @author Heiko Hees

// Allow to tokenize MintingRights and make them tradable
//
// Mechanics:
// Contract which owns and tokenizes minting rights, i.e. allows to trade tokens that will be mintable in the future.
// In order to be fungible all tokenized MintingRights need to have the same start and maturity date.
// One future token represents the right to receive one original token at the maturity date
// the contract mints tokens (if called to do so) and keeps them until the minting period ended.
//
// 1) Transfer minting rights to the contract
// 2) get future tokens equivalent to the number of not minted tokens
// 3) at the maturity date the tokens can be claimed by destroying the future
// 4) future tokens can be freely transferred (i.e. traded)

contract RaidenFuturesToken is StandardToken {

    /*  Token meta data */

    string constant public name = "Raiden Token Future";
    string constant public symbol = "RDNF";
    uint constant public decimals = 24;  // ETH has 18
    Token public token;
    Mint public mint;
    uint startTime;
    uint endTime;

    /* Events */

    event Destroyed(address indexed receiver, uint num, uint _totalSupply);
    event Issued(address indexed receiver, uint num, uint _totalSupply);

    /*  Public functions */

    /// @dev Contract constructor function sets the token and mint contract address plus minting period
    function RaidenFuturesToken(address _token, address _mint, uint _startTime, uint _endTime)
        public
    {
        token = _token;
        mint = _mint;
        startTime = _startTime;
        endTime = _endTime;
    }

    // how many tokens an address can mint now and in the future in total
    function totalMintable(address _account)
        public
        constant
    {
        uint[] mr = mint.getMintingRight(_account);
        require(mr[0] == startTime && mr[1] == endTime); // require compatible minting periods
        return mr[2] - mr[3]; // total - issued
    }

    // convert minting rights to futures
    function issue()
        public
    {
        require(totalMintable(msg.sender) > 0); // implicitly requires compatible minting periods
        // transfer rights to this contract
        uint mintable_before = totalMintable(this.address);
        // transfer minting rights to this contract
        // note: would not fail for the first call if minting periods don't match!
        require(mint.delegatecall(bytes4(sha3("transferMintingRight(address)"), this.address)); // FIXME
        uint mintable_after = totalMintable(this.address);
        uint newly_issued = mintable_after - mintable_before;
        require(newly_issued >0);
        totalSupply += newly_issued;
        balances[msg.sender] += newly_issued;
        assert(totalSupply == mintable_after);
        assert(totalSupply <= token.totalSupply());
        Issued(msg.sender, newly_issued, totalSupply);
    }

    // anyone can call at any time. helpful to update the totalSupply of token
    function mintOutstandingTokens()
        public
        returns (uint)
    {
        // mint all minable tokens
        uint mintable = mint.mintable(this.address);
        if (mintable) {
            assert(mint.mint(mintable, this.address));
            assert(totalSupply == token.balanceOf(this.address));
        }
        return mintable;
    }

    // after endTime, the futures can be converted to their respective Tokens
    function destroy()
        public
    {
        uint num = balances[msg.sender];
        require(num>0);
        require(now >= endTime);
        mintOutstandingTokens();
        totalSupply -= num;
        balances[msg.sender] = 0;
        assert(token.transfer(msg.sender, num));
        assert(totalSupply == token.balanceOf(this.address));
        Destroyed(msg.sender, num, totalSupply);
    }
}

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


Log creation of new shortIds.

Log creation of new shortIds.

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 A new shortId has been created.
     * @param itemId itemId of the item.
     * @param shortId shortId of the item
     */
    event CreateShortId(bytes32 indexed itemId, bytes32 shortId);

    /**
     * @dev Revert if the itemId already has a shortId.
     * @param itemId itemId of the item.
     */
    modifier noShortId(bytes32 itemId) {
        require (itemIdShortId[itemId] == 0);
        _;
    }

    /**
     * @dev Create a 4 byte shortId for a 32 byte itemId.
     * @param itemId itemId of the item.
     * @return shortId New 4 byte shortId.
     */
    function createShortId(bytes32 itemId) external noShortId(itemId) returns (bytes4 shortId) {
        // Caluculate the shortId.
        bytes32 hash = keccak256(itemId);
        shortId = bytes4(hash);
        // Make sure it hasn't been used before.
        while(shortIdItemId[shortId] != 0) {
            hash = keccak256(hash);
            shortId = bytes4(hash);
        }
        // Store the mappings.
        itemIdShortId[itemId] = shortId;
        shortIdItemId[shortId] = itemId;
        // Log the event.
        emit CreateShortId(itemId, shortId);
    }

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

}

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 Revert if the itemId already has a shortId.
     * @param itemId itemId of the item.
     */
    modifier noShortId(bytes32 itemId) {
        require (itemIdShortId[itemId] == 0);
        _;
    }

    /**
     * @dev Create a 4 byte shortId for a 32 byte itemId.
     * @param itemId itemId of the item.
     * @return shortId New 4 byte shortId.
     */
    function createShortId(bytes32 itemId) external noShortId(itemId) returns (bytes4 shortId) {
        // Caluculate the shortId.
        bytes32 hash = keccak256(itemId);
        shortId = bytes4(hash);
        // Make sure it hasn't been used before.
        while(shortIdItemId[shortId] != 0) {
            hash = keccak256(hash);
            shortId = bytes4(hash);
        }
        // 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];
    }

}