update sol

update sol

import "./owned.sol";
import "./localsCointoken.sol";

contract localsStore is owned {

  // Which tokencontract to use
  //MyToken public token;

  // the address of the tokencontract to use
  address public tokenaddr;

  // the address of the foundation to use
  address public foundation;

  event Log(string _log, address _newclub);
  event Error(string _error);
  event Allowance(string _msg, uint256 _balance);
  event ClubCreated(string _clubname, address _newClub, address _creator);

	function localsStore(address _tokenContract, address _foundationContract) {
		tokenaddr = _tokenContract;
    foundation = _foundationContract;
	}

	function createClub(string _nickname, string _clubname, string _clubicon, address _token)
		returns (address clubAddress)

	{
			// Create a new Token contract and return its address.
			// From the JavaScript side, the return type is simply
			// "address", as this is the closest type available in
			// the ABI.
      // the creator should pay localcoin to the localsfoundation
      // create an instance of the token contract
      var tokencontract = localsCointoken(tokenaddr);

      if(tokencontract.allowance(msg.sender,this)<200) {
        Error('LocalCoin allowance too low');
        throw;
        }

      Error('allowance check');
      /*Allowance('TEST ', token.allowance(msg.sender, this));*/

      tokencontract.transferFrom(msg.sender, foundation, 200);

      Error('localcoin transferred');
      //token.transfer(foundation, 200);

      clubAddress = new localsClub(msg.sender, _nickname, _clubicon, _clubname, _token);

      ClubCreated(_clubname, clubAddress, msg.sender);

      return clubAddress;

	}

  function createAssociation(uint _minimumQuorum, uint _debatingPeriodInMinutes, token _sharesTokenAddress) returns (address associationAddress) {

    var tokencontract = localsCointoken(tokenaddr);

    if(tokencontract.allowance(msg.sender,this)<200) {
      Error('LocalCoin allowance too low');
      throw;
      }

    Error('allowance check');
    /*Allowance('TEST ', token.allowance(msg.sender, this));*/

    tokencontract.transferFrom(msg.sender, foundation, 200);

    Error('localcoin transferred');
    //token.transfer(foundation, 200);

    associationAddress = new Association(_minimumQuorum, _debatingPeriodInMinutes, _sharesTokenAddress);

    ClubCreated('association', associationAddress, msg.sender);

    return associationAddress;

  }

  /* Kill function, for debug purposes (I don't want a mist wallet full of token contracts :) */
  function kill() { if (msg.sender == owner) suicide(owner); }

}

// Here we start the item contracts
contract localsClub {

	address public creator;
  string public clubname;
  string public clubicon;
  string public token;

  uint public numMembers;
  address[] public members;

	struct clubMember {
		string nickName;
		bool active;
	}

  event MemberAdded(string _clubname, string _nickName, address _newmember);
  event MemberDissed(string _clubname, address _newmember);

	mapping (address => clubMember) public clubMembers;

	function localsClub(address _creator, string _nickName, string _clubicon, string _clubname){
		creator = _creator;
    clubname = _clubname;
    clubicon = _clubicon;
		clubMembers[_creator].nickName = _nickName;
		clubMembers[_creator].active = true;
	}

	// Add a member to the club and make em active
	function addMember(address _newmember, string _nickName) {
    //if(msg.sender!=creator) throw;
    if(clubMembers[_newmember].active) throw;
		clubMembers[_newmember].nickName = _nickName;
		clubMembers[_newmember].active = true;
    members.push(_newmember);
    numMembers = members.length;
    MemberAdded(clubname, _nickName, _newmember);
	}

	// Set a member to active = false
	function disMember(address _newmember){
    if(msg.sender!=creator) throw;
		clubMembers[_newmember].active = false;
    MemberDissed(clubname, _newmember);
	}

  // When someone just sends value to the contract
  function () {
    throw;
  }

}

contract token { mapping (address => uint256) public balanceOf;  }

// Here we start an Association
/* The democracy contract itself */
contract Association is owned {

    /* Contract Variables and events */
    uint public minimumQuorum;
    uint public debatingPeriodInMinutes;
    Proposal[] public proposals;
    uint public numProposals;
    token public sharesTokenAddress;

    event ProposalAdded(uint proposalID, address recipient, uint amount, string description);
    event Voted(uint proposalID, bool position, address voter);
    event ProposalTallied(uint proposalID, int result, uint quorum, bool active);
    event ChangeOfRules(uint minimumQuorum, uint debatingPeriodInMinutes, address sharesTokenAddress);

    struct Proposal {
        address recipient;
        uint amount;
        string description;
        uint votingDeadline;
        bool executed;
        bool proposalPassed;
        uint numberOfVotes;
        bytes32 proposalHash;
        Vote[] votes;
        mapping (address => bool) voted;
    }

    struct Vote {
        bool inSupport;
        address voter;
    }

    /* modifier that allows only shareholders to vote and create new proposals */
    modifier onlyShareholders {
        if (sharesTokenAddress.balanceOf(msg.sender) == 0) throw;
        _
    }

    /* First time setup */
    function Association(token sharesAddress, uint minimumSharesToPassAVote, uint minutesForDebate) {
        changeVotingRules(sharesAddress, minimumSharesToPassAVote, minutesForDebate);
    }

    /*change rules*/
    function changeVotingRules(token sharesAddress, uint minimumSharesToPassAVote, uint minutesForDebate) onlyOwner {
        sharesTokenAddress = token(sharesAddress);
        if (minimumSharesToPassAVote == 0 ) minimumSharesToPassAVote = 1;
        minimumQuorum = minimumSharesToPassAVote;
        debatingPeriodInMinutes = minutesForDebate;
        ChangeOfRules(minimumQuorum, debatingPeriodInMinutes, sharesTokenAddress);
    }

    /* Function to create a new proposal */
    function newProposal(
        address beneficiary,
        uint etherAmount,
        string JobDescription,
        bytes transactionBytecode
    )
        onlyShareholders
        returns (uint proposalID)
    {
        proposalID = proposals.length++;
        Proposal p = proposals[proposalID];
        p.recipient = beneficiary;
        p.amount = etherAmount;
        p.description = JobDescription;
        p.proposalHash = sha3(beneficiary, etherAmount, transactionBytecode);
        p.votingDeadline = now + debatingPeriodInMinutes * 1 minutes;
        p.executed = false;
        p.proposalPassed = false;
        p.numberOfVotes = 0;
        ProposalAdded(proposalID, beneficiary, etherAmount, JobDescription);
        numProposals = proposalID+1;
    }

    /* function to check if a proposal code matches */
    function checkProposalCode(
        uint proposalNumber,
        address beneficiary,
        uint etherAmount,
        bytes transactionBytecode
    )
        constant
        returns (bool codeChecksOut)
    {
        Proposal p = proposals[proposalNumber];
        return p.proposalHash == sha3(beneficiary, etherAmount, transactionBytecode);
    }

    /* */
    function vote(uint proposalNumber, bool supportsProposal)
        onlyShareholders
        returns (uint voteID)
    {
        Proposal p = proposals[proposalNumber];
        if (p.voted[msg.sender] == true) throw;

        voteID = p.votes.length++;
        p.votes[voteID] = Vote({inSupport: supportsProposal, voter: msg.sender});
        p.voted[msg.sender] = true;
        p.numberOfVotes = voteID +1;
        Voted(proposalNumber,  supportsProposal, msg.sender);
    }

    function executeProposal(uint proposalNumber, bytes transactionBytecode) returns (int result) {
        Proposal p = proposals[proposalNumber];
        /* Check if the proposal can be executed */
        if (now < p.votingDeadline  /* has the voting deadline arrived? */
            ||  p.executed        /* has it been already executed? */
            ||  p.proposalHash != sha3(p.recipient, p.amount, transactionBytecode)) /* Does the transaction code match the proposal? */
            throw;

        /* tally the votes */
        uint quorum = 0;
        uint yea = 0;
        uint nay = 0;

        for (uint i = 0; i <  p.votes.length; ++i) {
            Vote v = p.votes[i];
            uint voteWeight = sharesTokenAddress.balanceOf(v.voter);
            quorum += voteWeight;
            if (v.inSupport) {
                yea += voteWeight;
            } else {
                nay += voteWeight;
            }
        }

        /* execute result */
        if (quorum <= minimumQuorum) {
            /* Not enough significant voters */
            throw;
        } else if (yea > nay ) {
            /* has quorum and was approved */
            p.recipient.call.value(p.amount * 1 ether)(transactionBytecode);
            p.executed = true;
            p.proposalPassed = true;
        } else {
            p.executed = true;
            p.proposalPassed = false;
        }
        // Fire Events
        ProposalTallied(proposalNumber, result, quorum, p.proposalPassed);
    }
}

import "./owned.sol";
import "./localsCointoken.sol";

contract localsStore is owned {

  // Which tokencontract to use
  //MyToken public token;

  // the address of the tokencontract to use
  address public tokenaddr;

  // the address of the foundation to use
  address public foundation;

  event Log(string _log, address _newclub);
  event Error(string _error);
  event Allowance(string _msg, uint256 _balance);
  event ClubCreated(string _clubname, address _newClub, address _creator);

	function localsStore(address _tokenContract, address _foundationContract) {
		tokenaddr = _tokenContract;
    foundation = _foundationContract;
	}

	function createClub(string _nickname, string _clubname, string _clubicon, address _token)
		returns (address clubAddress)

	{
			// Create a new Token contract and return its address.
			// From the JavaScript side, the return type is simply
			// "address", as this is the closest type available in
			// the ABI.
      // the creator should pay localcoin to the localsfoundation
      // create an instance of the token contract
      var tokencontract = localsCointoken(tokenaddr);

      if(tokencontract.allowance(msg.sender,this)<200) {
        Error('LocalCoin allowance too low');
        throw;
        }

      Error('allowance check');
      /*Allowance('TEST ', token.allowance(msg.sender, this));*/

      tokencontract.transferFrom(msg.sender, foundation, 200);

      Error('localcoin transferred');
      //token.transfer(foundation, 200);

      clubAddress = new localsClub(msg.sender, _nickname, _clubicon, _clubname, _token);

      ClubCreated(_clubname, clubAddress, msg.sender);

      return clubAddress;

	}

  function createAssociation(uint _minimumQuorum, uint _debatingPeriodInMinutes, token _sharesTokenAddress) returns address associationAddress {

    var tokencontract = localsCointoken(tokenaddr);

    if(tokencontract.allowance(msg.sender,this)<200) {
      Error('LocalCoin allowance too low');
      throw;
      }

    Error('allowance check');
    /*Allowance('TEST ', token.allowance(msg.sender, this));*/

    tokencontract.transferFrom(msg.sender, foundation, 200);

    Error('localcoin transferred');
    //token.transfer(foundation, 200);

    associationAddress = new Association(_minimumQuorum, _debatingPeriodInMinutes, _sharesTokenAddress);

    ClubCreated('association', associationAddress, msg.sender);

    return associationAddress;

  }

  /* Kill function, for debug purposes (I don't want a mist wallet full of token contracts :) */
  function kill() { if (msg.sender == owner) suicide(owner); }

}

contract token { mapping (address => uint256) public balanceOf;  }

// Here we start an Association
/* The democracy contract itself */
contract Association is owned {

    /* Contract Variables and events */
    uint public minimumQuorum;
    uint public debatingPeriodInMinutes;
    Proposal[] public proposals;
    uint public numProposals;
    token public sharesTokenAddress;

    event ProposalAdded(uint proposalID, address recipient, uint amount, string description);
    event Voted(uint proposalID, bool position, address voter);
    event ProposalTallied(uint proposalID, int result, uint quorum, bool active);
    event ChangeOfRules(uint minimumQuorum, uint debatingPeriodInMinutes, address sharesTokenAddress);

    struct Proposal {
        address recipient;
        uint amount;
        string description;
        uint votingDeadline;
        bool executed;
        bool proposalPassed;
        uint numberOfVotes;
        bytes32 proposalHash;
        Vote[] votes;
        mapping (address => bool) voted;
    }

    struct Vote {
        bool inSupport;
        address voter;
    }

    /* modifier that allows only shareholders to vote and create new proposals */
    modifier onlyShareholders {
        if (sharesTokenAddress.balanceOf(msg.sender) == 0) throw;
        _
    }

    /* First time setup */
    function Association(token sharesAddress, uint minimumSharesToPassAVote, uint minutesForDebate) {
        changeVotingRules(sharesAddress, minimumSharesToPassAVote, minutesForDebate);
    }

    /*change rules*/
    function changeVotingRules(token sharesAddress, uint minimumSharesToPassAVote, uint minutesForDebate) onlyOwner {
        sharesTokenAddress = token(sharesAddress);
        if (minimumSharesToPassAVote == 0 ) minimumSharesToPassAVote = 1;
        minimumQuorum = minimumSharesToPassAVote;
        debatingPeriodInMinutes = minutesForDebate;
        ChangeOfRules(minimumQuorum, debatingPeriodInMinutes, sharesTokenAddress);
    }

    /* Function to create a new proposal */
    function newProposal(
        address beneficiary,
        uint etherAmount,
        string JobDescription,
        bytes transactionBytecode
    )
        onlyShareholders
        returns (uint proposalID)
    {
        proposalID = proposals.length++;
        Proposal p = proposals[proposalID];
        p.recipient = beneficiary;
        p.amount = etherAmount;
        p.description = JobDescription;
        p.proposalHash = sha3(beneficiary, etherAmount, transactionBytecode);
        p.votingDeadline = now + debatingPeriodInMinutes * 1 minutes;
        p.executed = false;
        p.proposalPassed = false;
        p.numberOfVotes = 0;
        ProposalAdded(proposalID, beneficiary, etherAmount, JobDescription);
        numProposals = proposalID+1;
    }

    /* function to check if a proposal code matches */
    function checkProposalCode(
        uint proposalNumber,
        address beneficiary,
        uint etherAmount,
        bytes transactionBytecode
    )
        constant
        returns (bool codeChecksOut)
    {
        Proposal p = proposals[proposalNumber];
        return p.proposalHash == sha3(beneficiary, etherAmount, transactionBytecode);
    }

    /* */
    function vote(uint proposalNumber, bool supportsProposal)
        onlyShareholders
        returns (uint voteID)
    {
        Proposal p = proposals[proposalNumber];
        if (p.voted[msg.sender] == true) throw;

        voteID = p.votes.length++;
        p.votes[voteID] = Vote({inSupport: supportsProposal, voter: msg.sender});
        p.voted[msg.sender] = true;
        p.numberOfVotes = voteID +1;
        Voted(proposalNumber,  supportsProposal, msg.sender);
    }

    function executeProposal(uint proposalNumber, bytes transactionBytecode) returns (int result) {
        Proposal p = proposals[proposalNumber];
        /* Check if the proposal can be executed */
        if (now < p.votingDeadline  /* has the voting deadline arrived? */
            ||  p.executed        /* has it been already executed? */
            ||  p.proposalHash != sha3(p.recipient, p.amount, transactionBytecode)) /* Does the transaction code match the proposal? */
            throw;

        /* tally the votes */
        uint quorum = 0;
        uint yea = 0;
        uint nay = 0;

        for (uint i = 0; i <  p.votes.length; ++i) {
            Vote v = p.votes[i];
            uint voteWeight = sharesTokenAddress.balanceOf(v.voter);
            quorum += voteWeight;
            if (v.inSupport) {
                yea += voteWeight;
            } else {
                nay += voteWeight;
            }
        }

        /* execute result */
        if (quorum <= minimumQuorum) {
            /* Not enough significant voters */
            throw;
        } else if (yea > nay ) {
            /* has quorum and was approved */
            p.recipient.call.value(p.amount * 1 ether)(transactionBytecode);
            p.executed = true;
            p.proposalPassed = true;
        } else {
            p.executed = true;
            p.proposalPassed = false;
        }
        // Fire Events
        ProposalTallied(proposalNumber, result, quorum, p.proposalPassed);
    }

// Here we start the item contracts
contract localsClub {

	address public creator;
  string public clubname;
  string public clubicon;
  string public token;

  uint public numMembers;
  address[] public members;

	struct clubMember {
		string nickName;
		bool active;
	}

  event MemberAdded(string _clubname, string _nickName, address _newmember);
  event MemberDissed(string _clubname, address _newmember);

	mapping (address => clubMember) public clubMembers;

	function localsClub(address _creator, string _nickName, string _clubicon, string _clubname){
		creator = _creator;
    clubname = _clubname;
    clubicon = _clubicon;
		clubMembers[_creator].nickName = _nickName;
		clubMembers[_creator].active = true;
	}

	// Add a member to the club and make em active
	function addMember(address _newmember, string _nickName) {
    //if(msg.sender!=creator) throw;
    if(clubMembers[_newmember].active) throw;
		clubMembers[_newmember].nickName = _nickName;
		clubMembers[_newmember].active = true;
    members.push(_newmember);
    numMembers = members.length;
    MemberAdded(clubname, _nickName, _newmember);
	}

	// Set a member to active = false
	function disMember(address _newmember){
    if(msg.sender!=creator) throw;
		clubMembers[_newmember].active = false;
    MemberDissed(clubname, _newmember);
	}

  // When someone just sends value to the contract
  function () {
    throw;
  }

}


Add invariant checks to ensure that funds do not go missing

pragma solidity ^0.4.2;

// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

import "../../wealdtech-solidity/contracts/ens/ENSReverseRegister.sol";

// Interesting parts of the ENS deed
contract Deed {
    address public owner;
    address public previousOwner;
}

// Interesting parts of the ENS registry
contract Registry {
    function owner(bytes32 _hash) constant returns (address);
}

// Interesting parts of the ENS registrar
contract Registrar {
    function transfer(bytes32 _hash, address newOwner);
    function entries(bytes32 _hash) constant returns (uint, Deed, uint, uint, uint);
}

contract DomainSale is ENSReverseRegister {
    Registrar public registrar;
    mapping (string => Sale) private sales;
    mapping (address => uint256) private balances;

    // Auction parameters
    uint256 private constant AUCTION_DURATION = 24 hours;
    uint256 private constant HIGH_BID_KICKIN = 7 days;
    uint256 private constant NORMAL_BID_INCREASE_PERCENTAGE = 10;
    uint256 private constant HIGH_BID_INCREASE_PERCENTAGE = 50;

    // Distribution of the sale funds
    uint256 private constant SELLER_SALE_PERCENTAGE = 90;
    uint256 private constant START_REFERRER_SALE_PERCENTAGE = 5;
    uint256 private constant BID_REFERRER_SALE_PERCENTAGE = 5;

    // ENS
    string private constant CONTRACT_ENS = "domainsale.eth";
    // Hex is namehash("eth")
    bytes32 private constant NAMEHASH_ETH = 0x93cdeb708b7545dc668eb9280176169d1c33cfd8ed6f04690a0bcc88a93fc4ae;

    // Funds tracker.  Ensures we don't forget about any Ether
    // Funds held for sales (both buys and bids)
    uint256 private saleFunds = 0;
    // Funds pending withdrawal
    uint256 private withdrawalFunds = 0;

    struct Sale {
        // The lowest direct purchase price that will be accepted
        uint256 price;
        // The lowest auction bid that will be accepted
        uint256 reserve;
        // The last bid on the auction.  0 if no bid has been made
        uint256 lastBid;
        // The address of the last bider on the auction.  0 if no bid has been made
        address lastBidder;
        // The timestamp when this auction started
        uint256 auctionStarted;
        // The timestamp at which this auction ends
        uint256 auctionEnds;
        // The address of the referrer who started the sale
        address startReferrer;
        // The address of the referrer who supplied the winning bid
        address bidReferrer;
    }

    //
    // Events
    //

    // Sent when a name is offered (can occur multiple times if the seller
    // changes their prices)
    event Offer(address indexed seller, string name, uint256 price, uint256 reserve);
    // Sent when a bid is placed for a name
    event Bid(address indexed bidder, string name, uint256 bid);
    // Sent when a name is transferred to a new owner
    event Transfer(address indexed seller, address indexed buyer, string name, uint256 value);
    // Sent when a sale for a name is cancelled
    event Cancel(string name);

    //
    // Modifiers
    //

    // Actions that can only be undertaken by the seller of the name.
    // The owner of the name is this contract, so we use the previous
    // owner from the deed
    modifier onlyNameSeller(string _name) {
        Deed deed;
        (,deed,,,) = registrar.entries(sha3(_name));
        require(deed.owner() == address(this));
        require(deed.previousOwner() == msg.sender);
        _;
    }

    // It is possible for a name to be invalidated, in which case the
    // owner will be reset
    modifier deedValid(string _name) {
        address deed;
        (,deed,,,) = registrar.entries(sha3(_name));
        require(deed != 0);
        _;
    }

    // Actions that can only be undertaken if the name sale has attracted
    // no bids.
    modifier auctionNotStarted(string _name) {
        require(sales[_name].auctionStarted == 0);
        _;
    }

    // Allow if the name can be bid upon
    modifier canBid(string _name) {
        require(sales[_name].reserve != 0);
        _;
    }

    // Allow if the name can be purchased
    modifier canBuy(string _name) {
        require(sales[_name].price != 0);
        _;
    }

    // Payables add their value to the sales funds tracker
    modifier addSaleFunds(uint256 value) {
        saleFunds += value;
        _;
    }

    /**
     * @dev Constructor takes the address of the ENS registry
     */
    function DomainSale(address _registry) ENSReverseRegister(_registry, CONTRACT_ENS) {
        registrar = Registrar(Registry(_registry).owner(NAMEHASH_ETH));
    }

    //
    // Accessors for sales struct
    //

    /**
     * @dev return useful information from the sale structure in one go
     */
    function sale(string _name) public constant returns (uint256, uint256, uint256, address, uint256, uint256) {
        Sale storage s = sales[_name];
        return (s.price, s.reserve, s.lastBid, s.lastBidder, s.auctionStarted, s.auctionEnds);
    }

    /**
     * @dev a flag set if this name can be purchased through auction
     */
    function isAuction(string _name) public constant returns (bool) {
        return sales[_name].reserve != 0;
    }

    /**
     * @dev a flag set if this name can be purchased outright
     */
    function isBuyable(string _name) public constant returns (bool) {
        return sales[_name].price != 0;
    }

    /**
     * @dev a flag set if the auction has started
     */
    function auctionStarted(string _name) public constant returns (bool) {
        return sales[_name].lastBid != 0;
    }

    /**
     * @dev the time at which the auction ends
     */
    function auctionEnds(string _name) public constant returns (uint256) {
        return sales[_name].auctionEnds;
    }

    /**
     * @dev minimumBid is the greater of the minimum bid or the last bid + 10%.
     *      If an auction has been going longer than 7 days then it is the last
     *      bid + 50%.
     *      Throws if this sale does not accept bids
     */
    function minimumBid(string _name) public constant returns (uint256) {
        Sale storage s = sales[_name];

        if (s.auctionStarted == 0) {
            return s.reserve;
        } else if (s.auctionStarted + HIGH_BID_KICKIN > now) {
            return s.lastBid + s.lastBid * NORMAL_BID_INCREASE_PERCENTAGE / 100;
        } else {
            return s.lastBid + s.lastBid * HIGH_BID_INCREASE_PERCENTAGE / 100;
        }
    }

    /**
     * @dev price is the instant purchase price.
     *      Throws if this sale does not accept an instant purchase
     */
    function price(string _name) public constant returns (uint256) {
        Sale storage s = sales[_name];

        return s.price;
    }

    /**
     * @dev The balance available for withdrawal
     */
    function balance() public constant returns (uint256) {
        return balances[msg.sender];
    }

    //
    // Operations
    //

    /**
     * @dev offer a domain for sale.
     *      The price is the price at which a domain can be purchased directly.
     *      The reserve is the initial lowest price for which a bid can be made.
     */
    function offer(string _name, uint256 _price, uint256 reserve, address referrer) onlyNameSeller(_name) auctionNotStarted(_name) deedValid(_name) public {
        require(_price == 0 || _price > reserve);
        require(_price != 0 || reserve != 0);
        Sale storage s = sales[_name];
        s.reserve = reserve;
        s.price = _price;
        s.startReferrer = referrer;
        Offer(msg.sender, _name, _price, reserve);

        // Funds tracker invariant
        assert(saleFunds + withdrawalFunds == address(this).balance);
    }

    /**
     * @dev cancel a sale for a domain.
     *      This can only happen if there have been no bids for the name.
     */
    function cancel(string _name) onlyNameSeller(_name) auctionNotStarted(_name) deedValid(_name) public {
        registrar.transfer(sha3(_name), msg.sender);
        Cancel(_name);

        // Tidy up
        clearStorage(_name);

        // Funds tracker invariant
        assert(saleFunds + withdrawalFunds == address(this).balance);
    }

    /**
     * @dev buy a domain directly
     */
    function buy(string _name, address bidReferrer) canBuy(_name) deedValid(_name) addSaleFunds(msg.value) public payable {
        Sale storage s = sales[_name];
        require(msg.value >= s.price);
        require(s.auctionStarted == 0);

        // As we're here, return any funds that the sender is owed
        withdraw();

        // Obtain the previous owner from the deed
        Deed deed;
        (,deed,,,) = registrar.entries(sha3(_name));
        address previousOwner = deed.previousOwner();

        // Transfer the name
        registrar.transfer(sha3(_name), msg.sender);
        Transfer(previousOwner, msg.sender, _name, msg.value);

        // Distribute funds to referrers
        transferFunds(msg.value, previousOwner, s.startReferrer, bidReferrer);

        // Tidy up
        clearStorage(_name);

        // Funds tracker invariant
        require(saleFunds + withdrawalFunds == address(this).balance);
    }

    /**
     * @dev bid for a domain
     */
    function bid(string _name, address bidReferrer) canBid(_name) deedValid(_name) addSaleFunds(msg.value) public payable {
        require(msg.value >= minimumBid(_name));

        Sale storage s = sales[_name];
        require(s.auctionStarted == 0 || now < s.auctionEnds);

        // Update the balance for the outbid bidder
        balances[s.lastBidder] += s.lastBid;
        saleFunds -= s.lastBid;
        withdrawalFunds += s.lastBid;

        // As we're here, return any funds that the sender is owed
        withdraw();

        if (s.auctionStarted == 0) {
          // First bid; set the auction start
          s.auctionStarted = now;
        }
        s.lastBidder = msg.sender;
        s.lastBid = msg.value;
        s.auctionEnds = now + AUCTION_DURATION;
        s.bidReferrer = bidReferrer;
        Bid(msg.sender, _name, msg.value);

        // Funds tracker invariant
        assert(saleFunds + withdrawalFunds == address(this).balance);
    }

    /**
     * @dev finish an auction
     */
    function finish(string _name) deedValid(_name) public {
        Sale storage s = sales[_name];
        require(now > s.auctionEnds);

        // Obtain the previous owner from the deed
        Deed deed;
        (,deed,,,) = registrar.entries(sha3(_name));

        address previousOwner = deed.previousOwner();
        registrar.transfer(sha3(_name), s.lastBidder);
        Transfer(previousOwner, s.lastBidder, _name, s.lastBid);

        // Distribute funds to referrers
        transferFunds(s.lastBid, previousOwner, s.startReferrer, s.bidReferrer);

        clearStorage(_name);

        // Funds tracker invariant
        assert(saleFunds + withdrawalFunds == address(this).balance);
    }

    /**
     * @dev withdraw any owned balance
     */
    function withdraw() public {
        uint256 amount = balances[msg.sender];
        if (amount > 0) {
            balances[msg.sender] = 0;
            withdrawalFunds -= amount;
            msg.sender.transfer(amount);
        }
    }

    /**
     * @dev Invalidate an auction if the deed is no longer active
     */
    function invalidate(string _name) public {
        // Ensure the deed has been invalidated
        address deed;
        (,deed,,,) = registrar.entries(sha3(_name));
        require(deed == 0);

        Sale storage s = sales[_name];

        // Update the balance for the winning bidder
        balances[s.lastBidder] += s.lastBid;

        // As we're here, return any funds that the sender is owed
        withdraw();

        // Cancel the auction
        Cancel(_name);

        // Tidy up
        clearStorage(_name);

        // Funds tracker invariant
        assert(saleFunds + withdrawalFunds == address(this).balance);
    }

    //
    // Internal functions
    //

    /**
     * @dev Transfer funds for a sale to the relevant parties
     */
    function transferFunds(uint256 amount, address seller, address startReferrer, address bidReferrer) internal {
        seller.transfer(amount * SELLER_SALE_PERCENTAGE / 100);
        startReferrer.transfer(amount * START_REFERRER_SALE_PERCENTAGE / 100);
        bidReferrer.transfer(amount * BID_REFERRER_SALE_PERCENTAGE / 100);
        saleFunds -= amount;
    }

    /**
     * @dev Clear the storage for a name
     */
    function clearStorage(string _name) internal {
        // Clear name records
        sales[_name] = Sale({
            reserve: 0,
            price: 0,
            lastBid:0,
            lastBidder:0,
            auctionStarted:0,
            auctionEnds:0,
            startReferrer: 0,
            bidReferrer: 0
        });
    }
}

pragma solidity ^0.4.2;

// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

import "../../wealdtech-solidity/contracts/ens/ENSReverseRegister.sol";

// Interesting parts of the ENS deed
contract Deed {
    address public owner;
    address public previousOwner;
}

// Interesting parts of the ENS registry
contract Registry {
    function owner(bytes32 _hash) constant returns (address);
}

// Interesting parts of the ENS registrar
contract Registrar {
    function transfer(bytes32 _hash, address newOwner);
    function entries(bytes32 _hash) constant returns (uint, Deed, uint, uint, uint);
}

contract DomainSale is ENSReverseRegister {
    Registrar public registrar;
    mapping (string => Sale) private sales;
    mapping (address => uint256) private balances;

    // Auction parameters
    uint256 private constant AUCTION_DURATION = 24 hours;
    uint256 private constant HIGH_BID_KICKIN = 7 days;
    uint256 private constant NORMAL_BID_INCREASE_PERCENTAGE = 10;
    uint256 private constant HIGH_BID_INCREASE_PERCENTAGE = 50;

    // Distribution of the sale funds
    uint256 private constant SELLER_SALE_PERCENTAGE = 90;
    uint256 private constant START_REFERRER_SALE_PERCENTAGE = 5;
    uint256 private constant BID_REFERRER_SALE_PERCENTAGE = 5;

    // ENS
    string private constant CONTRACT_ENS = "domainsale.eth";
    // Hex is namehash("eth")
    bytes32 private constant NAMEHASH_ETH = 0x93cdeb708b7545dc668eb9280176169d1c33cfd8ed6f04690a0bcc88a93fc4ae;

    struct Sale {
        // The lowest direct purchase price that will be accepted
        uint256 price;
        // The lowest auction bid that will be accepted
        uint256 reserve;
        // The last bid on the auction.  0 if no bid has been made
        uint256 lastBid;
        // The address of the last bider on the auction.  0 if no bid has been made
        address lastBidder;
        // The timestamp when this auction started
        uint256 auctionStarted;
        // The timestamp at which this auction ends
        uint256 auctionEnds;
        // The address of the referrer who started the sale
        address startReferrer;
        // The address of the referrer who supplied the winning bid
        address bidReferrer;
    }

    //
    // Events
    //

    // Sent when a name is offered (can occur multiple times if the seller
    // changes their prices)
    event Offer(address indexed seller, string name, uint256 price, uint256 reserve);
    // Sent when a bid is placed for a name
    event Bid(address indexed bidder, string name, uint256 bid);
    // Sent when a name is transferred to a new owner
    event Transfer(address indexed seller, address indexed buyer, string name, uint256 value);
    // Sent when a sale for a name is cancelled
    event Cancel(string name);

    //
    // Modifiers
    //

    // Actions that can only be undertaken by the seller of the name.
    // The owner of the name is this contract, so we use the previous
    // owner from the deed
    modifier onlyNameSeller(string _name) {
        Deed deed;
        (,deed,,,) = registrar.entries(sha3(_name));
        require(deed.owner() == address(this));
        require(deed.previousOwner() == msg.sender);
        _;
    }

    // It is possible for a name to be invalidated, in which case the
    // owner will be reset
    modifier deedValid(string _name) {
        address deed;
        (,deed,,,) = registrar.entries(sha3(_name));
        require(deed != 0);
        _;
    }

    // Actions that can only be undertaken if the name sale has attracted
    // no bids.
    modifier auctionNotStarted(string _name) {
        require(sales[_name].auctionStarted == 0);
        _;
    }

    // Allow if the name can be bid upon
    modifier canBid(string _name) {
        require(sales[_name].reserve != 0);
        _;
    }

    // Allow if the name can be purchased
    modifier canBuy(string _name) {
        require(sales[_name].price != 0);
        _;
    }

    /**
     * @dev Constructor takes the address of the ENS registry
     */
    function DomainSale(address _registry) ENSReverseRegister(_registry, CONTRACT_ENS) {
        registrar = Registrar(Registry(_registry).owner(NAMEHASH_ETH));
    }

    //
    // Accessors for sales struct
    //

    /**
     * @dev return useful information from the sale structure in one go
     */
    function sale(string _name) public constant returns (uint256, uint256, uint256, address, uint256, uint256) {
        Sale storage s = sales[_name];
        return (s.price, s.reserve, s.lastBid, s.lastBidder, s.auctionStarted, s.auctionEnds);
    }

    /**
     * @dev a flag set if this name can be purchased through auction
     */
    function isAuction(string _name) public constant returns (bool) {
        return sales[_name].reserve != 0;
    }

    /**
     * @dev a flag set if this name can be purchased outright
     */
    function isBuyable(string _name) public constant returns (bool) {
        return sales[_name].price != 0;
    }

    /**
     * @dev a flag set if the auction has started
     */
    function auctionStarted(string _name) public constant returns (bool) {
        return sales[_name].lastBid != 0;
    }

    /**
     * @dev the time at which the auction ends
     */
    function auctionEnds(string _name) public constant returns (uint256) {
        return sales[_name].auctionEnds;
    }

    /**
     * @dev minimumBid is the greater of the minimum bid or the last bid + 10%.
     *      If an auction has been going longer than 7 days then it is the last
     *      bid + 50%.
     *      Throws if this sale does not accept bids
     */
    function minimumBid(string _name) public constant returns (uint256) {
        Sale storage s = sales[_name];

        if (s.auctionStarted == 0) {
            return s.reserve;
        } else if (s.auctionStarted + HIGH_BID_KICKIN > now) {
            return s.lastBid + s.lastBid * NORMAL_BID_INCREASE_PERCENTAGE / 100;
        } else {
            return s.lastBid + s.lastBid * HIGH_BID_INCREASE_PERCENTAGE / 100;
        }
    }

    /**
     * @dev price is the instant purchase price.
     *      Throws if this sale does not accept an instant purchase
     */
    function price(string _name) public constant returns (uint256) {
        Sale storage s = sales[_name];

        return s.price;
    }

    /**
     * @dev The balance available for withdrawal
     */
    function balance() public constant returns (uint256) {
        return balances[msg.sender];
    }

    //
    // Operations
    //

    /**
     * @dev offer a domain for sale.
     *      The price is the price at which a domain can be purchased directly.
     *      The reserve is the initial lowest price for which a bid can be made.
     */
    function offer(string _name, uint256 _price, uint256 reserve, address referrer) onlyNameSeller(_name) auctionNotStarted(_name) deedValid(_name) public {
        require(_price == 0 || _price > reserve);
        require(_price != 0 || reserve != 0);
        Sale storage s = sales[_name];
        s.reserve = reserve;
        s.price = _price;
        s.startReferrer = referrer;
        Offer(msg.sender, _name, _price, reserve);
    }

    /**
     * @dev cancel a sale for a domain.
     *      This can only happen if there have been no bids for the name.
     */
    function cancel(string _name) onlyNameSeller(_name) auctionNotStarted(_name) deedValid(_name) public {
        registrar.transfer(sha3(_name), msg.sender);
        Cancel(_name);

        // Tidy up
        clearStorage(_name);
    }

    /**
     * @dev buy a domain directly
     */
    function buy(string _name, address bidReferrer) canBuy(_name) deedValid(_name) public payable {
        Sale storage s = sales[_name];
        require(msg.value >= s.price);
        require(s.auctionStarted == 0);

        // As we're here, return any funds that the sender is owed
        withdraw();

        // Obtain the previous owner from the deed
        Deed deed;
        (,deed,,,) = registrar.entries(sha3(_name));
        address previousOwner = deed.previousOwner();

        // Transfer the name
        registrar.transfer(sha3(_name), msg.sender);
        Transfer(previousOwner, msg.sender, _name, msg.value);

        // Distribute funds to referrers
        transferFunds(msg.value, previousOwner, s.startReferrer, bidReferrer);

        // Tidy up
        clearStorage(_name);
    }

    /**
     * @dev bid for a domain
     */
    function bid(string _name, address bidReferrer) canBid(_name) deedValid(_name) public payable {
        require(msg.value >= minimumBid(_name));

        Sale storage s = sales[_name];
        require(s.auctionStarted == 0 || now < s.auctionEnds);

        // Update the balance for the outbid bidder
        balances[s.lastBidder] += s.lastBid;

        // As we're here, return any funds that the sender is owed
        withdraw();

        if (s.auctionStarted == 0) {
          // First bid; set the auction start
          s.auctionStarted = now;
        }
        s.lastBidder = msg.sender;
        s.lastBid = msg.value;
        s.auctionEnds = now + AUCTION_DURATION;
        s.bidReferrer = bidReferrer;
        Bid(msg.sender, _name, msg.value);
    }

    /**
     * @dev finish an auction
     */
    function finish(string _name) deedValid(_name) public {
        Sale storage s = sales[_name];
        require(now > s.auctionEnds);

        // Obtain the previous owner from the deed
        Deed deed;
        (,deed,,,) = registrar.entries(sha3(_name));

        address previousOwner = deed.previousOwner();
        registrar.transfer(sha3(_name), s.lastBidder);
        Transfer(previousOwner, s.lastBidder, _name, s.lastBid);

        // Distribute funds to referrers
        transferFunds(s.lastBid, previousOwner, s.startReferrer, s.bidReferrer);
        clearStorage(_name);
    }

    /**
     * @dev withdraw any owned balance
     */
    function withdraw() public {
        uint256 withdrawalAmount = balances[msg.sender];
        if (withdrawalAmount > 0) {
            balances[msg.sender] = 0;
            msg.sender.transfer(withdrawalAmount);
        }
    }

    /**
     * @dev Invalidate an auction if the deed is no longer active
     */
    function invalidate(string _name) public {
        // Ensure the deed has been invalidated
        address deed;
        (,deed,,,) = registrar.entries(sha3(_name));
        require(deed == 0);

        Sale storage s = sales[_name];

        // Update the balance for the winning bidder
        balances[s.lastBidder] += s.lastBid;

        // As we're here, return any funds that the sender is owed
        withdraw();

        // Cancel the auction
        Cancel(_name);

        // Tidy up
        clearStorage(_name);
    }

    //
    // Internal functions
    //

    /**
     * @dev Transfer funds for a sale to the relevant parties
     */
    function transferFunds(uint256 amount, address seller, address startReferrer, address bidReferrer) internal {
        seller.transfer(amount * SELLER_SALE_PERCENTAGE / 100);
        startReferrer.transfer(amount * START_REFERRER_SALE_PERCENTAGE / 100);
        bidReferrer.transfer(amount * BID_REFERRER_SALE_PERCENTAGE / 100);
    }

    /**
     * @dev Clear the storage for a name
     */
    function clearStorage(string _name) internal {
        // Clear name records
        sales[_name] = Sale({
            reserve: 0,
            price: 0,
            lastBid:0,
            lastBidder:0,
            auctionStarted:0,
            auctionEnds:0,
            startReferrer: 0,
            bidReferrer: 0
        });
    }
}


Test updateLatestRevision()

Test updateLatestRevision()

pragma solidity ^0.4.2;

import "dapple/test.sol";
import "blobstore.sol";
import "blobstore_flags.sol";

/**
 * @title BlobStoreTest
 * @author Jonathan Brown <jbrown@bluedroplet.com>
 */
contract BlobStoreTest is Test, BlobStoreFlags {

    BlobStoreRegistry blobStoreRegistry;
    BlobStore blobStore;

    function setUp() {
        blobStoreRegistry = new BlobStoreRegistry();
        blobStore = new BlobStore(blobStoreRegistry);
    }

    function testThrowRegisterContractAgain() {
        blobStoreRegistry.register(blobStore.getContractId());
    }

    function testThrowBlobStoreNotRegistered() {
        blobStoreRegistry.getBlobStore(0);
    }

    function testBlobStoreRegistered() {
        assertEq(blobStoreRegistry.getBlobStore(blobStore.getContractId()), blobStore);
    }

    function testThrowCreateExistingNonce() {
        blobStore.create(0, hex"00");
        blobStore.create(0, hex"00");
    }

    function testCreate() {
        bytes20 blobId0 = blobStore.create(0, hex"00");
        assertTrue(blobStore.getExists(blobId0));
        assertEq(blobStore.getOwner(blobId0), this);
        assertEq(blobStore.getRevisionCount(blobId0), 1);
        assertFalse(blobStore.getUpdatable(blobId0));
        assertFalse(blobStore.getEnforceRevisions(blobId0));
        assertFalse(blobStore.getRetractable(blobId0));
        assertFalse(blobStore.getTransferable(blobId0));

        bytes20 blobId1 = blobStore.create(FLAG_UPDATABLE | FLAG_ENFORCE_REVISIONS | FLAG_RETRACTABLE | FLAG_TRANSFERABLE | FLAG_ANONYMOUS, hex"00");
        assertTrue(blobStore.getExists(blobId1));
        assertEq(blobStore.getOwner(blobId1), 0);
        assertEq(blobStore.getRevisionCount(blobId1), 1);
        assertTrue(blobStore.getUpdatable(blobId1));
        assertTrue(blobStore.getEnforceRevisions(blobId1));
        assertTrue(blobStore.getRetractable(blobId1));
        assertTrue(blobStore.getTransferable(blobId1));

        assertFalse(blobId0 == blobId1);
    }

    function testThrowsCreateNewRevisionNotUpdatable() {
        bytes20 blobId = blobStore.create(0, hex"00");
        blobStore.createNewRevision(blobId, hex"00");
    }

    function testCreateNewRevision() {
        bytes20 blobId = blobStore.create(FLAG_UPDATABLE, hex"00");
        uint revisionId = blobStore.createNewRevision(blobId, hex"00");
        assertEq(revisionId, 1);
        assertEq(blobStore.getRevisionCount(blobId), 2);
    }

    function testThrowsUpdateLatestRevisionNotUpdatable() {
        bytes20 blobId = blobStore.create(0, hex"00");
        blobStore.updateLatestRevision(blobId, hex"00");
    }

    function testThrowsUpdateLatestRevisionEnforceRevisions() {
        bytes20 blobId = blobStore.create(FLAG_UPDATABLE | FLAG_ENFORCE_REVISIONS, hex"00");
        blobStore.updateLatestRevision(blobId, hex"00");
    }

    function testUpdateLatestRevision() {
        bytes20 blobId = blobStore.create(FLAG_UPDATABLE, hex"00");
        blobStore.updateLatestRevision(blobId, hex"00");
        assertEq(blobStore.getRevisionCount(blobId), 1);
    }

}

pragma solidity ^0.4.2;

import "dapple/test.sol";
import "blobstore.sol";
import "blobstore_flags.sol";

/**
 * @title BlobStoreTest
 * @author Jonathan Brown <jbrown@bluedroplet.com>
 */
contract BlobStoreTest is Test, BlobStoreFlags {

    BlobStoreRegistry blobStoreRegistry;
    BlobStore blobStore;

    function setUp() {
        blobStoreRegistry = new BlobStoreRegistry();
        blobStore = new BlobStore(blobStoreRegistry);
    }

    function testThrowRegisterContractAgain() {
        blobStoreRegistry.register(blobStore.getContractId());
    }

    function testThrowBlobStoreNotRegistered() {
        blobStoreRegistry.getBlobStore(0);
    }

    function testBlobStoreRegistered() {
        assertEq(blobStoreRegistry.getBlobStore(blobStore.getContractId()), blobStore);
    }

    function testThrowCreateExistingNonce() {
        blobStore.create(0, hex"00");
        blobStore.create(0, hex"00");
    }

    function testCreate() {
        bytes20 blobId0 = blobStore.create(0, hex"00");
        assertTrue(blobStore.getExists(blobId0));
        assertEq(blobStore.getOwner(blobId0), this);
        assertEq(blobStore.getRevisionCount(blobId0), 1);
        assertFalse(blobStore.getUpdatable(blobId0));
        assertFalse(blobStore.getEnforceRevisions(blobId0));
        assertFalse(blobStore.getRetractable(blobId0));
        assertFalse(blobStore.getTransferable(blobId0));

        bytes20 blobId1 = blobStore.create(FLAG_UPDATABLE | FLAG_ENFORCE_REVISIONS | FLAG_RETRACTABLE | FLAG_TRANSFERABLE | FLAG_ANONYMOUS, hex"00");
        assertTrue(blobStore.getExists(blobId1));
        assertEq(blobStore.getOwner(blobId1), 0);
        assertEq(blobStore.getRevisionCount(blobId1), 1);
        assertTrue(blobStore.getUpdatable(blobId1));
        assertTrue(blobStore.getEnforceRevisions(blobId1));
        assertTrue(blobStore.getRetractable(blobId1));
        assertTrue(blobStore.getTransferable(blobId1));

        assertFalse(blobId0 == blobId1);
    }

    function testThrowsCreateNewRevisionNotUpdatable() {
        bytes20 blobId = blobStore.create(0, hex"00");
        blobStore.createNewRevision(blobId, hex"00");
    }

    function testCreateNewRevision() {
        bytes20 blobId = blobStore.create(FLAG_UPDATABLE, hex"00");
        uint revisionId = blobStore.createNewRevision(blobId, hex"00");
        assertEq(revisionId, 1);
        assertEq(blobStore.getRevisionCount(blobId), 2);
    }

}


remove penalty for commited wrong hash

remove penalty for commited wrong hash

pragma solidity ^0.4.0;

import "./Math.sol";
import "./Concept.sol";
import "./ConceptRegistry.sol";
import "./UserRegistry.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 => State) assessorState;
  mapping(uint => int[]) clusters; //Initializes mapping to store clusters of scores
  State assessmentStage;
  enum State {//The state of the assessors
    None,
    Called, //Been called as a potential assessor
    Confirmed, //Confirmed as assessing
    Committed, //Committed a score
    Done, //Completed the assessment processs
    Burned //Entire stake has been burned
  }

  uint public assessorPoolLength; //how many users are potential assessors (also changed to public)
  address concept;
  address userRegistry;
  address conceptRegistry;
  uint public startTime;
  uint public size;
  uint cost;
  mapping(address => string[]) public data; //IPFS 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);

  modifier onlyAssessorAssessee() {
    if(msg.sender != assessee && uint(assessorState[msg.sender]) == 0) {
      throw;
    }
    _;
  }

  modifier onlyConceptAssessment() {
    if(msg.sender != address(this) && msg.sender != concept) {
      throw;
    }
    _;
  }

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

  modifier onlyInStage(State _stage) {
      if(assessmentStage != _stage){
          throw;
      }
      _;
  }

  function Assessment(address _assessee, address _userRegistry, address _conceptRegistry, uint _size, uint _cost) {
    assessee = _assessee;
    concept = msg.sender;
    userRegistry = _userRegistry;
    conceptRegistry = _conceptRegistry;
    startTime = block.number;
    size = _size;
    cost = _cost;
    UserRegistry(userRegistry).notification(assessee, 0); // assesse has started an assessment
    assessorPoolLength = 0;
  }

  function cancelAssessment() onlyInStage(State.Called) {
    if(msg.sender != assessee) throw;
    Concept(concept).addBalance(assessee, cost*size);
    UserRegistry(userRegistry).notification(assessee, 3); //Assessment Cancled and you have been refunded
    for(uint i = 0; i < assessors.length; i++) {
      Concept(concept).addBalance(assessors[i], cost);
      UserRegistry(userRegistry).notification(assessors[i], 3); //Assessment Cancled and you have been refunded
    }
    suicide(conceptRegistry);
  }

  //@purpose: adds a user to the pool eligible to accept an assessment
  function addAssessorToPool(address assessor) onlyConcept() returns(bool) {
    if(assessorState[assessor] == State.None) {
      UserRegistry(userRegistry).notification(assessor, 1); //Called As A Potential Assessor
      assessorState[assessor] = State.Called; //Sets the state of the assessor as called
      assessorPoolLength++;
      return true;
    }
    else {
      return false;
    }
  }

  /*
  @purpose: To recursively set the pool to draw assessors from in the assessment
  stops when the pool of potential assessors is 20 times the size of the assessment2
  @param: uint seed = the seed number for random number generation
  @param: address _concept = the concept being called from
  @param: uint num = the number of assessors to be called
  */
  function setAssessorPool(uint seed, address _concept, uint num) onlyConceptAssessment() {
    uint numCalled = 0;
    for (uint k=0; k < num; k++) {
      if (assessorPoolLength == size*20) { return; } //
      address randomUser = Concept(_concept).getRandomMember(seed + k);
      if (addAssessorToPool(randomUser)) {
        numCalled++;
      }
    }
    uint remaining = num - numCalled;
    if (remaining > 0) {
      for (uint i = 0; i < Concept(_concept).getParentsLength(); i++) {
        setAssessorPool(seed + assessorPoolLength, Concept(_concept).parents(i), remaining/Concept(_concept).getParentsLength() + 1); //Calls the remaining users from the parent concepts proportional to their size
      }
    }
    assessmentStage = State.Called;
  }

  /*
    @purpose: To set the pool of assessors when there are so few users in the system that
    assembling them at random is not meaningful. This will use all members of mew instead
  */
  function setAssessorPoolFromMew() onlyConcept() {
    Concept mew = Concept(ConceptRegistry(conceptRegistry).mewAddress()); //TODO: can this be more elegant and/or in one line?
      for (uint i=0; i<mew.getMemberLength(); i++) {
        addAssessorToPool(mew.members(i));
      }
      size = mew.getMemberLength();
      assessmentStage = State.Called;
  }

  //@purpose: called by an assessor to confirm and stake
  function confirmAssessor() onlyInStage(State.Called){
    //Check if the time to confirm has not passed, that the assessor was actually called, assessors are still needed, and that the assessor has enough of a balance to pay the stake
    if (assessorState[msg.sender] == State.Called &&
        assessors.length < size &&
        Concept(concept).subtractBalance(msg.sender, cost)
       )
      {
      assessors.push(msg.sender); //Adds the user that called this function to the array of confirmed assessors
      assessorState[msg.sender] = State.Confirmed; //Sets the assessor's state to confirmed
      stake[msg.sender] = cost; //Sets the current stake value of the assessor to the cost of the assessment
      UserRegistry(userRegistry).notification(msg.sender, 2); //Confirmed for assessing, stake has been taken
    }
    if (assessors.length == size) { //If enough assessors have been called
      notifyAssessors(uint(State.Confirmed), 4);
      UserRegistry(userRegistry).notification(assessee, 4);
      assessmentStage = State.Confirmed;
    }
  }

  function setData(string _data) onlyAssessorAssessee() {
    data[msg.sender].push(_data); //Adds the data to an array corresponding to the user that uploaded it
    DataSet(msg.sender, data[msg.sender].length - 1); // fire event
  }

  //@purpose: called by an assessor to commit a hash of their score //TODO explain in more detail what's happening
  function commit(bytes32 hash) onlyInStage(State.Confirmed){
    //If more than half the assessors have committed their score hash:
    if(done > size/2) {
        burnStakes();
    }
    //If all the assessors have either committed or had their entire stake burned
    if(done == size) {
      notifyAssessors(uint(State.Committed), 5);
      startTime = block.number; //Resets the startTime
      done = 0; //Resets the done counter
      assessmentStage = State.Committed;
    }
    //If the caller is confirmed as an assessor
    if(assessorState[msg.sender] == State.Confirmed)
    {
      commits[msg.sender] = hash; //Maps the score hash to the assessor
      assessorState[msg.sender] = State.Committed; //Sets the assessor's state to Committed
      done++; //Increases done by 1 to help progress to the next assessment stage.

      if(done <= size/2) {
        startTime = block.number;
      }
    }
  }

  //@purpose: called by assessors to reveal their own commits or others
  function reveal(int8 score, bytes16 salt, address assessor) onlyInStage(State.Committed) {
    if(block.number - startTime <= 10) { //If less than 10 blocks have passed since the socre commiting stage ended
      bytes32 hash = sha3(score,salt);
      if(commits[assessor] == hash) {
        if(msg.sender == assessor) {
          scores[msg.sender] = score;
          assessorState[assessor] = State.Done;
          done++; //done increases by 1 to help progress to the next assessment stage
        }
        else { //If it was submitted by another user than the given assessor
          Concept(concept).addBalance(msg.sender, stake[assessor]); // give the stake to the caller
          stake[assessor] = 0;
          assessorState[assessor] = State.Burned;
          done++; //done increases by 1 to help progress to the next assessment stage
        }
      }
    }
    else { //If more than 10 blocks have passed
      for(uint i = 0; i < assessors.length; i++) { //Loops through all the assessors
        if(assessorState[assessors[i]] == State.Committed) { //If the assessor has not revealed their score
          stake[assessors[i]] = 0; //The assessor's stake is completely burned
          assessorState[assessors[i]] = State.Burned;
          done++; //done increases by 1 to help progress to the next assessment stage
        }
      }
    }
    if(done == size) { //If all the assessors have revealed their scored or burned their stakes
      assessmentStage = State.Done;
      calculateResult(); //The final result is calculated
    }
  }

  function burnStakes() internal {
      for(uint i = 0; i < assessors.length; i++) {
          if(assessorState[assessors[i]] == State.Confirmed) { //if the assessor has not committed  a score
              uint r = 38; //Inverse burn rate
              stake[assessors[i]] = cost*2**(-(now-startTime)/r) - 1; //burns stake as a function of how much time has passed since half of the assessors commited
          }
          if(stake[assessors[i]] == 0) { //If an assessor's stake is entirely burned
              assessorState[assessors[i]] = State.Burned;
              done++; //Increases done by 1 to help progress to the next assessment stage
          }
      }
  }

   function notifyAssessors(uint _state, uint _topic) private {
      for(uint i=0; i < assessors.length; i++) {
          if(uint(assessorState[assessors[i]]) == _state) {
              UserRegistry(userRegistry).notification(assessors[i], _topic);
          }
      }
  }

   function calculateResult() onlyInStage(State.Done) private {
    for(uint j = 0; j < size; j++) { //Loops through the assessors
      if(assessorState[assessors[i]] == State.Done) {
        finalAssessors.push(assessors[i]); //Adds all the assessors that completed the assessment process to an array
      }
    }
    int[] memory score = new int[] (finalAssessors.length); //Initializes an array to store scores that is the same length as the number of finalAssessors
    uint largestClusterIndex = 0; //store the index of the largest cluster
    int averageScore;
    for(uint i = 0; i < finalAssessors.length; i++) {
      score[i] = scores[finalAssessors[i]]; //Puts all the scores in the score array
    }
    int meanAbsoluteDeviation = Math.calculateMAD(score,int(finalAssessors.length));
    for(uint l = 0; l < score.length; l++) { //Find the largest cluster of scores
      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++) { //Records which assessors submitted a score that was in the largest cluster
      averageScore += clusters[largestClusterIndex][o];
      inRewardCluster[clusters[largestClusterIndex][o]] = true;
    }
    averageScore /= int(clusters[largestClusterIndex].length); //Calculates the average score from the largest cluster
    finalScore = averageScore; //Sets the final score to the average score
    payout(); //Initializes the payout sequence
  }

  function payout() onlyInStage(State.Done) private {
    for(uint i = 0; i < size; i++) { //Loops through all the confirmed assessors
      int score = scores[assessors[i]]; //Gets the score of an assessor
      int scoreDistance = ((score - finalScore)*100)/finalScore; //Calculates the percent difference between the final score the assessors score
      if(scoreDistance < 0) { //Makes negative scoreDistances positive
        scoreDistance *= -1;
      }
      uint payoutValue = 1; //Initializes the payoutValue for the assessor
      if(inRewardCluster[score] == true) { //If the assessor's score was in the largest cluster
        uint q = 1; //Inflation rate factor, WE NEED TO FIGURE THIS OUT AT SOME POINT
        payoutValue = q*cost*((100 - uint(scoreDistance))/100); //The assessor's payout will be some constant times a propotion of their original stake determined by how close to the final score they were
        Concept(concept).addBalance(assessors[i], payoutValue); //Pays the user
      }
      if(inRewardCluster[score] == false) { //If the assessor's score wasn't in the largest cluster
        payoutValue = stake[assessors[i]]*((200 - uint(scoreDistance))/200); //The assessor's payout will be a propotion of their remaining stake determined by their distance from the final score
        Concept(concept).addBalance(assessors[i], payoutValue); //Pays the user
      }
    Concept(concept).finishAssessment(finalScore, assessee, address(this)); //Sends assessment info to the concept so that it can update its records
    UserRegistry(userRegistry).notification(assessors[i], 6); //You Have Received Payment For Your Assessment
    }
  }
}

pragma solidity ^0.4.0;

import "./Math.sol";
import "./Concept.sol";
import "./ConceptRegistry.sol";
import "./UserRegistry.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 => State) assessorState;
  mapping(uint => int[]) clusters; //Initializes mapping to store clusters of scores
  State assessmentStage;
  enum State {//The state of the assessors
    None,
    Called, //Been called as a potential assessor
    Confirmed, //Confirmed as assessing
    Committed, //Committed a score
    Done, //Completed the assessment processs
    Burned //Entire stake has been burned
  }

  uint public assessorPoolLength; //how many users are potential assessors (also changed to public)
  address concept;
  address userRegistry;
  address conceptRegistry;
  uint public startTime;
  uint public size;
  uint cost;
  mapping(address => string[]) public data; //IPFS 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);

  modifier onlyAssessorAssessee() {
    if(msg.sender != assessee && uint(assessorState[msg.sender]) == 0) {
      throw;
    }
    _;
  }

  modifier onlyConceptAssessment() {
    if(msg.sender != address(this) && msg.sender != concept) {
      throw;
    }
    _;
  }

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

  modifier onlyInStage(State _stage) {
      if(assessmentStage != _stage){
          throw;
      }
      _;
  }

  function Assessment(address _assessee, address _userRegistry, address _conceptRegistry, uint _size, uint _cost) {
    assessee = _assessee;
    concept = msg.sender;
    userRegistry = _userRegistry;
    conceptRegistry = _conceptRegistry;
    startTime = block.number;
    size = _size;
    cost = _cost;
    UserRegistry(userRegistry).notification(assessee, 0); // assesse has started an assessment
    assessorPoolLength = 0;
  }

  function cancelAssessment() onlyInStage(State.Called) {
    if(msg.sender != assessee) throw;
    Concept(concept).addBalance(assessee, cost*size);
    UserRegistry(userRegistry).notification(assessee, 3); //Assessment Cancled and you have been refunded
    for(uint i = 0; i < assessors.length; i++) {
      Concept(concept).addBalance(assessors[i], cost);
      UserRegistry(userRegistry).notification(assessors[i], 3); //Assessment Cancled and you have been refunded
    }
    suicide(conceptRegistry);
  }

  //@purpose: adds a user to the pool eligible to accept an assessment
  function addAssessorToPool(address assessor) onlyConcept() returns(bool) {
    if(assessorState[assessor] == State.None) {
      UserRegistry(userRegistry).notification(assessor, 1); //Called As A Potential Assessor
      assessorState[assessor] = State.Called; //Sets the state of the assessor as called
      assessorPoolLength++;
      return true;
    }
    else {
      return false;
    }
  }

  /*
  @purpose: To recursively set the pool to draw assessors from in the assessment
  stops when the pool of potential assessors is 20 times the size of the assessment2
  @param: uint seed = the seed number for random number generation
  @param: address _concept = the concept being called from
  @param: uint num = the number of assessors to be called
  */
  function setAssessorPool(uint seed, address _concept, uint num) onlyConceptAssessment() {
    uint numCalled = 0;
    for (uint k=0; k < num; k++) {
      if (assessorPoolLength == size*20) { return; } //
      address randomUser = Concept(_concept).getRandomMember(seed + k);
      if (addAssessorToPool(randomUser)) {
        numCalled++;
      }
    }
    uint remaining = num - numCalled;
    if (remaining > 0) {
      for (uint i = 0; i < Concept(_concept).getParentsLength(); i++) {
        setAssessorPool(seed + assessorPoolLength, Concept(_concept).parents(i), remaining/Concept(_concept).getParentsLength() + 1); //Calls the remaining users from the parent concepts proportional to their size
      }
    }
    assessmentStage = State.Called;
  }

  /*
    @purpose: To set the pool of assessors when there are so few users in the system that
    assembling them at random is not meaningful. This will use all members of mew instead
  */
  function setAssessorPoolFromMew() onlyConcept() {
    Concept mew = Concept(ConceptRegistry(conceptRegistry).mewAddress()); //TODO: can this be more elegant and/or in one line?
      for (uint i=0; i<mew.getMemberLength(); i++) {
        addAssessorToPool(mew.members(i));
      }
      size = mew.getMemberLength();
      assessmentStage = State.Called;
  }

  //@purpose: called by an assessor to confirm and stake
  function confirmAssessor() onlyInStage(State.Called){
    //Check if the time to confirm has not passed, that the assessor was actually called, assessors are still needed, and that the assessor has enough of a balance to pay the stake
    if (assessorState[msg.sender] == State.Called &&
        assessors.length < size &&
        Concept(concept).subtractBalance(msg.sender, cost)
       )
      {
      assessors.push(msg.sender); //Adds the user that called this function to the array of confirmed assessors
      assessorState[msg.sender] = State.Confirmed; //Sets the assessor's state to confirmed
      stake[msg.sender] = cost; //Sets the current stake value of the assessor to the cost of the assessment
      UserRegistry(userRegistry).notification(msg.sender, 2); //Confirmed for assessing, stake has been taken
    }
    if (assessors.length == size) { //If enough assessors have been called
      notifyAssessors(uint(State.Confirmed), 4);
      UserRegistry(userRegistry).notification(assessee, 4);
      assessmentStage = State.Confirmed;
    }
  }

  function setData(string _data) onlyAssessorAssessee() {
    data[msg.sender].push(_data); //Adds the data to an array corresponding to the user that uploaded it
    DataSet(msg.sender, data[msg.sender].length - 1); // fire event
  }

  //@purpose: called by an assessor to commit a hash of their score //TODO explain in more detail what's happening
  function commit(bytes32 hash) onlyInStage(State.Confirmed){
    //If more than half the assessors have committed their score hash:
    if(done > size/2) {
        burnStakes();
    }
    //If all the assessors have either committed or had their entire stake burned
    if(done == size) {
      notifyAssessors(uint(State.Committed), 5);
      startTime = block.number; //Resets the startTime
      done = 0; //Resets the done counter
      assessmentStage = State.Committed;
    }
    //If the caller is confirmed as an assessor
    if(assessorState[msg.sender] == State.Confirmed)
    {
      commits[msg.sender] = hash; //Maps the score hash to the assessor
      assessorState[msg.sender] = State.Committed; //Sets the assessor's state to Committed
      done++; //Increases done by 1 to help progress to the next assessment stage.

      if(done <= size/2) {
        startTime = block.number;
      }
    }
  }

  //@purpose: called by assessors to reveal their own commits or others
  function reveal(int8 score, bytes16 salt, address assessor) onlyInStage(State.Committed) {
    if(block.number - startTime <= 10) { //If less than 10 blocks have passed since the socre commiting stage ended
      bytes32 hash = sha3(score,salt);
      if(commits[assessor] == hash) {
        if(msg.sender == assessor) {
          scores[msg.sender] = score;
          assessorState[assessor] = State.Done;
          done++; //done increases by 1 to help progress to the next assessment stage
        }
        else { //If it was submitted by another user than the given assessor
          Concept(concept).addBalance(msg.sender, stake[assessor]); // give the stake to the caller
          stake[assessor] = 0;
          assessorState[assessor] = State.Burned;
          done++; //done increases by 1 to help progress to the next assessment stage
        }
      }
      else if(msg.sender == assessor) { //If the stake was wrong and was provided by the assessor in the parameter
        stake[assessor] = 0; //The assessor's stake is completely burned
        assessorState[assessor] = State.Burned; //The assessor's state is set to Burned
        done++; //done increases by 1 to help progress to the next assessment stage

    }
    else { //If more than 10 blocks have passed
      for(uint i = 0; i < assessors.length; i++) { //Loops through all the assessors
        if(assessorState[assessors[i]] == State.Committed) { //If the assessor has not revealed their score
          stake[assessors[i]] = 0; //The assessor's stake is completely burned
          assessorState[assessors[i]] = State.Burned;
          done++; //done increases by 1 to help progress to the next assessment stage
        }
      }
    }
    if(done == size) { //If all the assessors have revealed their scored or burned their stakes
      assessmentStage = State.Done;
      calculateResult(); //The final result is calculated
    }
  }

  function burnStakes() internal {
      for(uint i = 0; i < assessors.length; i++) {
          if(assessorState[assessors[i]] == State.Confirmed) { //if the assessor has not committed  a score
              uint r = 38; //Inverse burn rate
              stake[assessors[i]] = cost*2**(-(now-startTime)/r) - 1; //burns stake as a function of how much time has passed since half of the assessors commited
          }
          if(stake[assessors[i]] == 0) { //If an assessor's stake is entirely burned
              assessorState[assessors[i]] = State.Burned;
              done++; //Increases done by 1 to help progress to the next assessment stage
          }
      }
  }

   function notifyAssessors(uint _state, uint _topic) private {
      for(uint i=0; i < assessors.length; i++) {
          if(uint(assessorState[assessors[i]]) == _state) {
              UserRegistry(userRegistry).notification(assessors[i], _topic);
          }
      }
  }

   function calculateResult() onlyInStage(State.Done) private {
    for(uint j = 0; j < size; j++) { //Loops through the assessors
      if(assessorState[assessors[i]] == State.Done) {
        finalAssessors.push(assessors[i]); //Adds all the assessors that completed the assessment process to an array
      }
    }
    int[] memory score = new int[] (finalAssessors.length); //Initializes an array to store scores that is the same length as the number of finalAssessors
    uint largestClusterIndex = 0; //store the index of the largest cluster
    int averageScore;
    for(uint i = 0; i < finalAssessors.length; i++) {
      score[i] = scores[finalAssessors[i]]; //Puts all the scores in the score array
    }
    int meanAbsoluteDeviation = Math.calculateMAD(score,int(finalAssessors.length));
    for(uint l = 0; l < score.length; l++) { //Find the largest cluster of scores
      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++) { //Records which assessors submitted a score that was in the largest cluster
      averageScore += clusters[largestClusterIndex][o];
      inRewardCluster[clusters[largestClusterIndex][o]] = true;
    }
    averageScore /= int(clusters[largestClusterIndex].length); //Calculates the average score from the largest cluster
    finalScore = averageScore; //Sets the final score to the average score
    payout(); //Initializes the payout sequence
  }

  function payout() onlyInStage(State.Done) private {
    for(uint i = 0; i < size; i++) { //Loops through all the confirmed assessors
      int score = scores[assessors[i]]; //Gets the score of an assessor
      int scoreDistance = ((score - finalScore)*100)/finalScore; //Calculates the percent difference between the final score the assessors score
      if(scoreDistance < 0) { //Makes negative scoreDistances positive
        scoreDistance *= -1;
      }
      uint payoutValue = 1; //Initializes the payoutValue for the assessor
      if(inRewardCluster[score] == true) { //If the assessor's score was in the largest cluster
        uint q = 1; //Inflation rate factor, WE NEED TO FIGURE THIS OUT AT SOME POINT
        payoutValue = q*cost*((100 - uint(scoreDistance))/100); //The assessor's payout will be some constant times a propotion of their original stake determined by how close to the final score they were
        Concept(concept).addBalance(assessors[i], payoutValue); //Pays the user
      }
      if(inRewardCluster[score] == false) { //If the assessor's score wasn't in the largest cluster
        payoutValue = stake[assessors[i]]*((200 - uint(scoreDistance))/200); //The assessor's payout will be a propotion of their remaining stake determined by their distance from the final score
        Concept(concept).addBalance(assessors[i], payoutValue); //Pays the user
      }
    Concept(concept).finishAssessment(finalScore, assessee, address(this)); //Sends assessment info to the concept so that it can update its records
    UserRegistry(userRegistry).notification(assessors[i], 6); //You Have Received Payment For Your Assessment
    }
  }
}


Change deposit to use 1 ether

Change deposit to use 1 ether

import './zeppelin/Rejector.sol';
import './zeppelin/Ownable.sol';

contract Conference is Rejector, Ownable {
	string public name;
	uint256 public totalBalance;
	uint256 public deposit;
	uint public limitOfParticipants;
	uint public registered;
	uint public attended;
	bool public ended;
	mapping (address => Participant) public participants;
	mapping (uint => address) public participantsIndex;
	bool paid;
	uint256 _payout;

	struct Participant {
		string participantName;
		address addr;
		bool attended;
		int payout;
	}

	event Register(string participantName, address addr, uint256 balance, uint256 value);
	event Attend(address addr, uint256 balance);
	event Payback(address addr, uint256 _payout, uint256 balance, bool paid);
	event Cancel(address addr, uint256 balance);

	function Conference() {
		name = 'CodeUp';
		deposit = 1 ether;
		totalBalance = 0;
		registered = 0;
		attended = 0;
		limitOfParticipants = 10;
		ended = false;
	}

	modifier sentDepositOrReturn {
		if (msg.value == deposit) {
			_
		}else{
			msg.sender.send(msg.value);
		}
	}

	modifier onlyActive {
		if (ended == false) {
			_
		}
	}

	modifier onlyActiveOrReturn {
		if (ended == false) {
			_
		}else{
			msg.sender.send(msg.value);
		}
	}

	modifier withinLimitOrReturn {
		if (registered < limitOfParticipants ) {
			_
		}else{
			msg.sender.send(msg.value);
		}
	}

	function register(string _participant) sentDepositOrReturn withinLimitOrReturn onlyActiveOrReturn{
		Register(_participant, msg.sender, msg.sender.balance, msg.value);
		if (isRegistered(msg.sender)) throw;
		registered++;
		participantsIndex[registered] = msg.sender;
		participants[msg.sender] = Participant(_participant, msg.sender, false, 0);
		totalBalance = totalBalance + (deposit * 1);
	}

	function setLimitOfParticipants(uint _limitOfParticipants) {
		limitOfParticipants = _limitOfParticipants;
	}

	function attend(address _addr) onlyOwner{
		if (isRegistered(_addr) != true) throw;
		if (isAttended(_addr)) throw;
		Attend(_addr, msg.sender.balance);
		participants[_addr].attended = true;
		attended++;
	}

	function isRegistered(address _addr) returns (bool){
		return participants[_addr].addr != 0x0;
	}

	function isAttended(address _addr) returns (bool){
		return isRegistered(_addr) && participants[_addr].attended;
	}

	function payout() returns(uint256){
		return totalBalance / uint(attended);
	}

	function payback() onlyOwner{
		for(uint i=1;i<=registered;i++)
		{
			if(participants[participantsIndex[i]].attended){
				Payback(participantsIndex[i], payout(), participantsIndex[i].balance,  true);
				participants[participantsIndex[i]].payout = int(payout() - deposit);
				participantsIndex[i].send(payout());
			}else{
				participants[participantsIndex[i]].payout = int(deposit - (deposit * 2));
				Payback(participantsIndex[i], payout(), participantsIndex[i].balance, false);
			}
		}
		/*
		 *	Actual balance may have some left over if 4 payout is divided among 3 attendees
		 *	eg: 4 / 3 = 1.333
		 */
		totalBalance = 0;
		ended = true;
	}

	function cancel() onlyOwner onlyActive{
		Cancel(owner, totalBalance);
		for(uint i=1;i<=registered;i++)
		{
			if(totalBalance > 0){
				participantsIndex[i].send(deposit);
			}
			delete participants[participantsIndex[i]];
			delete participantsIndex[i];
		}
		totalBalance = 0;
		registered = 0;
		attended = 0;
		ended = true;
	}
}

import './zeppelin/Rejector.sol';
import './zeppelin/Ownable.sol';

contract Conference is Rejector, Ownable {
	string public name;
	uint256 public totalBalance;
	uint256 public deposit;
	uint public limitOfParticipants;
	uint public registered;
	uint public attended;
	bool public ended;
	mapping (address => Participant) public participants;
	mapping (uint => address) public participantsIndex;
	bool paid;
	uint256 _payout;

	struct Participant {
		string participantName;
		address addr;
		bool attended;
		int payout;
	}

	event Register(string participantName, address addr, uint256 balance, uint256 value);
	event Attend(address addr, uint256 balance);
	event Payback(address addr, uint256 _payout, uint256 balance, bool paid);
	event Cancel(address addr, uint256 balance);

	function Conference() {
		name = 'CodeUp';
		deposit = 1000000000000000000;		// 1 ETH = 10**18 wai
		totalBalance = 0;
		registered = 0;
		attended = 0;
		limitOfParticipants = 10;
		ended = false;
	}

	modifier sentDepositOrReturn {
		if (msg.value == deposit) {
			_
		}else{
			msg.sender.send(msg.value);
		}
	}

	modifier onlyActive {
		if (ended == false) {
			_
		}
	}

	modifier onlyActiveOrReturn {
		if (ended == false) {
			_
		}else{
			msg.sender.send(msg.value);
		}
	}

	modifier withinLimitOrReturn {
		if (registered < limitOfParticipants ) {
			_
		}else{
			msg.sender.send(msg.value);
		}
	}

	function register(string _participant) sentDepositOrReturn withinLimitOrReturn onlyActiveOrReturn{
		Register(_participant, msg.sender, msg.sender.balance, msg.value);
		if (isRegistered(msg.sender)) throw;
		registered++;
		participantsIndex[registered] = msg.sender;
		participants[msg.sender] = Participant(_participant, msg.sender, false, 0);
		totalBalance = totalBalance + (deposit * 1);
	}

	function setLimitOfParticipants(uint _limitOfParticipants) {
		limitOfParticipants = _limitOfParticipants;
	}

	function attend(address _addr) onlyOwner{
		if (isRegistered(_addr) != true) throw;
		if (isAttended(_addr)) throw;
		Attend(_addr, msg.sender.balance);
		participants[_addr].attended = true;
		attended++;
	}

	function isRegistered(address _addr) returns (bool){
		return participants[_addr].addr != 0x0;
	}

	function isAttended(address _addr) returns (bool){
		return isRegistered(_addr) && participants[_addr].attended;
	}

	function payout() returns(uint256){
		return totalBalance / uint(attended);
	}

	function payback() onlyOwner{
		for(uint i=1;i<=registered;i++)
		{
			if(participants[participantsIndex[i]].attended){
				Payback(participantsIndex[i], payout(), participantsIndex[i].balance,  true);
				participants[participantsIndex[i]].payout = int(payout() - deposit);
				participantsIndex[i].send(payout());
			}else{
				participants[participantsIndex[i]].payout = int(deposit - (deposit * 2));
				Payback(participantsIndex[i], payout(), participantsIndex[i].balance, false);
			}
		}
		/*
		 *	Actual balance may have some left over if 4 payout is divided among 3 attendees
		 *	eg: 4 / 3 = 1.333
		 */
		totalBalance = 0;
		ended = true;
	}

	function cancel() onlyOwner onlyActive{
		Cancel(owner, totalBalance);
		for(uint i=1;i<=registered;i++)
		{
			if(totalBalance > 0){
				participantsIndex[i].send(deposit);
			}
			delete participants[participantsIndex[i]];
			delete participantsIndex[i];
		}
		totalBalance = 0;
		registered = 0;
		attended = 0;
		ended = true;
	}
}


Bugfix, this.balance becomes stake

Bugfix, this.balance becomes stake

this.balanec is updated at the beginning of a function, thus the calculation was wronk

pragma solidity ^0.4.6;

// ## Matthew - a contract for increasing "whaleth"
// README: https://github.com/rolandkofler/matthew
// MIT LICENSE 2016 Roland Kofler, thanks to Crul for testing

contract Matthew {
    address owner;
    address public whale;
    uint256 public blockheight;
    uint256 public stake;
    uint256 period = 40; //180 blocks ~ 42 min, 300 blocks ~ 1h 10 min;
    uint constant DELTA = 0.1 ether;
    uint constant WINNERTAX_PRECENT = 10;
    bool mustBeDestroyed = false;
    uint newPeriod = period;

    event MatthewWon(string msg, address winner, uint value,  uint blocknumber);
    event StakeIncreased(string msg, address staker, uint value, uint blocknumber);

    function Matthew(){
        owner = msg.sender;
        setFacts();
    }

    function setFacts() private {
        stake = this.balance;
        period = newPeriod;
        blockheight = block.number;
        whale = msg.sender;
    }

    /// The rich get richer, the whale get whaler
    function () payable{

        if (block.number - period >= blockheight){ // time is over, Matthew won
            bool isSuccess=false; //mutex against recursion attack
            var nextStake = stake * WINNERTAX_PRECENT/100;  // leave some money for the next round
            if (isSuccess == false) //check against recursion attack
                isSuccess = whale.send(stake - nextStake); // pay out the stake
            MatthewWon("Matthew won", whale, stake - nextStake, block.number);
            setFacts();//reset the game
            if (mustBeDestroyed) selfdestruct(whale);
            return;

        }else{ // top the stake
            if (msg.value < stake + DELTA) throw; // you must rise the stake by Delta
            bool isOtherSuccess = msg.sender.send(stake); // give back the old stake
            setFacts(); //reset the game
            StakeIncreased("stake increased", whale, stake, blockheight);
        }
    }

    // better safe than sorry
    function destroyWhenRoundOver() onlyOwner{
        mustBeDestroyed = true;
    }

    // next round we set a new staking perioud
    function setNewPeriod(uint _newPeriod) onlyOwner{
        newPeriod = _newPeriod;
    }

    function getPeriod() constant returns (uint){
        return period;
    }

    function getNewPeriod() constant returns (uint){
        return newPeriod;
    }

    function getDestroyedWhenRoundOver() constant returns (bool){
        return mustBeDestroyed;
    }

    //how long until a Matthew wins?
    function getBlocksTillMatthew() public constant returns(uint){
        if (blockheight + period > block.number)
            return blockheight + period - block.number;
        else
            return 0;
    }

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

pragma solidity ^0.4.6;

// ## Matthew - a contract for increasing "whaleth"
// README: https://github.com/rolandkofler/matthew
// MIT LICENSE 2016 Roland Kofler, thanks to Crul for testing

contract Matthew {
    address owner;
    address whale;
    uint256 blockheight;
    uint256 period = 40; //180 blocks ~ 42 min, 300 blocks ~ 1h 10 min;
    uint constant DELTA = 0.1 ether;
    uint constant WINNERTAX_PRECENT = 10;
    bool mustBeDestroyed = false;
    uint newPeriod = period;

    event MatthewWon(string msg, address winner, uint value,  uint blocknumber);
    event StakeIncreased(string msg, address staker, uint value, uint blocknumber);

    function Matthew(){
        owner = msg.sender;
        setFacts();
    }

    function setFacts() private {
        period = newPeriod;
        blockheight = block.number;
        whale = msg.sender;
    }

    /// The rich get richer, the whale get whaler
    function () payable{

        if (block.number - period >= blockheight){ // time is over, Matthew won
            bool isSuccess=false; //mutex against recursion attack
            var nextStake = this.balance * WINNERTAX_PRECENT/100;  // leave some money for the next round
            if (isSuccess == false) //check against recursion attack
                isSuccess = whale.send(this.balance - nextStake); // pay out the stake
            MatthewWon("Matthew won", whale, this.balance, block.number);
            setFacts();//reset the game
            if (mustBeDestroyed) selfdestruct(whale);
            return;

        }else{ // top the stake
            if (msg.value < this.balance + DELTA) throw; // you must rise the stake by Delta
            bool isOtherSuccess = msg.sender.send(this.balance); // give back the old stake
            setFacts(); //reset the game
            StakeIncreased("stake increased", whale, this.balance, blockheight);
        }
    }

    // better safe than sorry
    function destroyWhenRoundOver() onlyOwner{
        mustBeDestroyed = true;
    }

    // next round we set a new staking perioud
    function setNewPeriod(uint _newPeriod) onlyOwner{
        newPeriod = _newPeriod;
    }

    function getPeriod() constant returns (uint){
        return period;
    }

    function getNewPeriod() constant returns (uint){
        return newPeriod;
    }

    function getDestroyedWhenRoundOver() constant returns (bool){
        return mustBeDestroyed;
    }

    //how long until a Matthew wins?
    function getBlocksTillMatthew() public constant returns(uint){
        if (blockheight + period > block.number)
            return blockheight + period - block.number;
        else
            return 0;
    }

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


clean up

clean up

pragma solidity ^0.4.6;

contract Conference {

  address Organizer;
  mapping (address => uint) RegistrantsPaid;
  uint public Registrants;
  uint Quota;

  event Deposit(address from, uint amount);
  event Refund(address to, uint amount);

  function Conference() {
    Organizer = msg.sender;
    Quota = 5;
    Registrants = 0;
  }

  function GetQuota() constant returns(uint) {
    return Quota;
  }

  function BuyTicket() payable {
    if (msg.value > 0) {
      if (Registrants < Quota && RegistrantsPaid[msg.sender] == 0) {
        RegistrantsPaid[msg.sender] = msg.value;
        Registrants++;
        Deposit(msg.sender, msg.value);
      }
      else {
        if (!msg.sender.send(msg.value)) {
          throw;
        }
      }
    }
  }

  function ChangeQuota(uint newquota) public {
    if (msg.sender != Organizer) {
      throw;
    }

    Quota = newquota;
  }

  function RefundTicket(address recipient, uint amount) public
  {
    if (msg.sender != Organizer) {
      throw;
    }

    if (RegistrantsPaid[recipient] == amount) {
      address myAddress = this;

      if (myAddress.balance >= amount) {
        if (recipient.send(amount))
        {
          Refund(recipient, amount);
          RegistrantsPaid[recipient] = 0;
          Registrants--;
        }
      }
    }
  }

  function Destroy() {
    if (msg.sender == Organizer) {
      // without this funds could be locked in the contract forever!
      suicide(Organizer);
    }
  }
}