Implemented stake burning algorithm

Implemented stake burning algorithm

pragma solidity ^0.4.0;

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;
  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 _assessee, address _userRegistry, address _conceptRegistry, uint _size, uint _cost)
  {
    assessee = _assessee;
    concept = msg.sender;
    userRegistry = _userRegistry;
    conceptRegistry = _conceptRegistry;
    startTime = block.timestamp;
    size = _size;
    cost = _cost;
    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()
  {
    if(assessorState[assessor] == 0)
    {
      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: uint seed = the seed number for random number generation
  @returns: nothing
  */
  function setAssessorPool(uint seed) onlyConceptAssessment()
  {
    if(Concept(ConceptRegistry(conceptRegistry).mewAddress()).getOwnerLength() < size*20) //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(size*20, 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 _data) onlyAssessorAssessee()
  {
    data[msg.sender].push(_data);
    DataSet(msg.sender, data[msg.sender].length - 1);
  }

  function commit(bytes32 hash)
  {
    if(done > size/2)
    {
      for(uint i = 0; i < assessors.length; i++)
      {
        if(assessorState[assessors[i]] == 2)
        {
          r = 38; //Inverse burn rate
          stake[assessors[i]] = cost*2**(-(now-startTime)/r) - 1;
        }
        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;
    }
    if(assessorState[msg.sender] == 2)
    {
      commits[msg.sender] = hash;
      assessorState[msg.sender] == 3;
      done++;
      if(done <= size/2)
      {
        startTime = block.number;
      }
    }
  }

  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));();
  }

}

pragma solidity ^0.4.0;

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;
  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 _assessee, address _userRegistry, address _conceptRegistry, uint _size, uint _cost)
  {
    assessee = _assessee;
    concept = msg.sender;
    userRegistry = _userRegistry;
    conceptRegistry = _conceptRegistry;
    startTime = block.timestamp;
    size = _size;
    cost = _cost;
    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()
  {
    if(assessorState[assessor] == 0)
    {
      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: uint seed = the seed number for random number generation
  @returns: nothing
  */
  function setAssessorPool(uint seed) onlyConceptAssessment()
  {
    if(Concept(ConceptRegistry(conceptRegistry).mewAddress()).getOwnerLength() < size*20) //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(size*20, 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 _data) onlyAssessorAssessee()
  {
    data[msg.sender].push(_data);
    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));();
  }

}


Decided open TODO items, removed wrong comment about change of ownership

pragma solidity ^0.4.11;

import 'zeppelin/SafeMath.sol';

/**
 * @title Standing order
 * @dev Lifecycle of a standing order:
 *  - the payment amount per interval is set at construction time and can not be changed afterwards
 *  - the payee is set by the owner and can not be changed after creation
 *  - at <startTime> (unix timestamp) the first payment is due
 *  - every <intervall> seconds the next payment is due
 *  - the owner can add funds to the order contract at any time
 *  - the owner can withdraw only funds that do not (yet) belong to the payee
 *  - the owner can terminate a standingorder anytime. Termination results in:
 *    - No further funding being allowed
 *    - order marked as "terminated" and not being displayed anymore in owner UI
 *    - as long as there are uncollected funds entitled to the payee, it is still displayed in payee UI
 *    - the payee can still collect funds owned to him
 *
 *   * Terminology *
 *   "withdraw" -> performed by owner - transfer funds stored in contract back to owner
 *   "collect"  -> performed by payee - transfer entitled funds from contract to payee
 *
 *   * How does a payment work? *
 *   Since a contract can not trigger a payment by itself, it provides the method "collectFunds" for the payee.
 *   The payee can always query the contract to determine how many funds he is entitled to collect.
 *   The payee can call "collectFunds" to initiate transfer of entitled funds to his address.
 */
contract StandingOrder is SafeMath {
    address public owner;        /** The owner of this order */
    address public payee;        /** The payee is the receiver of funds */
    uint public startTime;       /** Date and time (unix timestamp - seconds since 1970) when first payment can be claimed by payee */
    uint public paymentInterval; /** Interval for payments (Unit: seconds) */
    uint public paymentAmount;   /** How much can payee claim per period (Unit: Wei) */
    uint public claimedFunds;    /** How much funds have been claimed already (Unit: Wei) */
    string public ownerLabel;    /** Label (set by contract owner) */
    bool public isTerminated;    /** Marks order as terminated */
    uint public terminationTime; /** Date and time (unix timestamp - seconds since 1970) when order terminated */

    modifier onlyPayee() {
        require(msg.sender == payee);
        _;
    }

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

    /** Event triggered when payee collects funds */
    event Collect(uint amount);
    /** Event triggered when contract gets funded */
    event Fund(uint amount);
    /** Event triggered when owner withdraws funds */
    event Withdraw(uint amount);

    /**
     * Constructor
     * @param _owner The owner of the contract
     * @param _payee The payee - the account that can collect payments from this contract
     * @param _paymentInterval Interval for payments, unit: seconds
     * @param _paymentAmount The amount payee can claim per period, unit: wei
     * @param _startTime Date and time (unix timestamp - seconds since 1970) when first payment can be claimed by payee
     * @param _label Label for contract, e.g "rent" or "weekly paycheck"
     */
    function StandingOrder(
        address _owner,
        address _payee,
        uint _paymentInterval,
        uint _paymentAmount,
        uint _startTime,
        string _label
    )
        payable
    {
        // Sanity check parameters
        require(_paymentInterval > 0);
        require(_paymentAmount > 0);
        // Following check is not exact for unicode strings, but here i just want to make sure that some label is provided
        // See https://ethereum.stackexchange.com/questions/13862/is-it-possible-to-check-string-variables-length-inside-the-contract/13886
        require(bytes(_label).length > 2);

        // Set owner to _owner, as msg.sender is the StandingOrderFactory contract
        owner = _owner;

        payee = _payee;
        paymentInterval = _paymentInterval;
        paymentAmount = _paymentAmount;
        ownerLabel = _label;
        startTime = _startTime;
        isTerminated = false;
    }

    /**
     * Fallback function.
     * Allows adding funds to existing order. Will throw in case the order is terminated!
     */
    function() payable {
        // TODO: Dont make contract as a whole payable. Instead create a dedicated "addFunds" method to prevent any accidental payment!
        if (isTerminated) {
            // adding funds not allowed for terminated orders
            revert();
        }
        // Log Fund event
        Fund(msg.value);
    }

    /**
     * Determine how much funds payee is entitled to collect
     * Note that this might be more than actual funds available!
     * @return Number of wei that payee is entitled to collect
     */
    function getEntitledFunds() constant returns (uint) {
        // First check if the contract startTime has been reached at all
        if (now < startTime) {
            // startTime not yet reached
            return 0;
        }

        // startTime has been reached, so add first payment
        uint entitledAmount = paymentAmount;

        // Determine endTime for calculation. If order has been terminated -> terminationTime, otherwise current time
        uint endTime = isTerminated ? terminationTime : now;

        // calculate number of complete intervals since startTime
        uint runtime = safeSub(endTime, startTime);
        uint completeIntervals = safeDiv(runtime, paymentInterval); // implicitly rounding down
        // add interval * paymentAmount to entitledAmount
        entitledAmount = safeAdd(entitledAmount, safeMul(completeIntervals, paymentAmount));

        // subtract already collected funds
        return safeSub(entitledAmount, claimedFunds);
    }

    /**
     * Determine how much funds are available for payee to collect
     * This can be less than the entitled amount if the contract does not have enough funds to cover the due payments,
     * in other words: The owner has not put enough funds into the contract.
     * @return Number of wei that payee can collect
     */
    function getUnclaimedFunds() constant returns (uint) {
        // don't return more than available balance
        return min256(getEntitledFunds(), this.balance);
    }

    /**
     * Determine how much funds are still owned by owner (not yet reserved for payee)
     * Note that this can be negative in case contract is not funded enough to cover entitled amount for payee!
     * @return number of wei belonging owner, negative if contract is missing funds to cover payments
     */
    function getOwnerFunds() constant returns (int) {
        // Conversion from unsigned int to int will produce unexpected results only for very large
        // numbers (2^255 and greater)
        return int256(this.balance) - int256(getEntitledFunds());
    }

    /**
     * Collect payment
     * Can only be called by payee. This will transfer all available funds (see getUnclaimedFunds) to payee
     * @return amount that has been transferred!
     */
    function collectFunds() onlyPayee returns(uint) {
        uint amount = getUnclaimedFunds();
        if (amount <= 0) {
            // nothing to collect :-(
            revert();
        }

        // keep track of collected funds
        claimedFunds = safeAdd(claimedFunds, amount);

        // create log entry
        Collect(amount);

        // initiate transfer of unclaimed funds to payee
        payee.transfer(amount);

        return amount;
    }

    /**
     * Withdraw requested amount back to owner.
     * Only funds not (yet) reserved for payee can be withdrawn. So it is not possible for the owner
     * to withdraw unclaimed funds - They can only be claimed by payee!
     * Withdrawing funds does not terminate the order, at any time owner can fund it again!
     * @param amount Number of wei owner wants to withdraw
     */
    function WithdrawOwnerFunds(uint amount) onlyOwner {
        int intOwnerFunds = getOwnerFunds(); // this might be negative in case of underfunded contract!
        if (intOwnerFunds <= 0) {
            // nothing available to withdraw :-(
            revert();
        }
        // conversion int -> uint is safe here as I'm checking <= 0 above!
        uint256 ownerFunds = uint256(intOwnerFunds);

        if (amount > ownerFunds) {
            // Trying to withdraw more than available!
            revert(); // Alternatively could just withdraw all available funds
        }

        // Log Withdraw event
        Withdraw(amount);

        owner.transfer(amount);
    }

    /**
     * Terminate order
     * Marks the order as terminated.
     * Can only be executed if no ownerfunds are left
     */
    function Terminate() onlyOwner {
        assert(getOwnerFunds() <= 0);
        terminationTime = now;
        isTerminated = true;
    }
}

/**
 * @title StandingOrder factory
 */
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
     * The owner of the new order will be the address that called this function (msg.sender)
     * @param _payee The payee - the account that can collect payments from this contract
     * @param _paymentInterval Interval for payments, unit: seconds
     * @param _paymentAmount The amount payee can claim per period, unit: wei
     * @param _startTime Date and time (unix timestamp - seconds since 1970) when first payment can be claimed by payee
     * @param _label Label for contract, e.g "rent" or "weekly paycheck"
     * @return Address of new created standingOrder contract
     */
    function createStandingOrder(address _payee, uint _paymentAmount, uint _paymentInterval, uint _startTime, string _label) returns (StandingOrder) {
        StandingOrder so = new StandingOrder(msg.sender, _payee, _paymentInterval, _paymentAmount, _startTime, _label);
        standingOrdersByOwner[msg.sender].push(so);
        standingOrdersByPayee[_payee].push(so);
        LogOrderCreated(so, msg.sender, _payee);
        return so;
    }

    /**
     * Determine how many orders are owned by caller (msg.sender)
     * @return Number of orders
     */
    function getNumOrdersByOwner() constant returns (uint) {
        return standingOrdersByOwner[msg.sender].length;
    }

    /**
     * Get order by index from the Owner mapping
     * @param index Index of order
     * @return standing order address
     */
    function getOwnOrderByIndex(uint index) constant returns (StandingOrder) {
        return standingOrdersByOwner[msg.sender][index];
    }

    /**
     * Determine how many orders are paying to caller (msg.sender)
     * @return Number of orders
     */
    function getNumOrdersByPayee() constant returns (uint) {
        return standingOrdersByPayee[msg.sender].length;
    }

    /**
     * Get order by index from the Payee mapping
     * @param index Index of order
     * @return standing order address
     */
    function getPaidOrderByIndex(uint index) constant returns (StandingOrder) {
        return standingOrdersByPayee[msg.sender][index];
    }
}

pragma solidity ^0.4.11;

import 'zeppelin/SafeMath.sol';

/**
 * @title Standing order
 * @dev Lifecycle of a standing order:
 *  - the payment amount per interval is set at construction time and can not be changed afterwards
 *  - the payee is set by the owner and can not be changed after creation (TODO: Decide if payee should be able to change receiving address?)
 *  - the owner can be changed by owner (using "ownable" base contract) (TODO: Change to "claimable" base contract for extra security!)
 *  - at <startTime> (unix timestamp) the first payment is due
 *  - every <intervall> seconds the next payment is due
 *  - the owner can add funds to the order contract at any time
 *  - the owner can withdraw only funds that do not (yet) belong to the payee
 *  - the owner can terminate a standingorder anytime. Termination results in:
 *    - No further funding being allowed
 *    - order marked as "terminated" and not being displayed anymore in owner UI
 *    - as long as there are uncollected funds entitled to the payee, it is still displayed in payee UI
 *    - the payee can still collect funds owned to him
 *
 *   * Terminology *
 *   "withdraw" -> performed by owner - transfer funds stored in contract back to owner
 *   "collect"  -> performed by payee - transfer entitled funds from contract to payee
 *
 *   * How does a payment work? *
 *   Since a contract can not trigger a payment by itself, it provides the method "collectFunds" for the payee.
 *   The payee can always query the contract to determine how many funds he is entitled to collect.
 *   The payee can call "collectFunds" to initiate transfer of entitled funds to his address.
 */
contract StandingOrder is SafeMath {
    address public owner;        /** The owner of this order */
    address public payee;        /** The payee is the receiver of funds */
    uint public startTime;       /** Date and time (unix timestamp - seconds since 1970) when first payment can be claimed by payee */
    uint public paymentInterval; /** Interval for payments (Unit: seconds) */
    uint public paymentAmount;   /** How much can payee claim per period (Unit: Wei) */
    uint public claimedFunds;    /** How much funds have been claimed already (Unit: Wei) */
    string public ownerLabel;    /** Label (set by contract owner) */
    bool public isTerminated;    /** Marks order as terminated */
    uint public terminationTime; /** Date and time (unix timestamp - seconds since 1970) when order terminated */

    modifier onlyPayee() {
        require(msg.sender == payee);
        _;
    }

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

    /** Event triggered when payee collects funds */
    event Collect(uint amount);
    /** Event triggered when contract gets funded */
    event Fund(uint amount);
    /** Event triggered when owner withdraws funds */
    event Withdraw(uint amount);

    /**
     * Constructor
     * @param _owner The owner of the contract
     * @param _payee The payee - the account that can collect payments from this contract
     * @param _paymentInterval Interval for payments, unit: seconds
     * @param _paymentAmount The amount payee can claim per period, unit: wei
     * @param _startTime Date and time (unix timestamp - seconds since 1970) when first payment can be claimed by payee
     * @param _label Label for contract, e.g "rent" or "weekly paycheck"
     */
    function StandingOrder(
        address _owner,
        address _payee,
        uint _paymentInterval,
        uint _paymentAmount,
        uint _startTime,
        string _label
    )
        payable
    {
        // Sanity check parameters
        require(_paymentInterval > 0);
        require(_paymentAmount > 0);
        // Following check is not exact for unicode strings, but here i just want to make sure that some label is provided
        // See https://ethereum.stackexchange.com/questions/13862/is-it-possible-to-check-string-variables-length-inside-the-contract/13886
        require(bytes(_label).length > 2);

        // Set owner to _owner, as msg.sender is the StandingOrderFactory contract
        owner = _owner;

        payee = _payee;
        paymentInterval = _paymentInterval;
        paymentAmount = _paymentAmount;
        ownerLabel = _label;
        startTime = _startTime;
        isTerminated = false;
    }

    /**
     * Fallback function.
     * Allows adding funds to existing order. Will throw in case the order is terminated!
     */
    function() payable {
        // TODO: Dont make contract as a whole payable. Instead create a dedicated "addFunds" method to prevent any accidental payment!
        if (isTerminated) {
            // adding funds not allowed for terminated orders
            revert();
        }
        // Log Fund event
        Fund(msg.value);
    }

    /**
     * Determine how much funds payee is entitled to collect
     * Note that this might be more than actual funds available!
     * @return Number of wei that payee is entitled to collect
     */
    function getEntitledFunds() constant returns (uint) {
        // First check if the contract startTime has been reached at all
        if (now < startTime) {
            // startTime not yet reached
            return 0;
        }

        // startTime has been reached, so add first payment
        uint entitledAmount = paymentAmount;

        // Determine endTime for calculation. If order has been terminated -> terminationTime, otherwise current time
        uint endTime = isTerminated ? terminationTime : now;

        // calculate number of complete intervals since startTime
        uint runtime = safeSub(endTime, startTime);
        uint completeIntervals = safeDiv(runtime, paymentInterval); // implicitly rounding down
        // add interval * paymentAmount to entitledAmount
        entitledAmount = safeAdd(entitledAmount, safeMul(completeIntervals, paymentAmount));

        // subtract already collected funds
        return safeSub(entitledAmount, claimedFunds);
    }

    /**
     * Determine how much funds are available for payee to collect
     * This can be less than the entitled amount if the contract does not have enough funds to cover the due payments,
     * in other words: The owner has not put enough funds into the contract.
     * @return Number of wei that payee can collect
     */
    function getUnclaimedFunds() constant returns (uint) {
        // don't return more than available balance
        return min256(getEntitledFunds(), this.balance);
    }

    /**
     * Determine how much funds are still owned by owner (not yet reserved for payee)
     * Note that this can be negative in case contract is not funded enough to cover entitled amount for payee!
     * @return number of wei belonging owner, negative if contract is missing funds to cover payments
     */
    function getOwnerFunds() constant returns (int) {
        // Conversion from unsigned int to int will produce unexpected results only for very large
        // numbers (2^255 and greater)
        return int256(this.balance) - int256(getEntitledFunds());
    }

    /**
     * Collect payment
     * Can only be called by payee. This will transfer all available funds (see getUnclaimedFunds) to payee
     * @return amount that has been transferred!
     */
    function collectFunds() onlyPayee returns(uint) {
        uint amount = getUnclaimedFunds();
        if (amount <= 0) {
            // nothing to collect :-(
            revert();
        }

        // keep track of collected funds
        claimedFunds = safeAdd(claimedFunds, amount);

        // create log entry
        Collect(amount);

        // initiate transfer of unclaimed funds to payee
        payee.transfer(amount);

        return amount;
    }

    /**
     * Withdraw requested amount back to owner.
     * Only funds not (yet) reserved for payee can be withdrawn. So it is not possible for the owner
     * to withdraw unclaimed funds - They can only be claimed by payee!
     * Withdrawing funds does not terminate the order, at any time owner can fund it again!
     * @param amount Number of wei owner wants to withdraw
     */
    function WithdrawOwnerFunds(uint amount) onlyOwner {
        int intOwnerFunds = getOwnerFunds(); // this might be negative in case of underfunded contract!
        if (intOwnerFunds <= 0) {
            // nothing available to withdraw :-(
            revert();
        }
        // conversion int -> uint is safe here as I'm checking <= 0 above!
        uint256 ownerFunds = uint256(intOwnerFunds);

        if (amount > ownerFunds) {
            // Trying to withdraw more than available!
            revert(); // Alternatively could just withdraw all available funds
        }

        // Log Withdraw event
        Withdraw(amount);

        owner.transfer(amount);
    }

    /**
     * Terminate order
     * Marks the order as terminated.
     * Can only be executed if no ownerfunds are left
     */
    function Terminate() onlyOwner {
        assert(getOwnerFunds() <= 0);
        terminationTime = now;
        isTerminated = true;
    }
}

/**
 * @title StandingOrder factory
 */
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
     * The owner of the new order will be the address that called this function (msg.sender)
     * @param _payee The payee - the account that can collect payments from this contract
     * @param _paymentInterval Interval for payments, unit: seconds
     * @param _paymentAmount The amount payee can claim per period, unit: wei
     * @param _startTime Date and time (unix timestamp - seconds since 1970) when first payment can be claimed by payee
     * @param _label Label for contract, e.g "rent" or "weekly paycheck"
     * @return Address of new created standingOrder contract
     */
    function createStandingOrder(address _payee, uint _paymentAmount, uint _paymentInterval, uint _startTime, string _label) returns (StandingOrder) {
        StandingOrder so = new StandingOrder(msg.sender, _payee, _paymentInterval, _paymentAmount, _startTime, _label);
        standingOrdersByOwner[msg.sender].push(so);
        standingOrdersByPayee[_payee].push(so);
        LogOrderCreated(so, msg.sender, _payee);
        return so;
    }

    /**
     * Determine how many orders are owned by caller (msg.sender)
     * @return Number of orders
     */
    function getNumOrdersByOwner() constant returns (uint) {
        return standingOrdersByOwner[msg.sender].length;
    }

    /**
     * Get order by index from the Owner mapping
     * @param index Index of order
     * @return standing order address
     */
    function getOwnOrderByIndex(uint index) constant returns (StandingOrder) {
        return standingOrdersByOwner[msg.sender][index];
    }

    /**
     * Determine how many orders are paying to caller (msg.sender)
     * @return Number of orders
     */
    function getNumOrdersByPayee() constant returns (uint) {
        return standingOrdersByPayee[msg.sender].length;
    }

    /**
     * Get order by index from the Payee mapping
     * @param index Index of order
     * @return standing order address
     */
    function getPaidOrderByIndex(uint index) constant returns (StandingOrder) {
        return standingOrdersByPayee[msg.sender][index];
    }
}


Build fixes

Build fixes

pragma solidity ^0.4.4;

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

/**
 * @title Core liability contract
 */
contract Liability is Object {
    /**
     * Params
     */
    address public promisor;
    address public promisee;

    ERC20   public token;
    uint256 public cost;

    uint public constant gasbase = 500000;
    uint public gasprice;

    /**
     * @dev Create liability contract
     * @param _promisor Promisor account
     * @param _promisee Promisee account
     * @param _token Payment token contract
     * @param _cost Liability cost
     */
    function Liability(address _promisor,
                       address _promisee,
                       address _token,
                       uint256 _cost) {
        promisor = _promisor;
        promisee = _promisee;
        token = ERC20(_token);
        cost = _cost;
    }

    /**
     * @dev Emitted for every received result hash
     */
    event Result(bytes32 indexed hash);

    /**
     * @dev Current result hash
     */
    bytes32 public resultHash;

    /**
     * @dev Result handler
     * @param _resultHash 256bit hash of result
     * @return `true` if is ok
     */
    function resultHash(bytes32 _resultHash) internal returns (bool) {
        // Result notification
        resultHash = _resultHash;
        Result(_resultHash);

        // Transfer beneficiar reward
        if (!token.transfer(owner, token.balanceOf(this))) throw;
        return true;
    }

    /**
     * @dev Publish liability result hash
     * @notice Only promisor can call it
     * @param _resultHash 256bit hash of result
     * @return `true` if is ok
     */
    function publishHash(bytes32 _resultHash) returns (bool) {
        // Only promisor can publish the results
        if (msg.sender != promisor) throw;
        return resultHash(_resultHash);
    }

    /**
     * @dev Process liability payment
     * @notice Tokens should be transfered before call it
     */
    function payment(uint _gasprice) payable returns (bool) {
        // Store gas price
        gasprice = _gasprice;

        // Check payment
        if (token.balanceOf(this) < cost
          || msg.value < gasprice * gasbase) throw;

        // Send promisor gas expenses
        if (!promisor.send(msg.value)) throw;

        return true;
    }

    /**
     * @dev External owned account oriented payment
     * @notice Tokens should be transfered before send ethers
     */
    function () payable
    { if (!payment(tx.gasprice)) throw; }
}

pragma solidity ^0.4.4;

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

/**
 * @title Core liability contract
 */
contract Liability is Object {
    /**
     * Params
     */
    address public promisor;
    address public promisee;

    ERC20   public token;
    uint256 public cost;

    uint public constant gasbase = 500000;
    uint public gasprice;

    /**
     * @dev Create liability contract
     * @param _promisor Promisor account
     * @param _promisee Promisee account
     * @param _token Payment token contract
     * @param _cost Liability cost
     */
    function Liability(address _promisor,
                       address _promisee,
                       ERC20 _token,
                       uint256 _cost) {
        promisor = _promisor;
        promisee = _promisee;
        token = _token;
        cost = _cost;
    }

    /**
     * @dev Emitted for every received result hash
     */
    event Result(bytes32 indexed hash);

    /**
     * @dev Current result hash
     */
    bytes32 public resultHash;

    /**
     * @dev Result handler
     * @param _resultHash 256bit hash of result
     * @return `true` if is ok
     */
    function resultHash(bytes32 _resultHash) internal returns (bool) {
        // Result notification
        resultHash = _resultHash;
        Result(_resultHash);

        // Transfer beneficiar reward
        if (!token.transfer(owner, token.balanceOf(this))) throw;
        return true;
    }

    /**
     * @dev Publish liability result hash
     * @notice Only promisor can call it
     * @param _resultHash 256bit hash of result
     * @return `true` if is ok
     */
    function publishHash(bytes32 _resultHash) returns (bool) {
        // Only promisor can publish the results
        if (msg.sender != promisor) throw;
        return resultHash(_resultHash);
    }

    /**
     * @dev Process liability payment
     * @notice Tokens should be transfered before call it
     */
    function payment(uint _gasprice) payable returns (bool) {
        // Store gas price
        gasprice = _gasprice;

        // Check payment
        if (token.balanceOf(this) < cost
          || msg.value < gasprice * gasbase) throw;

        // Send promisor gas expenses
        if (!promisor.send(msg.value)) throw;

        return true;
    }

    /**
     * @dev External owned account oriented payment
     * @notice Tokens should be transfered before send ethers
     */
    function () payable
    { if (!payment(tx.gasprice)) throw; }
}


Fix compilation error in sample client

Fix compilation error in sample client

//
// An example client calling our oracle service
//

import "api.sol";

contract SampleClient is usingTinyOracle {
  bytes public response;

  function __tinyOracleCallback(uint256 id, bytes _response) onlyFromTinyOracle external {
    response = _response;
  }

  function query() {
    string memory tmp = "hello world";
    query(bytes(tmp));
  }

  function query(bytes query) {
    queryTinyOracle(query);
  }
}

//
// An example client calling our oracle service
//

import "api.sol";

contract SampleClient is usingTinyOracle {
  bytes public response;

  function __tinyOracleCallback(uint256 id, bytes _response) onlyFromTinyOracle external {
    response = _response;
  }

  function query() {
    query("hello world");
  }

  function query(bytes query) {
    queryTinyOracle(query);
  }
}


Added and started modifying ownable contract

pragma solidity ^0.4.11;

/**
 * @title Ownable
 * @dev The Ownable contract has an owner address, and provides basic authorization control
 * functions, this simplifies the implementation of "user permissions".
 */
contract artOwnable {
  address public owner;

  address public pendingOwner;

  uint public price;

  event PriceSetByOwner(address indexed owner, uint indexed price);

  event OfferAcceptedbyOwner(address indexed purchaser, bool? );

  event PurchaserAddressWhitelisted(?);

  event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);

  /**
   * @dev The Ownable constructor sets the original `owner` of the contract to the sender
   * account.
   */
  function Ownable() {
    owner = msg.sender;
  }

  /**
   * @dev Throws if called by any account other than the owner.
   */
  modifier onlyOwner() {
    require(msg.sender == owner);
    _;
  }

  /**
   * @dev Modifier throws if called by any account other than the pendingOwner.
   */
  modifier onlyPendingOwner() {
    require(msg.sender == pendingOwner);
    _;
  }

  /**
   * @dev Allows the current owner to transfer control of the contract to a newOwner.
   * @param newOwner The address to transfer ownership to.
   */
  function transferOwnership(address newOwner) onlyOwner public {
    require(newOwner != address(0));
    require(
    OwnershipTransferred(owner, newOwner);
    owner = newOwner;
  }

}

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


contract first draft

contract first draft

pragma solidity ^0.4.0;
contract PotOfGold {

    struct Pot {
        string name;
        uint buyIn;

        address[] players;

        uint lastPlayerBlockNumber; // uint8(uint256(sha3(block.blockhash(lastPlayerBlockNumber+1)))) % 3 == loser index

        address loser;
    }

    address owner;

    Pot[] allPots;
    mapping(address => Pot[]) playerToPots;
    mapping(string => Pot) nameToPot;

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

    function ownerWithdraw(){
        if(msg.sender != owner) throw;

        int toWithdraw = this.balance - 100 finney; // leave 0.1 ether for gas (?)
        if(toWithdraw < 0) throw;

        owner.send(toWithdraw);
    }

    function getMyPots() constant returns (Pot[]){
        return playerToPots(msg.sender);
    }

    function getAllPots() constant returns (Pot[]){
        return allPots;
    }

    function getPot(string name) constant returns (Pot){
        return nameToPot[name];
    }

    function createPot(string name, uint buyIn) {
        if(buyIn == 0) throw; // must bet something
        if(bytes(name).length == 0) throw; // name mustn't be empty
        if(nameToPot[name].buyIn != 0) throw; // there's already a pot with this name

        Pot pot = nameToPot[name];
        pot.name = name;
        pot.buyIn = buyIn;
        pot.players.push(msg.sender);
        pot.buyIn = buyIn;

        allPots.push(pot);
        playerToPots[msg.sender].push(pot);
    }

    function joinPot(string name) {
        Pot pot = nameToPot[name];
        if(pot.buyIn == 0) throw; // no pot
        if(pot.loser != 0) throw; // pot is over
        if(pot.players.length == 3) throw; // pot is full but waiting for a loser
        if(msg.value != pot.buyIn) throw; // must bet buyin amount

        pot.players.push(msg.sender);
        if(pot.players.length == 3){
           pot.lastPlayerBlockNumber = block.number;
        }
    }

    /*function leavePot(string name) {
        Pot pot = nameToPot[name];
        if(pot.buyIn == 0) throw; // no pot
        if(pot.loser != 0) throw; // pot is over
        if(pot.players.length == 3) throw; // pot is full but waiting for a loser

        if(pot.players[0] != msg.sender && pot.players[1] != msg.sender) throw; // no such player in pot

        address[] newPlayers;
        for(uint i = 0; i < pot.players.length; i++){
            if(pot.players[i] != msg.sender){
                newPlayers.push(pot.players[i]);
            }
        }

        pot.players = newPlayers;

        msg.sender.send((pot.buyIn * 99) / 100); // leaving fee 1%
    }*/

    function solvePot(string name){
        Pot pot = nameToPot[name];
        if(pot.loser != 0) throw; // pot is over
        if(pot.players.length < 3) throw; // pot not full
        if(block.number <= pot.lastPlayerBlockNumber) throw;

        bytes32 blockHash = block.blockhash(pot.lastPlayerBlockNumber + 1);
        if(blockHash == 0) { // pot expired due to hash storage limits - players didn't solve pot
            pot.loser = msg.sender; // doesn't matter, everybody loses a fee

            for(uint i = 0; i < pot.players.length; i++){
                pot.players[i].send((pot.buyIn * 99) / 100); // return money minus 1% fee
            }

            return;
        }

        bytes32 potShaResult = sha3(msg.sender, blockHash);
        uint8 loserIndex = uint8(uint256(potShaResult) % 3);

        address winner1 = pot.players[(loserIndex + 1) % 3];
        address winner2 = pot.players[(loserIndex + 2) % 3];

        uint winAmount = ((pot.buyIn * / 2) * 99) / 100;
        uint returnAmount = pot.buyIn + winAmount;

        winner1.send(returnAmount);
        winner2.send(returnAmount);
    }
}

pragma solidity ^0.4.0;
contract PotOfGold {

    struct Pot {
        string name;
        uint buyIn;

        address[] players;

        uint lastPlayerBlockNumber; // uint8(uint256(sha3(block.blockhash(lastJoinerBlockNumber+1)))) % 3 == loser index

        address loser;
    }

    address owner;

    Pot[] allPots;
    mapping(address => Pot[]) playerToPots;
    mapping(string => Pot) nameToPot;

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

    function ownerWithdraw(){
        if(msg.sender != owner) throw;

        int toWithdraw = this.balance - 100 finney; // leave 0.1 ether for gas (?)
        if(toWithdraw < 0) throw;

        owner.send(toWithdraw);
    }

    function getMyPots() constant returns (Pot[]){
        return playerToPots(msg.sender);
    }

    function getAllPots() constant returns (Pot[]){
        return allPots;
    }

    function getPot(string name) constant returns (Pot){
        return nameToPot[name];
    }

    function createPot(string name, uint buyIn) {
        if(buyIn == 0) throw; // must bet something
        if(bytes(name).length == 0) throw; // name mustn't be empty
        if(nameToPot[name].buyIn != 0) throw; // there's already a pot with this name

        Pot pot = nameToPot[name];
        pot.name = name;
        pot.buyIn = buyIn;
        pot.players.push(msg.sender);
        pot.buyIn = buyIn;

        allPots.push(pot);
        playerToPots[msg.sender].push(pot);
    }

    function joinPot(string name) {
        Pot pot = nameToPot[name];
        if(pot.buyIn == 0) throw; // no pot
        if(pot.loser != 0) throw; // pot is over
        if(pot.players.length == 3) throw; // pot is full but waiting for a loser
        if(msg.value != pot.buyIn) throw; // must bet buyin amount

        pot.players.push(msg.sender);
        if(pot.players.length == 3){
           pot.lastPlayerBlockNumber = block.number;
        }
    }

    function solvePot(string name){
        Pot pot = nameToPot[name];
        if(pot.loser != 0) throw; // pot is over
        if(pot.players.length < 3) throw; // pot not full
        if(block.number - 256 > pot.lastPlayerBlockNumber) throw; // pot expired - players didn't solve pot - money stays (this is due to hash storage limits - http://solidity.readthedocs.io/en/latest/units-and-global-variables.html#block-and-transaction-properties)
        if(block.number <= pot.lastPlayerBlockNumber) throw;

uint8(uint256(sha3(block.blockhash(lastJoinerBlockNumber+1)))) % 3 == loser index
    }
}


fix deploy contract

fix deploy contract

pragma solidity ^0.4.4;

contract Migrations {
  address public owner;
  uint public last_completed_migration;

  modifier restricted() {
    if (msg.sender == owner) _;
  }

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

  function setCompleted(uint completed) restricted {
    last_completed_migration = completed;
  }

  function upgrade(address new_address) restricted {
    Migrations upgraded = Migrations(new_address);
    upgraded.setCompleted(last_completed_migration);
  }
}

pragma solidity ^0.4.4;

contract Migrations {
  address public owner;
  uint public last_completed_migration;

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

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

  function setCompleted(uint completed) restricted {
    last_completed_migration = completed;
  }

  function upgrade(address new_address) restricted {
    Migrations upgraded = Migrations(new_address);
    upgraded.setCompleted(last_completed_migration);
  }
}


Use uint64 to save space and cost

Use uint64 to save space and cost

pragma solidity ^0.4.4;

contract PunchClock {
    // the owner of the contract
    address owner;

    // The data structure to store the time in and out of a person
    struct PunchCard {
        uint64 timeIn; // time the person gets in, unix timestamp
        uint64 timeOut; // time the person gets out, unix timestamp
    }

    // The list of all admins. The reason for having these two mapping is that
    // it's not possible to iterate through the list of keys in a mapping,
    // so the workaround is to have two mapping, with the second mapping is basically
    // just a map by index so that we can get all the keys. Similarly, it's not
    // possible to iterate through a mapping, so the workaround is to keep track
    // of the size manually.
    mapping(address => bool) admins;
    mapping(uint64 => address) adminsByIndex;
    uint64 totalNumberOfAdmins;

    // The list of all members.
    mapping(address => bool) members;
    mapping(uint64 => address) membersByIndex;
    uint64 totalNumberOfMembers;

    // All punch cards of all members
    mapping(address => PunchCard[]) punchClock;

    // Constructor, create a new punch clock and assign the creator as the owner of the punch clock
    function PunchClock() {
        owner = msg.sender;
        admins[owner] = true;
        adminsByIndex[0] = owner;
        totalNumberOfAdmins = 1;
        members[owner] = true;
        membersByIndex[0] = owner;
        totalNumberOfMembers = 1;
    }

    modifier onlyOwner() {
        if (msg.sender != owner) throw;
        _;
    }
    modifier onlyAdmins() {
        if (admins[msg.sender] == false) throw;
        _;
    }
    modifier onlyMembers() {
        if (members[msg.sender] == false) throw;
        _;
    }

    // Add a member to the contract if the member does not already exist
    function addMemberInternal(address member) internal {
        if (members[member] == false) {
            var newMemberIndex = totalNumberOfMembers;
            members[member] = true;
            membersByIndex[newMemberIndex] = member;
            totalNumberOfMembers++;
        }
    }
    // Add a new admin. Only the owner can perform this task.
    function addAdmin(address admin) onlyOwner {
        if (admins[admin] == false) {
            var indexOfNewAdmin = totalNumberOfAdmins;
            admins[admin] = true;
            adminsByIndex[indexOfNewAdmin] = admin;
            totalNumberOfAdmins++;

            addMemberInternal(admin);
        }
    }

    // Add a new member to the list of member. Only admins can perform this task
    function addMember(address member) onlyAdmins {
        addMemberInternal(member);
    }

    // Return all punch cards of a member
    function getPunchCardsInternal(address member) constant internal returns(uint64[2][]) {
        var allCards = punchClock[member];
        uint64[2][] memory tmp = new uint64[2][](allCards.length);
        for (uint64 i = 0; i < allCards.length; i++) {
            tmp[i] = [allCards[i].timeIn, allCards[i].timeOut];
        }
        return tmp;
    }

    // Return all punch cards of the requestor. Only member can perform this task
    function getMyPunchCards() onlyMembers constant returns(uint64[2][] punchCards) {
        return getPunchCardsInternal(msg.sender);
    }

    // Return all punch cards of a member. Only admin can perform this task
    function getPunchCardsOf(address member) onlyAdmins constant returns(uint64[2][] punchcards) {
        return getPunchCardsInternal(member);
    }

    // Return all members in the contract. Only admins can perform this task.
    function getAllMembers() onlyAdmins constant returns(address[]) {
        address[] memory allMembers = new address[](totalNumberOfMembers);
        for (uint64 i = 0; i < totalNumberOfMembers; i++) {
            allMembers[i] = membersByIndex[i];
        }
        return allMembers;
    }

    // Return all admins in the contract. Only owner can perform this task.
    function getAllAdmins() onlyOwner constant returns(address[]) {
        address[] memory allAdmins = new address[](totalNumberOfAdmins);
        for (uint64 i = 0; i < totalNumberOfAdmins; i++) {
            allAdmins[i] = adminsByIndex[i];
        }
        return allAdmins;
    }

    // Return the owner of the contract. Anyone can perform this task.
    function getOwner() constant returns(address) {
        return owner;
    }

    // Helper function to get the last element in an array
    function getLast(PunchCard[] punchCards) constant internal returns(PunchCard) {
        return punchCards[punchCards.length - 1];
    }

    // Register an in time for a member. Only admins can perform this task.
    function punchIn(address member, uint64 inTime) onlyAdmins {
        // If the member does not exist, throw
        if (members[member] == false) throw;

        var allCards = punchClock[member];
        if (allCards.length > 0) {
            var lastCard = getLast(allCards);
            if (lastCard.timeOut == 0) {
                // remove the last card if it's incomplete. We'll replace it with a new one.
                punchClock[member].length = punchClock[member].length - 1;
            }
        }

        punchClock[member].push(
            PunchCard({
            timeIn: inTime,
            timeOut: 0
        })
        );
    }

    // Register an out time for a member. Only admins can perform this task.
    function punchOut(address member, uint64 outTime) onlyAdmins {
        // If the member does not exist, throw
        if (members[member] == false) throw;

        var allCards = punchClock[member];
        if (allCards.length == 0) throw;
        var lastCard = getLast(allCards);
        if (lastCard.timeOut != 0) throw;
        // Remove the last card and replace it with a new one
        punchClock[member].length = punchClock[member].length - 1;
        //lastCard.timeOut = outTime;
        punchClock[member].push(
            PunchCard({
            timeIn: lastCard.timeIn,
            timeOut: outTime
        })
        );
    }

    // Remove an admin. Only owner can perform this task.
    function removeAdmin(address admin) onlyOwner {
        if (admins[admin] == true) {
            admins[admin] = false;
            members[admin] = false;
        }
    }

    // Remove a member. Only admin can perform this task.
    function removeMember(address member) onlyAdmins {
        if (members[member] == true) {
            members[member] = false;
        }
    }

    // Check if a certain person is a member
    function isMember(address person) constant returns(bool) {
        return members[person];
    }

    // Check if a certain person is an admin
    function isAdmin(address person) constant returns(bool) {
        return admins[person];
    }

    // Change the owner to another person. Only owner can perform this task.
    function changeOwner(address newOwner) onlyOwner {
        owner = newOwner;
    }

    // Kill the contract
    function destroy() onlyOwner {
        suicide(owner);
    }

    // TODO: publish events

    // TODO: batch adding
    // function addAdmins(address[] admins) onlyOwner
    // function addMembers(address[] members) onlyAdmins

    // TODO: batch punching
    //  function batchPunchIn(address[] members,  uint64[] inTimes) onlyAdmins
    //  function batchPunchOut(address[] members,  uint64[] outTimes) onlyAdmins
}

pragma solidity ^0.4.4;

contract PunchClock {
    // the owner of the contract
    address owner;

    // The data structure to store the time in and out of a person
    struct PunchCard {
        uint timeIn; // time the person gets in, unix timestamp
        uint timeOut; // time the person gets out, unix timestamp
    }

    // The list of all admins. The reason for having these two mapping is that
    // it's not possible to iterate through the list of keys in a mapping,
    // so the workaround is to have two mapping, with the second mapping is basically
    // just a map by index so that we can get all the keys. Similarly, it's not
    // possible to iterate through a mapping, so the workaround is to keep track
    // of the size manually.
    mapping(address => bool) admins;
    mapping(uint => address) adminsByIndex;
    uint totalNumberOfAdmins;

    // The list of all members.
    mapping(address => bool) members;
    mapping(uint => address) membersByIndex;
    uint totalNumberOfMembers;

    // All punch cards of all members
    mapping(address => PunchCard[]) punchClock;

    // Constructor, create a new punch clock and assign the creator as the owner of the punch clock
    function PunchClock() {
        owner = msg.sender;
        admins[owner] = true;
        adminsByIndex[0] = owner;
        totalNumberOfAdmins = 1;
        members[owner] = true;
        membersByIndex[0] = owner;
        totalNumberOfMembers = 1;
    }

    modifier onlyOwner() {
        if (msg.sender != owner) throw;
        _;
    }
    modifier onlyAdmins() {
        if (admins[msg.sender] == false) throw;
        _;
    }
    modifier onlyMembers() {
        if (members[msg.sender] == false) throw;
        _;
    }

    // Add a member to the contract if the member does not already exist
    function addMemberInternal(address member) internal {
        if (members[member] == false) {
            var newMemberIndex = totalNumberOfMembers;
            members[member] = true;
            membersByIndex[newMemberIndex] = member;
            totalNumberOfMembers++;
        }
    }
    // Add a new admin. Only the owner can perform this task.
    function addAdmin(address admin) onlyOwner {
        if (admins[admin] == false) {
            var indexOfNewAdmin = totalNumberOfAdmins;
            admins[admin] = true;
            adminsByIndex[indexOfNewAdmin] = admin;
            totalNumberOfAdmins++;

            addMemberInternal(admin);
        }
    }

    // Add a new member to the list of member. Only admins can perform this task
    function addMember(address member) onlyAdmins {
        addMemberInternal(member);
    }

    // Return all punch cards of a member
    function getPunchCardsInternal(address member) constant internal returns(uint[2][]) {
        var allCards = punchClock[member];
        uint[2][] memory tmp = new uint[2][](allCards.length);
        for (uint i = 0; i < allCards.length; i++) {
            tmp[i] = [allCards[i].timeIn, allCards[i].timeOut];
        }
        return tmp;
    }

    // Return all punch cards of the requestor. Only member can perform this task
    function getMyPunchCards() onlyMembers constant returns(uint[2][] punchCards) {
        return getPunchCardsInternal(msg.sender);
    }

    // Return all punch cards of a member. Only admin can perform this task
    function getPunchCardsOf(address member) onlyAdmins constant returns(uint[2][] punchcards) {
        return getPunchCardsInternal(member);
    }

    // Return all members in the contract. Only admins can perform this task.
    function getAllMembers() onlyAdmins constant returns(address[]) {
        address[] memory allMembers = new address[](totalNumberOfMembers);
        for (uint i = 0; i < totalNumberOfMembers; i++) {
            allMembers[i] = membersByIndex[i];
        }
        return allMembers;
    }

    // Return all admins in the contract. Only owner can perform this task.
    function getAllAdmins() onlyOwner constant returns(address[]) {
        address[] memory allAdmins = new address[](totalNumberOfAdmins);
        for (uint i = 0; i < totalNumberOfAdmins; i++) {
            allAdmins[i] = adminsByIndex[i];
        }
        return allAdmins;
    }

    // Return the owner of the contract. Anyone can perform this task.
    function getOwner() constant returns(address) {
        return owner;
    }

    // Helper function to get the last element in an array
    function getLast(PunchCard[] punchCards) constant internal returns(PunchCard) {
        return punchCards[punchCards.length - 1];
    }

    // Register an in time for a member. Only admins can perform this task.
    function punchIn(address member, uint inTime) onlyAdmins {
        // If the member does not exist, throw
        if (members[member] == false) throw;

        var allCards = punchClock[member];
        if (allCards.length > 0) {
            var lastCard = getLast(allCards);
            if (lastCard.timeOut == 0) {
                // remove the last card if it's incomplete. We'll replace it with a new one.
                punchClock[member].length = punchClock[member].length - 1;
            }
        }

        punchClock[member].push(
            PunchCard({
            timeIn: inTime,
            timeOut: 0
        })
        );
    }

    // Register an out time for a member. Only admins can perform this task.
    function punchOut(address member, uint outTime) onlyAdmins {
        // If the member does not exist, throw
        if (members[member] == false) throw;

        var allCards = punchClock[member];
        if (allCards.length == 0) throw;
        var lastCard = getLast(allCards);
        if (lastCard.timeOut != 0) throw;
        // Remove the last card and replace it with a new one
        punchClock[member].length = punchClock[member].length - 1;
        //lastCard.timeOut = outTime;
        punchClock[member].push(
            PunchCard({
            timeIn: lastCard.timeIn,
            timeOut: outTime
        })
        );
    }

    // Remove an admin. Only owner can perform this task.
    function removeAdmin(address admin) onlyOwner {
        if (admins[admin] == true) {
            admins[admin] = false;
            members[admin] = false;
        }
    }

    // Remove a member. Only admin can perform this task.
    function removeMember(address member) onlyAdmins {
        if (members[member] == true) {
            members[member] = false;
        }
    }

    // Check if a certain person is a member
    function isMember(address person) constant returns(bool) {
        return members[person];
    }

    // Check if a certain person is an admin
    function isAdmin(address person) constant returns(bool) {
        return admins[person];
    }

    // Change the owner to another person. Only owner can perform this task.
    function changeOwner(address newOwner) onlyOwner {
        owner = newOwner;
    }

    // Kill the contract
    function destroy() onlyOwner {
        suicide(owner);
    }

    // TODO: change owner
    // TODO: publish events

    // TODO: batch adding
    // function addAdmins(address[] admins) onlyOwner
    // function addMembers(address[] members) onlyAdmins

    // TODO: batch punching
    //  function batchPunchIn(address[] members,  uint[] inTimes) onlyAdmins
    //  function batchPunchOut(address[] members,  uint[] outTimes) onlyAdmins
}


Update TokenReal.sol

Update TokenReal.sol

import './Token.sol';

contract TokenReal is Token {
    uint8 public decimals;

    function TokenReal(string _name, string _symbol, uint _count, uint8 _decimals)
        Token(_name, _symbol, _count)
    { decimals = _decimals; }
}

import './Token.sol';

contract TokenReal is Token {
    uint8 public decimals;

    function TokenReal(string _name, string _symbol, uint _count, uint _decimals)
        Token(_name, _symbol, _count)
    { decimals = _decimals; }
}


include SPDX-License on AssertBytes32.sol

Getting a warning message when using the most recent compiler

"  truffle/AssertBytes32.sol: Warning: SPDX license identifier not provided in source file. Before publishing, consider adding a comment containing "SPDX-License-Identifier: <SPDX-License>" to each source file. Use "SPDX-License-Identifier: UNLICENSED" for non-open-source codeontaining "SPDX-License-Identifier: <SPDX-License>" to each so. Please see https://spdx.org for more information."

//SPDX-License-Identifier: MIT

pragma solidity >= 0.4.15 < 0.8.0;

library AssertBytes32 {

    // Constant: BYTES32_NULL
    // The null bytes32: 0
    bytes32 constant BYTES32_NULL = 0x0;

    byte constant MINUS = byte('-');

    /*
        Event: TestEvent

        Fired when an assertion is made.

        Params:
            result (bool) - Whether or not the assertion holds.
            message (string) - A message to display if the assertion does not hold.
    */
    event TestEvent(bool indexed result, string message);

    // ************************************** bytes32 **************************************

    /*
        Function: equal(bytes32)

        Assert that two 'bytes32' are equal.

        : A == B

        Params:
            A (bytes32) - The first 'bytes32'.
            B (bytes32) - The second 'bytes32'.
            message (string) - A message that is sent if the assertion fails.

        Returns:
            result (bool) - The result.
    */
    function equal(bytes32 a, bytes32 b, string memory message) public returns (bool result) {
        result = (a == b);
        _report(result, message);
    }

    /*
        Function: notEqual(bytes32)

        Assert that two 'bytes32' are not equal.

        : A != B

        Params:
            A (bytes32) - The first 'bytes32'.
            B (bytes32) - The second 'bytes32'.
            message (string) - A message that is sent if the assertion fails.

        Returns:
            result (bool) - The result.
    */
    function notEqual(bytes32 a, bytes32 b, string memory message) public returns (bool result) {
        result = (a != b);
        _report(result, message);
    }

    /*
        Function: isZero(bytes32)

        Assert that a 'bytes32' is zero.

        : bts == BYTES32_NULL

        Params:
            bts (bytes32) - The 'bytes32'.
            message (string) - A message that is sent if the assertion fails.

        Returns:
            result (bool) - The result.
    */
    function isZero(bytes32 bts, string memory message) public returns (bool result) {
        result = (bts == BYTES32_NULL);
        _report(result, message);
    }

    /*
        Function: isNotZero(bytes32)

        Assert that a 'bytes32' is not zero.

        : bts != BYTES32_NULL

        Params:
            bts (bytes32) - The 'bytes32'.
            message (string) - A message that is sent if the assertion fails.

        Returns:
            result (bool) - The result.
    */
    function isNotZero(bytes32 bts, string memory message) public returns (bool result) {
        result = (bts != BYTES32_NULL);
        _report(result, message);
    }

    /******************************** internal ********************************/

        /*
            Function: _report

            Internal function for triggering <TestEvent>.

            Params:
                result (bool) - The test result (true or false).
                message (string) - The message that is sent if the assertion fails.
        */
    function _report(bool result, string memory message) internal {
        if(result)
            emit TestEvent(true, "");
        else
            emit TestEvent(false, message);
    }

}


Changes throw to revert() for Metropolis compatibility

pragma solidity ^0.4.11;

contract Dgp {

    struct Client {
        uint256 startTime;
        uint256 lastRedemptionBlock;
        uint256 checkingBalance;
        uint256 depositedEndowments;
        uint256 endowmentTotal;
    }
    address public admin;
    uint256 public accountBalance;
    uint256 public allocated;
    uint256 public constant redemptionFrequency = 7; //7 days
    uint256 public constant redemptionAmt = 7000; //DUST (in cents)

    mapping (address => uint256) public vendorBalances;
    mapping (address => Client) public clients;

    // events
    event Donation(uint256 _value);
    event CheckingDeposit(address indexed _to, uint256 _value);
    event Endowment(address indexed _to, uint256 _value);
    event RemoveClient(address indexed _removed, uint256 _value);
    event Purchase(address indexed _client, address indexed _vendor, uint256 _value);
    event Refund(address indexed _vendor, address _client, uint256 _value);
    event Redemption(address indexed _vendor, uint256 _value);

    //access control
	modifier onlyAdmin {
		if (msg.sender != admin)  revert();
		_;
	}
	modifier onlyClient {
		if (clients[msg.sender].startTime == 0)  revert();
		_;
	}
	modifier onlyVendorWithBalance {
		if (vendorBalances[msg.sender] == 0)  revert();
		_;
	}

        // constructor
    function Dgp()
    {
      admin = msg.sender;
    }
    function registerDonation(uint256 _donationAmt) onlyAdmin() {
        accountBalance += _donationAmt;
        Donation(_donationAmt);
    }

    function registerClient(address _clientAddress, uint256 _endowmentTotal, uint256 _startTime) onlyAdmin() {
        //never allocate more than account balance
        if (_endowmentTotal <= 0) revert();
        if (_endowmentTotal + allocated > accountBalance) revert();
        if (clients[_clientAddress].endowmentTotal > 0) revert();
        //TODO use safeAdd?
        allocated += _endowmentTotal;
        clients[_clientAddress].checkingBalance = 0;
        clients[_clientAddress].endowmentTotal = _endowmentTotal;
        clients[_clientAddress].startTime = _startTime == 0 ? now : _startTime;
        clients[_clientAddress].lastRedemptionBlock = 0;
        if (_endowmentTotal > 0) Endowment(_clientAddress, _endowmentTotal);

    }
    //Used by admin to give immediately vested DUST to client
    function depositChecking(address _clientAddress, uint256 _amount) onlyAdmin() external {
        if (clients[_clientAddress].endowmentTotal == 0) revert();
        if (allocated + _amount > accountBalance) revert();
        allocated += _amount;
        clients[_clientAddress].checkingBalance += _amount;
        CheckingDeposit(_clientAddress, _amount);
    }
    function endow(address _clientAddress, uint256 _amount) onlyAdmin() external {
        if (clients[_clientAddress].endowmentTotal == 0) revert();
        if (allocated + _amount > accountBalance) revert();
        allocated += _amount;
        clients[_clientAddress].endowmentTotal += _amount;
        Endowment(_clientAddress, _amount);
    }
    function removeClient(address _clientAddress) onlyAdmin() external {
        if (clients[_clientAddress].endowmentTotal == 0) revert();
        uint256 clientFunds = clients[_clientAddress].checkingBalance +
         clients[_clientAddress].endowmentTotal - clients[_clientAddress].depositedEndowments;

        allocated -= clientFunds;

        RemoveClient(_clientAddress, clientFunds);
        delete clients[_clientAddress];
    }
    function getVested(address _clientAddress) constant returns(uint256 vested) {
        if (clients[_clientAddress].endowmentTotal == 0) revert();
        uint256 endowmentDuration = (now - clients[_clientAddress].startTime);
        uint256 earnedEndowments = endowmentDuration / (redemptionFrequency * 1 days);
        return (earnedEndowments * redemptionAmt - clients[_clientAddress].depositedEndowments);
    }
    function getCheckingBalance(address _clientAddress) constant external returns(uint256 checkingBalance) {
        if (clients[_clientAddress].endowmentTotal == 0) revert();
        checkingBalance = getVested(_clientAddress) + clients[_clientAddress].checkingBalance;
    }

    //Returns a virtual savings account balance, i.e. that which has been endowed but that can't be spent, maybe call it TrustBalance?
    function getSavingsBalance(address _clientAddress) constant external returns(uint256 savingsBalance) {
        if (clients[_clientAddress].endowmentTotal == 0) revert();
        savingsBalance = clients[_clientAddress].endowmentTotal -
        getVested(_clientAddress) - clients[_clientAddress].depositedEndowments;
    }

    function makePurchase(address _vendorAddress, uint256 amount) onlyClient() external  {
        //TODO validate vendor, is it necessary?
        uint256 vested = getVested(msg.sender);
        if (vested + clients[msg.sender].checkingBalance < amount) revert();
        clients[msg.sender].depositedEndowments += vested;
        clients[msg.sender].checkingBalance += vested-amount;
        vendorBalances[_vendorAddress] += amount;
        Purchase(msg.sender, _vendorAddress, amount);
    }
    function refundClient(address _clientAddress, uint256 amount) onlyVendorWithBalance() external {
        if (vendorBalances[msg.sender] < amount) revert();
        clients[_clientAddress].checkingBalance += amount;
        Refund(msg.sender,_clientAddress,amount);
    }

    function makePurchaseForClient(address _vendorAddress, address _clientAddress, uint256 amount)
       onlyAdmin() external {
        uint256 vested = getVested(_clientAddress);
        if (vested + clients[_clientAddress].checkingBalance < amount) revert();
        clients[_clientAddress].depositedEndowments += vested;
        clients[_clientAddress].checkingBalance += vested-amount;
        vendorBalances[_vendorAddress] += amount;
        Purchase(_clientAddress, _vendorAddress, amount);
    }

    function redeemPurchases() onlyVendorWithBalance() external {

        uint256 balance = vendorBalances[msg.sender];
        vendorBalances[msg.sender] = 0;
        accountBalance -= balance;
        allocated -= balance;
        Redemption(msg.sender,balance);

    }
    function redeemPurchasesForVendor(address _vendorAddress) onlyAdmin() external {

        uint256 balance = vendorBalances[_vendorAddress];
        vendorBalances[_vendorAddress] = 0;
        accountBalance -= balance;
        allocated -= balance;
        Redemption(_vendorAddress,balance);
    }

}

pragma solidity ^0.4.11;

contract Dgp {

    struct Client {
        uint256 startTime;
        uint256 lastRedemptionBlock;
        uint256 checkingBalance;
        uint256 depositedEndowments;
        uint256 endowmentTotal;
    }
    address public admin;
    uint256 public accountBalance;
    uint256 public allocated;
    uint256 public constant redemptionFrequency = 7; //7 days
    uint256 public constant redemptionAmt = 7000; //DUST (in cents)

    mapping (address => uint256) public vendorBalances;
    mapping (address => Client) public clients;

    // events
    event Donation(uint256 _value);
    event CheckingDeposit(address indexed _to, uint256 _value);
    event Endowment(address indexed _to, uint256 _value);
    event RemoveClient(address indexed _removed, uint256 _value);
    event Purchase(address indexed _client, address indexed _vendor, uint256 _value);
    event Refund(address indexed _vendor, address _client, uint256 _value);
    event Redemption(address indexed _vendor, uint256 _value);

    //access control
	modifier onlyAdmin {
		if (msg.sender != admin)  throw;
		_;
	}
	modifier onlyClient {
		if (clients[msg.sender].startTime == 0)  throw;
		_;
	}
	modifier onlyVendorWithBalance {
		if (vendorBalances[msg.sender] == 0)  throw;
		_;
	}

        // constructor
    function Dgp()
    {
      admin = msg.sender;
    }
    function registerDonation(uint256 _donationAmt) onlyAdmin() {
        accountBalance += _donationAmt;
        Donation(_donationAmt);
    }

    function registerClient(address _clientAddress, uint256 _endowmentTotal, uint256 _startTime) onlyAdmin() {
        //never allocate more than account balance
        if (_endowmentTotal <= 0) throw;
        if (_endowmentTotal + allocated > accountBalance) throw;
        if (clients[_clientAddress].endowmentTotal > 0) throw;
        //TODO use safeAdd?
        allocated += _endowmentTotal;
        clients[_clientAddress].checkingBalance = 0;
        clients[_clientAddress].endowmentTotal = _endowmentTotal;
        clients[_clientAddress].startTime = _startTime == 0 ? now : _startTime;
        clients[_clientAddress].lastRedemptionBlock = 0;
        if (_endowmentTotal > 0) Endowment(_clientAddress, _endowmentTotal);

    }
    //Used by admin to give immediately vested DUST to client
    function depositChecking(address _clientAddress, uint256 _amount) onlyAdmin() external {
        if (clients[_clientAddress].endowmentTotal == 0) throw;
        if (allocated + _amount > accountBalance) throw;
        allocated += _amount;
        clients[_clientAddress].checkingBalance += _amount;
        CheckingDeposit(_clientAddress, _amount);
    }
    function endow(address _clientAddress, uint256 _amount) onlyAdmin() external {
        if (clients[_clientAddress].endowmentTotal == 0) throw;
        if (allocated + _amount > accountBalance) throw;
        allocated += _amount;
        clients[_clientAddress].endowmentTotal += _amount;
        Endowment(_clientAddress, _amount);
    }
    function removeClient(address _clientAddress) onlyAdmin() external {
        if (clients[_clientAddress].endowmentTotal == 0) throw;
        uint256 clientFunds = clients[_clientAddress].checkingBalance +
         clients[_clientAddress].endowmentTotal - clients[_clientAddress].depositedEndowments;

        allocated -= clientFunds;

        RemoveClient(_clientAddress, clientFunds);
        delete clients[_clientAddress];
    }
    function getVested(address _clientAddress) constant returns(uint256 vested) {
        if (clients[_clientAddress].endowmentTotal == 0) throw;
        uint256 endowmentDuration = (now - clients[_clientAddress].startTime);
        uint256 earnedEndowments = endowmentDuration / (redemptionFrequency * 1 days);
        return (earnedEndowments * redemptionAmt - clients[_clientAddress].depositedEndowments);
    }
    function getCheckingBalance(address _clientAddress) constant external returns(uint256 checkingBalance) {
        if (clients[_clientAddress].endowmentTotal == 0) throw;
        checkingBalance = getVested(_clientAddress) + clients[_clientAddress].checkingBalance;
    }

    //Returns a virtual savings account balance, i.e. that which has been endowed but that can't be spent, maybe call it TrustBalance?
    function getSavingsBalance(address _clientAddress) constant external returns(uint256 savingsBalance) {
        if (clients[_clientAddress].endowmentTotal == 0) throw;
        savingsBalance = clients[_clientAddress].endowmentTotal -
        getVested(_clientAddress) - clients[_clientAddress].depositedEndowments;
    }

    function makePurchase(address _vendorAddress, uint256 amount) onlyClient() external  {
        //TODO validate vendor, is it necessary?
        uint256 vested = getVested(msg.sender);
        if (vested + clients[msg.sender].checkingBalance < amount) throw;
        clients[msg.sender].depositedEndowments += vested;
        clients[msg.sender].checkingBalance += vested-amount;
        vendorBalances[_vendorAddress] += amount;
        Purchase(msg.sender, _vendorAddress, amount);
    }
    function refundClient(address _clientAddress, uint256 amount) onlyVendorWithBalance() external {
        if (vendorBalances[msg.sender] < amount) throw;
        clients[_clientAddress].checkingBalance += amount;
        Refund(msg.sender,_clientAddress,amount);
    }

    function makePurchaseForClient(address _vendorAddress, address _clientAddress, uint256 amount)
       onlyAdmin() external {
        uint256 vested = getVested(_clientAddress);
        if (vested + clients[_clientAddress].checkingBalance < amount) throw;
        clients[_clientAddress].depositedEndowments += vested;
        clients[_clientAddress].checkingBalance += vested-amount;
        vendorBalances[_vendorAddress] += amount;
        Purchase(_clientAddress, _vendorAddress, amount);
    }

    function redeemPurchases() onlyVendorWithBalance() external {

        uint256 balance = vendorBalances[msg.sender];
        vendorBalances[msg.sender] = 0;
        accountBalance -= balance;
        allocated -= balance;
        Redemption(msg.sender,balance);

    }
    function redeemPurchasesForVendor(address _vendorAddress) onlyAdmin() external {

        uint256 balance = vendorBalances[_vendorAddress];
        vendorBalances[_vendorAddress] = 0;
        accountBalance -= balance;
        allocated -= balance;
        Redemption(_vendorAddress,balance);
    }

}