Create WeiController_Beta_Laucnh.sol

Create WeiController_Beta_Laucnh.sol

/*
WeiFund v1.0

This contract creates a WeiFund token dispersal controller.

Anyone is free to copy, modify, publish, use, compile, sell, or
distribute this software, either in source code form or as a compiled
binary, for any purpose, commercial or non-commercial, and by any
means.

In jurisdictions that recognize copyright laws, the author or authors
of this software dedicate any and all copyright interest in the
software to the public domain. We make this dedication for the benefit
of the public at large and to the detriment of our heirs and
successors. We intend this dedication to be an overt act of
relinquishment in perpetuity of all present and future rights to this
software under copyright law.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.

For more information, please refer to <http://unlicense.org>
*/

/// @title The core WeiFund configuration hook interface
/// @author Nick Dodson <thenickdodson@gmail.com>
/// @dev This contract enables campaigns to interact with other contracts, such as equity dispersal mechanisms (controllers) and registries
contract WeiFundConfig {
    /// @notice Called when a new campaign has been created
    /// @dev If a campaign specifies a configuration contract, this will be called when the new campaign is created
    /// @param _campaignID (campaign id) the campaign id
    /// @param _owner (campaign owner) the campaign owner or creator
    /// @param _fundingGoal (funding goal) the campaign funding goal
    function newCampaign(uint _campaignID, address _owner, uint _fundingGoal) {}

    /// @notice Called when a new contribution has been made
    /// @dev This will be called when a new contribution has been made to a campaign, this can be used for token generation
    /// @param _campaignID (campaign id) the campaign id
    /// @param _contributor (contributor) the account that initially made the campaign contribution
    /// @param _beneficiary (contribution beneficiary) the contribution beneficiary
    /// @param _amountContributed (amount contributed) the amount contributed by the contributor
    function contribute(uint _campaignID, address _contributor, address _beneficiary, uint _amountContributed) {}

    /// @notice Called when a new refund has been ordered
    /// @dev This will be called when a campaign has failed and a contributor is ordering a refund of their contributed ether
    /// @param _campaignID (campaign id) the campaign id
    /// @param _contributor (contributor) the campaign contributor address
    /// @param _amountRefunded the amount refunded to the contributor
    function refund(uint _campaignID, address _contributor, uint _amountRefunded) {}

    /// @notice Called when a campaign is being paid out
    /// @dev This will be called when a campaign has succeceed and the funds are being paid out to the contributor
    /// @param _campaignID (campaign id) the campaign id
    /// @param _amountPaid The amount paid out to the campaign beneficiary
    function payout(uint _campaignID, uint _amountPaid) {}
}

contract Token {
    /// @return total amount of tokens
    function totalSupply() constant returns (uint256 supply) {}

    /// @param _owner The address from which the balance will be retrieved
    /// @return The balance
    function balanceOf(address _owner) constant returns (uint256 balance) {}

    /// @notice send `_value` token to `_to` from `msg.sender`
    /// @param _to The address of the recipient
    /// @param _value The amount of token to be transferred
    /// @return Whether the transfer was successful or not
    function transfer(address _to, uint256 _value) returns (bool success) {}

    /// @notice send `_value` token to `_to` from `_from` on the condition it is approved by `_from`
    /// @param _from The address of the sender
    /// @param _to The address of the recipient
    /// @param _value The amount of token to be transferred
    /// @return Whether the transfer was successful or not
    function transferFrom(address _from, address _to, uint256 _value) returns (bool success) {}

    /// @notice `msg.sender` approves `_addr` to spend `_value` tokens
    /// @param _spender The address of the account able to transfer the tokens
    /// @param _value The amount of wei to be approved for transfer
    /// @return Whether the approval was successful or not
    function approve(address _spender, uint256 _value) returns (bool success) {}

    /// @param _owner The address of the account owning tokens
    /// @param _spender The address of the account able to transfer the tokens
    /// @return Amount of remaining tokens allowed to spent
    function allowance(address _owner, address _spender) constant returns (uint256 remaining) {}

    event Transfer(address indexed _from, address indexed _to, uint256 _value);
    event Approval(address indexed _owner, address indexed _spender, uint256 _value);
}

/// @title The core WeiFund Controller/Token Dispersal Contract
/// @author Nick Dodson <thenickdodson@gmail.com>
contract WeiController is WeiFundConfig {
    address token;
    address weifund;
    uint ratio;
    address owner;
    uint campaignID;
    bool paidout;

    function WeiController_custom (address _weifund, address _token, uint _ratio) {
        token = _token;
        weifund = _weifund;
        ratio = _ratio;
        owner = msg.sender;
    }

    function newCampaign (uint _campaignID, address _owner, uint _fundingGoal) {
        if(_owner != owner || msg.sender != weifund)
            return;

        campaignID = _campaignID;
    }

    function contribute (uint _campaignID, address _contributor, address _beneficiary, uint _amountContributed) {
        if(campaignID != _campaignID
            || _amountContributed <= 0
            || msg.sender != weifund
            || paidout)
            return;

        address receiver = _beneficiary;
        uint tokenAmount = _amountContributed / ratio;

        if(receiver == address(0))
            receiver = _contributor;

        Token(token).transfer(receiver, tokenAmount);
    }

    function refund (uint _campaignID, address _contributor, uint _amountRefunded) {
        if(campaignID != _campaignID || msg.sender != weifund)
            return;
    }

    function payout (uint _campaignID, uint _amountPaid) {
        if(campaignID != _campaignID || msg.sender != weifund)
            return;

        paidout = true;
    }
}

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


fix bug cannot calculate current block hash, have to wait one turn

pragma solidity ^0.4.11;
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 public owner;

    mapping(string => Pot) nameToPot;

    event newPot(string name, uint buyIn, address creatorPlayer);
    event potJoin(string name, address newPlayer);
    event potFull(string name);
    event potExpired(string name);
    event potClosed(string name, address loser);
    event playerWon(address player, uint amount);

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

    function ownerWithdraw(){
        require(msg.sender == owner);

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

        owner.transfer(uint(toWithdraw));
    }

    function createPot(string name) payable {
        require(msg.value > 0); // must bet something
        require(bytes(name).length > 0); // name mustn't be empty
        require(nameToPot[name].buyIn == 0); // there isn't already a pot with this name

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

        newPot(name, msg.value, msg.sender);
    }

    function joinPot(string name) payable {
        Pot pot = nameToPot[name];
        require(pot.buyIn > 0); // pot exists
        require(pot.loser == 0); // pot isn't over
        require(pot.players.length < 3); // pot isn't full
        require(msg.value == pot.buyIn); // must pay buyIn amount
        for(uint i = 0; i < pot.players.length; i++){
            require(pot.players[i] != msg.sender); //must be new to this pot
        }

        pot.players.push(msg.sender);
        potJoin(name, msg.sender);

        if(pot.players.length == 3){
            pot.lastPlayerBlockNumber = block.number;
            potFull(name);
        }
    }

    function solvePot(string name){
        Pot pot = nameToPot[name];
        require(pot.loser == 0); // pot isn't over
        require(pot.players.length == 3); // pot full
        require(block.number > pot.lastPlayerBlockNumber + 1);

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

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

            potExpired(name);
            return;
        }

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

        require(pot.loser == 0); // need this?
        pot.loser = pot.players[loserIndex];

        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.transfer(returnAmount);
        playerWon(winner1, winAmount);

        winner2.transfer(returnAmount);
        playerWon(winner2, winAmount);

        potClosed(name, pot.loser);
    }
}

pragma solidity ^0.4.11;
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 public owner;

    mapping(string => Pot) nameToPot;

    event newPot(string name, uint buyIn, address creatorPlayer);
    event potJoin(string name, address newPlayer);
    event potFull(string name);
    event potExpired(string name);
    event potClosed(string name, address loser);
    event playerWon(address player, uint amount);

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

    function ownerWithdraw(){
        require(msg.sender == owner);

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

        owner.transfer(uint(toWithdraw));
    }

    function createPot(string name) payable {
        require(msg.value > 0); // must bet something
        require(bytes(name).length > 0); // name mustn't be empty
        require(nameToPot[name].buyIn == 0); // there isn't already a pot with this name

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

        newPot(name, msg.value, msg.sender);
    }

    function joinPot(string name) payable {
        Pot pot = nameToPot[name];
        // require(pot.buyIn > 0); // pot exists
        // require(pot.loser == 0); // pot isn't over
        // require(pot.players.length < 3); // pot isn't full
        // require(msg.value == pot.buyIn); // must pay buyIn amount
        // require(pot.players[0] != msg.sender && pot.players[1] != msg.sender);

        pot.players.push(msg.sender);
        potJoin(name, msg.sender);

        if(pot.players.length == 3){
            pot.lastPlayerBlockNumber = block.number;
            potFull(name);
        }
    }

    function solvePot(string name){
        Pot pot = nameToPot[name];
        require(pot.loser == 0); // pot isn't over
        require(pot.players.length == 3); // pot full
        require(block.number > pot.lastPlayerBlockNumber);

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

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

            potExpired(name);
            return;
        }

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

        require(pot.loser == 0); // need this?
        pot.loser = pot.players[loserIndex];

        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.transfer(returnAmount);
        playerWon(winner1, winAmount);

        winner2.transfer(returnAmount);
        playerWon(winner2, winAmount);

        potClosed(name, pot.loser);
    }
}


remove data from assessments

remove data from assessments

pragma solidity ^0.4.11;

import "./Math.sol";
import "./Concept.sol";
import "./ConceptRegistry.sol";
import "./UserRegistry.sol";

contract Assessment {
    address assessee;
    address[] assessors;
    mapping (address => State) assessorState;
    State public assessmentStage;
    enum State {
        None,
        Called,
        Confirmed,
        Committed,
        Done,
        Burned
    }

    uint public assessorPoolLength;
    address concept;
    address userRegistry;
    address conceptRegistry;
    uint public endTime;
    uint public latestConfirmTime;
    uint burnRate;
    uint public size;
    uint cost;

    mapping(address => bytes32) commits;
    mapping(address => uint) stake;
    uint public done; //counter how many assessors have committed/revealed their score
    mapping(address => int128) scores;
    int public finalScore;

    modifier onlyAssessorAssessee() {
        require(msg.sender == assessee || assessorState[msg.sender] != State.None);
        _;
    }

    modifier onlyConceptAssessment() {
        require(msg.sender == address(this) || msg.sender == concept);
        _;
    }

    modifier onlyConcept() {
        require(msg.sender == concept);
        _;
    }

    modifier onlyInStage(State _stage) {
        require(assessmentStage == _stage);
        _;
    }

    function Assessment(address _assessee,
                        address _userRegistry,
                        address _conceptRegistry,
                        uint _size,
                        uint _cost,
                        uint _confirmTime,
                        uint _timeLimit) {
        assessee = _assessee;
        concept = msg.sender;
        userRegistry = _userRegistry;
        conceptRegistry = _conceptRegistry;

        endTime = now + _timeLimit;
        latestConfirmTime = now + _confirmTime;
        assert(latestConfirmTime < endTime);

        size = _size;
        cost = _cost;

        UserRegistry(userRegistry).notification(assessee, 0); // assesse has started an assessment
        assessorPoolLength = 0;
        done = 0;
    }

    function cancelAssessment() onlyConceptAssessment() {
        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;
            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 (randomUser != address(0x0) && 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) {
        // cancel if the assessment is older than 12 hours or already past its timelimit
        if (now > latestConfirmTime){
            this.cancelAssessment();
            return;
        }
        if (assessorState[msg.sender] == State.Called &&
            assessors.length < size &&
            Concept(concept).subtractBalance(msg.sender, cost)
            ) {
            assessors.push(msg.sender);
            assessorState[msg.sender] = State.Confirmed;
            stake[msg.sender] = cost;
            UserRegistry(userRegistry).notification(msg.sender, 2); //Confirmed for assessing, stake has been taken
        }
        if (assessors.length == size) {
            notifyAssessors(uint(State.Confirmed), 4);
            UserRegistry(userRegistry).notification(assessee, 4);
            assessmentStage = State.Confirmed;
        }
    }

    //@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 (now > endTime) {
            burnStakes();
        }
        if (assessorState[msg.sender] == State.Confirmed) {
                commits[msg.sender] = _hash;
                assessorState[msg.sender] = State.Committed;
                done++; //Increases done by 1 to help progress to the next assessment stage.
        }
        if (done == size) {
            notifyAssessors(uint(State.Committed), 5);
            done = 0; //Resets the done counter
            assessmentStage = State.Committed;
        }
    }

    function steal(int128 _score, string _salt, address assessor) {
        if(assessorState[assessor] == State.Committed && msg.sender != assessor) {
            if(commits[assessor] == sha3(_score, _salt)) {
                Concept(concept).addBalance(msg.sender, stake[assessor]);
                stake[assessor] = 0;
                assessorState[assessor] = State.Burned;
                size--;
            }
        }
    }

    //@purpose: called by assessors to reveal their own commits or others
    function reveal(int128 _score, string _salt) onlyInStage(State.Committed) {
        if (now > endTime + 12 hours) { //add bigger zerocheck
            for (uint i = 0; i < assessors.length; i++) {
                if (assessorState[assessors[i]] == State.Committed) { //If the assessor has not revealed their score
                    stake[assessors[i]] = 0;
                    assessorState[assessors[i]] = State.Burned;
                    size--;
                }
            }
        }

        if(assessorState[msg.sender] == State.Committed &&
           commits[msg.sender] == sha3(_score, _salt)) {
                    scores[msg.sender] = _score;
                    assessorState[msg.sender] = State.Done;
                    done++;
        }

        if (done == size) {
            assessmentStage = State.Done;
            calculateResult();
        }
    }

    //@purpose: burns stakes as a function of how much time has passed since half of the assessors commited
    function burnStakes() internal {
        for (uint i = 0; i < assessors.length; i++) {
            if (assessorState[assessors[i]] == State.Confirmed) {
                stake[assessors[i]] = 0;
                assessorState[assessors[i]] = State.Burned;
                size--; //decrease size 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 {
        int[] memory finalScores = new int[] (done);
        uint idx =0;
        for (uint j = 0; j < assessors.length; j++) {
            if (assessorState[assessors[j]] == State.Done) {
                finalScores[idx] = scores[assessors[j]];
                idx++;
            }
        }
        uint mad;
        uint finalClusterLength;
        (finalScore, finalClusterLength, mad) = Math.getFinalScore(finalScores);
        payout(finalScore, mad);
        if (finalScore > 0) {
            Concept(concept).addMember(assessee, uint(finalScore) * finalClusterLength);
        }
        UserRegistry(userRegistry).notification(assessee, 7);
   }

    function payout(int finalScore, uint mad) onlyInStage(State.Done) internal {
        uint q = 1; //INFLATION RATE
        for (uint i = 0; i < assessors.length; i++) {
            if (assessorState[assessors[i]] == State.Done) {
                uint payoutValue = Math.getPayout(scores[assessors[i]], finalScore, mad, stake[assessors[i]], q);
                Concept(concept).addBalance(assessors[i], payoutValue);
                UserRegistry(userRegistry).notification(assessors[i], 6); //You  got paid!
            }
        }
    }
}

pragma solidity ^0.4.11;

import "./Math.sol";
import "./Concept.sol";
import "./ConceptRegistry.sol";
import "./UserRegistry.sol";

contract Assessment {
    address assessee;
    address[] assessors;
    mapping (address => State) assessorState;
    State public assessmentStage;
    enum State {
        None,
        Called,
        Confirmed,
        Committed,
        Done,
        Burned
    }

    uint public assessorPoolLength;
    address concept;
    address userRegistry;
    address conceptRegistry;
    uint public endTime;
    uint public latestConfirmTime;
    uint burnRate;
    uint public size;
    uint cost;
    mapping(address => string[]) public data;
    mapping(address => bytes32) commits;
    mapping(address => uint) stake;
    uint public done; //counter how many assessors have committed/revealed their score
    mapping(address => int128) scores;
    int public finalScore;
    event DataSet(address _dataSetter, uint _index);

    modifier onlyAssessorAssessee() {
        require(msg.sender == assessee || assessorState[msg.sender] != State.None);
        _;
    }

    modifier onlyConceptAssessment() {
        require(msg.sender == address(this) || msg.sender == concept);
        _;
    }

    modifier onlyConcept() {
        require(msg.sender == concept);
        _;
    }

    modifier onlyInStage(State _stage) {
        require(assessmentStage == _stage);
        _;
    }

    function Assessment(address _assessee,
                        address _userRegistry,
                        address _conceptRegistry,
                        uint _size,
                        uint _cost,
                        uint _confirmTime,
                        uint _timeLimit) {
        assessee = _assessee;
        concept = msg.sender;
        userRegistry = _userRegistry;
        conceptRegistry = _conceptRegistry;

        endTime = now + _timeLimit;
        latestConfirmTime = now + _confirmTime;
        assert(latestConfirmTime < endTime);

        size = _size;
        cost = _cost;

        UserRegistry(userRegistry).notification(assessee, 0); // assesse has started an assessment
        assessorPoolLength = 0;
        done = 0;
    }

    function cancelAssessment() onlyConceptAssessment() {
        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;
            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 (randomUser != address(0x0) && 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) {
        // cancel if the assessment is older than 12 hours or already past its timelimit
        if (now > latestConfirmTime){
            this.cancelAssessment();
            return;
        }
        if (assessorState[msg.sender] == State.Called &&
            assessors.length < size &&
            Concept(concept).subtractBalance(msg.sender, cost)
            ) {
            assessors.push(msg.sender);
            assessorState[msg.sender] = State.Confirmed;
            stake[msg.sender] = cost;
            UserRegistry(userRegistry).notification(msg.sender, 2); //Confirmed for assessing, stake has been taken
        }
        if (assessors.length == size) {
            notifyAssessors(uint(State.Confirmed), 4);
            UserRegistry(userRegistry).notification(assessee, 4);
            assessmentStage = State.Confirmed;
        }
    }

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

    //@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 (now > endTime) {
            burnStakes();
        }
        if (assessorState[msg.sender] == State.Confirmed) {
                commits[msg.sender] = _hash;
                assessorState[msg.sender] = State.Committed;
                done++; //Increases done by 1 to help progress to the next assessment stage.
        }
        if (done == size) {
            notifyAssessors(uint(State.Committed), 5);
            done = 0; //Resets the done counter
            assessmentStage = State.Committed;
        }
    }

    function steal(int128 _score, string _salt, address assessor) {
        if(assessorState[assessor] == State.Committed && msg.sender != assessor) {
            if(commits[assessor] == sha3(_score, _salt)) {
                Concept(concept).addBalance(msg.sender, stake[assessor]);
                stake[assessor] = 0;
                assessorState[assessor] = State.Burned;
                size--;
            }
        }
    }

    //@purpose: called by assessors to reveal their own commits or others
    function reveal(int128 _score, string _salt) onlyInStage(State.Committed) {
        if (now > endTime + 12 hours) { //add bigger zerocheck
            for (uint i = 0; i < assessors.length; i++) {
                if (assessorState[assessors[i]] == State.Committed) { //If the assessor has not revealed their score
                    stake[assessors[i]] = 0;
                    assessorState[assessors[i]] = State.Burned;
                    size--;
                }
            }
        }

        if(assessorState[msg.sender] == State.Committed &&
           commits[msg.sender] == sha3(_score, _salt)) {
                    scores[msg.sender] = _score;
                    assessorState[msg.sender] = State.Done;
                    done++;
        }

        if (done == size) {
            assessmentStage = State.Done;
            calculateResult();
        }
    }

    //@purpose: burns stakes as a function of how much time has passed since half of the assessors commited
    function burnStakes() internal {
        for (uint i = 0; i < assessors.length; i++) {
            if (assessorState[assessors[i]] == State.Confirmed) {
                stake[assessors[i]] = 0;
                assessorState[assessors[i]] = State.Burned;
                size--; //decrease size 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 {
        int[] memory finalScores = new int[] (done);
        uint idx =0;
        for (uint j = 0; j < assessors.length; j++) {
            if (assessorState[assessors[j]] == State.Done) {
                finalScores[idx] = scores[assessors[j]];
                idx++;
            }
        }
        uint mad;
        uint finalClusterLength;
        (finalScore, finalClusterLength, mad) = Math.getFinalScore(finalScores);
        payout(finalScore, mad);
        if (finalScore > 0) {
            Concept(concept).addMember(assessee, uint(finalScore) * finalClusterLength);
        }
        UserRegistry(userRegistry).notification(assessee, 7);
   }

    function payout(int finalScore, uint mad) onlyInStage(State.Done) internal {
        uint q = 1; //INFLATION RATE
        for (uint i = 0; i < assessors.length; i++) {
            if (assessorState[assessors[i]] == State.Done) {
                uint payoutValue = Math.getPayout(scores[assessors[i]], finalScore, mad, stake[assessors[i]], q);
                Concept(concept).addBalance(assessors[i], payoutValue);
                UserRegistry(userRegistry).notification(assessors[i], 6); //You  got paid!
            }
        }
    }
}


Add balance converter to the payroll event.

pragma solidity ^0.4.2;

import "SpiceControlled.sol";
import "IBalanceConverter.sol";
import "SpicePayroll.sol";

contract SpiceHours is SpiceControlled {
    struct MemberBalance {
        bool available;
        uint total;
    }

    uint public fromTimestamp;
    address[] payrolls;

    mapping (bytes32 => MemberBalance) balances;
    bytes32[] infos;
    uint infoCount;

    event MarkHours(address indexed _sender, bytes32 indexed _info, bytes32 indexed _description, int _secs);
    event FixHours(address indexed _sender, bytes32 indexed _info, bytes32 indexed _description, int _secs);
    event PayrollLine(address indexed _sender, bytes32 indexed _info, uint secs, uint balance);
    event Payroll(address indexed _sender, address indexed _balanceConverter, address _payroll);

    function SpiceHours(address _members) SpiceControlled(_members) {
        fromTimestamp = now;
    }

    function payroll(uint _index) constant returns (address) {
        return payrolls[_index];
    }

    function payrollCount() constant returns (uint) {
        return payrolls.length;
    }

    function balance(bytes32 _info) constant returns (uint) {
        return balances[_info].total;
    }

    function adjustHours(bytes32 _info, int _secs) private {
        if (_info == 0) throw;
        if (_secs == 0) throw;
        if (_secs < 0 && balances[_info].total < uint(-_secs)) throw;

        if (!balances[_info].available) {
            balances[_info].available = true;
            infos.push(_info);
            infoCount++;
        }

        if (_secs < 0) {
            balances[_info].total -= uint(-_secs);
        } else {
            balances[_info].total += uint(_secs);
        }
    }

    function markHours(bytes32 _info, bytes32 _description, int _secs) onlyMember {
        if (!hasManagerAccess(msg.sender) && members.memberInfo(msg.sender) != _info) throw;

        adjustHours(_info, _secs);
        MarkHours(msg.sender, _info, _description, _secs);
    }

    function fixHours(bytes32 _info, bytes32 _description, int _secs) onlyDirector {
        adjustHours(_info, _secs);
        FixHours(msg.sender, _info, _description, _secs);
    }

    function processPayroll(address _balanceConverter) onlyDirector {
        IBalanceConverter converter = IBalanceConverter(_balanceConverter);
        SpicePayroll payroll = new SpicePayroll(msg.sender, fromTimestamp);
        for (uint i = 0; i < infoCount; i++) {
            uint secs = balances[infos[i]].total;
            delete balances[infos[i]];

            uint balance = converter.convertBalance(infos[i], secs);
            PayrollLine(msg.sender, infos[i], secs, balance);
            payroll.addLine(infos[i], balance);
        }
        delete infos;

        Payroll(msg.sender, converter, payroll);
        payrolls.push(payroll);
        fromTimestamp = now;
    }
}

pragma solidity ^0.4.2;

import "SpiceControlled.sol";
import "IBalanceConverter.sol";
import "SpicePayroll.sol";

contract SpiceHours is SpiceControlled {
    struct MemberBalance {
        bool available;
        uint total;
    }

    uint public fromTimestamp;
    address[] payrolls;

    mapping (bytes32 => MemberBalance) balances;
    bytes32[] infos;
    uint infoCount;

    event MarkHours(address indexed _sender, bytes32 indexed _info, bytes32 indexed _description, int _secs);
    event FixHours(address indexed _sender, bytes32 indexed _info, bytes32 indexed _description, int _secs);
    event PayrollLine(address indexed _sender, bytes32 indexed _info, uint secs, uint balance);
    event Payroll(address indexed _sender, address _payroll);

    function SpiceHours(address _members) SpiceControlled(_members) {
        fromTimestamp = now;
    }

    function payroll(uint _index) constant returns (address) {
        return payrolls[_index];
    }

    function payrollCount() constant returns (uint) {
        return payrolls.length;
    }

    function balance(bytes32 _info) constant returns (uint) {
        return balances[_info].total;
    }

    function adjustHours(bytes32 _info, int _secs) private {
        if (_info == 0) throw;
        if (_secs == 0) throw;
        if (_secs < 0 && balances[_info].total < uint(-_secs)) throw;

        if (!balances[_info].available) {
            balances[_info].available = true;
            infos.push(_info);
            infoCount++;
        }

        if (_secs < 0) {
            balances[_info].total -= uint(-_secs);
        } else {
            balances[_info].total += uint(_secs);
        }
    }

    function markHours(bytes32 _info, bytes32 _description, int _secs) onlyMember {
        if (!hasManagerAccess(msg.sender) && members.memberInfo(msg.sender) != _info) throw;

        adjustHours(_info, _secs);
        MarkHours(msg.sender, _info, _description, _secs);
    }

    function fixHours(bytes32 _info, bytes32 _description, int _secs) onlyDirector {
        adjustHours(_info, _secs);
        FixHours(msg.sender, _info, _description, _secs);
    }

    function processPayroll(address _balanceConverter) onlyDirector {
        IBalanceConverter converter = IBalanceConverter(_balanceConverter);
        SpicePayroll payroll = new SpicePayroll(msg.sender, fromTimestamp);
        for (uint i = 0; i < infoCount; i++) {
            uint secs = balances[infos[i]].total;
            delete balances[infos[i]];

            uint balance = converter.convertBalance(infos[i], secs);
            PayrollLine(msg.sender, infos[i], secs, balance);
            payroll.addLine(infos[i], balance);
        }
        delete infos;

        Payroll(msg.sender, payroll);
        payrolls.push(payroll);
        fromTimestamp = now;
    }
}


Add claimFee and update capability

Add claimFee and update capability

pragma solidity ^0.4.15;

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

contract StarMarket is Ownable {

// You can use this hash to verify the csv file containing all the stars
    string public csvHash = "";

    address owner;

    string public standard = 'Stars';
    string public name;
    string public symbol;
    uint8 public decimals;
    uint256 public totalSupply;
    uint256 public claimFee;

    uint public nextStarIndexToAssign = 0; // TODO: unused, remove?

    bool public allStarsAssigned = false;
    uint public starsRemainingToAssign = 0;

//mapping (address => uint) public addressToStarIndex;
    mapping (uint => address) public starIndexToAddress;

/* This creates an array with all balances */
    mapping (address => uint256) public balanceOf;

    struct Offer {
    bool isForSale;
    uint starIndex;
    address seller;
    uint minValue;          // in ether
    address onlySellTo;     // specify to sell only to a specific person
    }

    struct Bid {
    bool hasBid;
    uint starIndex;
    address bidder;
    uint value;
    }

// A record of stars that are offered for sale at a specific minimum value, and perhaps to a specific person
    mapping (uint => Offer) public starsOfferedForSale;

// A record of the highest star bid
    mapping (uint => Bid) public starBids;

    mapping (address => uint) public pendingWithdrawals;

    event Assign(address indexed to, uint256 starIndex);
    event Transfer(address indexed from, address indexed to, uint256 value);
    event StarTransfer(address indexed from, address indexed to, uint256 starIndex);
    event StarOffered(uint indexed starIndex, uint minValue, address indexed toAddress);
    event StarBidEntered(uint indexed starIndex, uint value, address indexed fromAddress);
    event StarBidWithdrawn(uint indexed starIndex, uint value, address indexed fromAddress);
    event StarBought(uint indexed starIndex, uint value, address indexed fromAddress, address indexed toAddress);
    event StarNoLongerForSale(uint indexed starIndex);
    event ClaimFeeUpdated(uint256 indexed claimFee);

/* Initializes contract with initial supply tokens to the creator of the contract */
    function StarMarket() payable {
    //        balanceOf[msg.sender] = initialSupply;        // Give the creator all initial tokens
        owner = msg.sender;
        totalSupply = 119615;                               // Update total supply
        starsRemainingToAssign = totalSupply;
        name = "STARS";                                     // Set the name for display purposes
        symbol = "★";                                       // Set the symbol for display purposes
        decimals = 0;                                       // Amount of decimals for display purposes
        claimFee = 15000000000000000;                       // Price of claiming a star
    }

    function setInitialOwner(address to, uint starIndex) onlyOwner {
        if (allStarsAssigned) revert();
        if (starIndex >= totalSupply) revert();
        if (starIndexToAddress[starIndex] != to) {
            if (starIndexToAddress[starIndex] != 0x0) {
                balanceOf[starIndexToAddress[starIndex]]--;
            } else {
                starsRemainingToAssign--;
            }
            starIndexToAddress[starIndex] = to;
            balanceOf[to]++;
            Assign(to, starIndex);
        }
    }

    function setInitialOwners(address[] addresses, uint[] indices) onlyOwner {
        uint n = addresses.length;
        for (uint i = 0; i < n; i++) {
            setInitialOwner(addresses[i], indices[i]);
        }
    }

    function allInitialOwnersAssigned() onlyOwner {
        allStarsAssigned = true;
    }

    function updateCSV(string newHash, uint256 newTotalSupply) onlyOwner {
        csvHash = newHash;
        totalSupply = newTotalSupply;
    }

    function updateClaimFee(uint256 newClaimFee) onlyOwner {
        claimFee = newClaimFee;
        ClaimFeeUpdated(newClaimFee);
    }

    function getStar(uint starIndex) {
        if (!allStarsAssigned) revert();
        if (starsRemainingToAssign == 0) revert();
        if (starIndexToAddress[starIndex] != 0x0) revert();
        if (starIndex >= totalSupply) revert();
        if (msg.value < claimFee) revert();
        pendingWithdrawals[owner] += msg.value;
        starIndexToAddress[starIndex] = msg.sender;
        balanceOf[msg.sender]++;
        starsRemainingToAssign--;
        Assign(msg.sender, starIndex);
    }

// Transfer ownership of a star to another user without requiring payment
    function transferStar(address to, uint starIndex) {
        if (!allStarsAssigned) revert();
        if (starIndexToAddress[starIndex] != msg.sender) revert();
        if (starIndex >= totalSupply) revert();
        if (starsOfferedForSale[starIndex].isForSale) {
            starNoLongerForSale(starIndex);
        }
        starIndexToAddress[starIndex] = to;
        balanceOf[msg.sender]--;
        balanceOf[to]++;
        Transfer(msg.sender, to, 1);
        StarTransfer(msg.sender, to, starIndex);
    // Check for the case where there is a bid from the new owner and refund it.
    // Any other bid can stay in place.
        Bid storage bid = starBids[starIndex];
        if (bid.bidder == to) {
        // Kill bid and refund value
            pendingWithdrawals[to] += bid.value;
            starBids[starIndex] = Bid(false, starIndex, 0x0, 0);
        }
    }

    function starNoLongerForSale(uint starIndex) {
        if (!allStarsAssigned) revert();
        if (starIndexToAddress[starIndex] != msg.sender) revert();
        if (starIndex >= totalSupply) revert();
        starsOfferedForSale[starIndex] = Offer(false, starIndex, msg.sender, 0, 0x0);
        StarNoLongerForSale(starIndex);
    }

    function offerStarForSale(uint starIndex, uint minSalePriceInWei) {
        if (!allStarsAssigned) revert();
        if (starIndexToAddress[starIndex] != msg.sender) revert();
        if (starIndex >= totalSupply) revert();
        starsOfferedForSale[starIndex] = Offer(true, starIndex, msg.sender, minSalePriceInWei, 0x0);
        StarOffered(starIndex, minSalePriceInWei, 0x0);
    }

    function offerStarForSaleToAddress(uint starIndex, uint minSalePriceInWei, address toAddress) {
        if (!allStarsAssigned) revert();
        if (starIndexToAddress[starIndex] != msg.sender) revert();
        if (starIndex >= totalSupply) revert();
        starsOfferedForSale[starIndex] = Offer(true, starIndex, msg.sender, minSalePriceInWei, toAddress);
        StarOffered(starIndex, minSalePriceInWei, toAddress);
    }

    function buyStar(uint starIndex) payable {
        if (!allStarsAssigned) revert();
        Offer storage offer = starsOfferedForSale[starIndex];
        if (starIndex >= totalSupply) revert();
        if (!offer.isForSale) revert();                // star not actually for sale
        if (offer.onlySellTo != 0x0 && offer.onlySellTo != msg.sender) revert();  // star not supposed to be sold to this user
        if (msg.value < offer.minValue) revert();      // Didn't send enough ETH
        if (offer.seller != starIndexToAddress[starIndex]) revert(); // Seller no longer owner of star

        address seller = offer.seller;

        starIndexToAddress[starIndex] = msg.sender;
        balanceOf[seller]--;
        balanceOf[msg.sender]++;
        Transfer(seller, msg.sender, 1);

        starNoLongerForSale(starIndex);
        pendingWithdrawals[seller] += msg.value;
        StarBought(starIndex, msg.value, seller, msg.sender);

    // Check for the case where there is a bid from the new owner and refund it.
    // Any other bid can stay in place.
        Bid storage bid = starBids[starIndex];
        if (bid.bidder == msg.sender) {
        // Kill bid and refund value
            pendingWithdrawals[msg.sender] += bid.value;
            starBids[starIndex] = Bid(false, starIndex, 0x0, 0);
        }
    }

    function withdraw() {
        if (!allStarsAssigned) revert();
        uint amount = pendingWithdrawals[msg.sender];
    // Remember to zero the pending refund before
    // sending to prevent re-entrancy attacks
        pendingWithdrawals[msg.sender] = 0;
        msg.sender.transfer(amount);
    }

    function enterBidForStar(uint starIndex) payable {
        if (starIndex >= totalSupply) revert();
        if (!allStarsAssigned) revert();
        if (starIndexToAddress[starIndex] == 0x0) revert();
        if (starIndexToAddress[starIndex] == msg.sender) revert();
        if (msg.value == 0) revert();
        Bid storage existing = starBids[starIndex];
        if (msg.value <= existing.value) revert();
        if (existing.value > 0) {
        // Refund the failing bid
            pendingWithdrawals[existing.bidder] += existing.value;
        }
        starBids[starIndex] = Bid(true, starIndex, msg.sender, msg.value);
        StarBidEntered(starIndex, msg.value, msg.sender);
    }

    function acceptBidForStar(uint starIndex, uint minPrice) {
        if (starIndex >= totalSupply) revert();
        if (!allStarsAssigned) revert();
        if (starIndexToAddress[starIndex] != msg.sender) revert();
        address seller = msg.sender;
        Bid storage bid = starBids[starIndex];
        if (bid.value == 0) revert();
        if (bid.value < minPrice) revert();

        starIndexToAddress[starIndex] = bid.bidder;
        balanceOf[seller]--;
        balanceOf[bid.bidder]++;
        Transfer(seller, bid.bidder, 1);

        starsOfferedForSale[starIndex] = Offer(false, starIndex, bid.bidder, 0, 0x0);
        uint amount = bid.value;
        starBids[starIndex] = Bid(false, starIndex, 0x0, 0);
        pendingWithdrawals[seller] += amount;
        StarBought(starIndex, bid.value, seller, bid.bidder);
    }

    function withdrawBidForStar(uint starIndex) {
        if (starIndex >= totalSupply) revert();
        if (!allStarsAssigned) revert();
        if (starIndexToAddress[starIndex] == 0x0) revert();
        if (starIndexToAddress[starIndex] == msg.sender) revert();
        Bid storage bid = starBids[starIndex];
        if (bid.bidder != msg.sender) revert();
        StarBidWithdrawn(starIndex, bid.value, msg.sender);
        uint amount = bid.value;
        starBids[starIndex] = Bid(false, starIndex, 0x0, 0);
    // Refund the bid money
        msg.sender.transfer(amount);
    }

}

pragma solidity ^0.4.15;

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

contract StarMarket is Ownable {

// You can use this hash to verify the csv file containing all the stars
    string public csvHash = "";

    address owner;

    string public standard = 'Stars';
    string public name;
    string public symbol;
    uint8 public decimals;
    uint256 public totalSupply;

    uint public nextStarIndexToAssign = 0; // TODO: unused, remove?

    bool public allStarsAssigned = false;
    uint public starsRemainingToAssign = 0;

//mapping (address => uint) public addressToStarIndex;
    mapping (uint => address) public starIndexToAddress;

/* This creates an array with all balances */
    mapping (address => uint256) public balanceOf;

    struct Offer {
    bool isForSale;
    uint starIndex;
    address seller;
    uint minValue;          // in ether
    address onlySellTo;     // specify to sell only to a specific person
    }

    struct Bid {
    bool hasBid;
    uint starIndex;
    address bidder;
    uint value;
    }

// A record of stars that are offered for sale at a specific minimum value, and perhaps to a specific person
    mapping (uint => Offer) public starsOfferedForSale;

// A record of the highest star bid
    mapping (uint => Bid) public starBids;

    mapping (address => uint) public pendingWithdrawals;

    event Assign(address indexed to, uint256 starIndex);
    event Transfer(address indexed from, address indexed to, uint256 value);
    event StarTransfer(address indexed from, address indexed to, uint256 starIndex);
    event StarOffered(uint indexed starIndex, uint minValue, address indexed toAddress);
    event StarBidEntered(uint indexed starIndex, uint value, address indexed fromAddress);
    event StarBidWithdrawn(uint indexed starIndex, uint value, address indexed fromAddress);
    event StarBought(uint indexed starIndex, uint value, address indexed fromAddress, address indexed toAddress);
    event StarNoLongerForSale(uint indexed starIndex);

/* Initializes contract with initial supply tokens to the creator of the contract */
    function StarMarket() payable {
    //        balanceOf[msg.sender] = initialSupply;        // Give the creator all initial tokens
        owner = msg.sender;
        totalSupply = 119615;                               // Update total supply
        starsRemainingToAssign = totalSupply;
        name = "STARS";                                     // Set the name for display purposes
        symbol = "★";                                       // Set the symbol for display purposes
        decimals = 0;                                       // Amount of decimals for display purposes
    }

    function setInitialOwner(address to, uint starIndex) onlyOwner {
        if (allStarsAssigned) revert();
        if (starIndex >= totalSupply) revert();
        if (starIndexToAddress[starIndex] != to) {
            if (starIndexToAddress[starIndex] != 0x0) {
                balanceOf[starIndexToAddress[starIndex]]--;
            } else {
                starsRemainingToAssign--;
            }
            starIndexToAddress[starIndex] = to;
            balanceOf[to]++;
            Assign(to, starIndex);
        }
    }

    function setInitialOwners(address[] addresses, uint[] indices) onlyOwner {
        uint n = addresses.length;
        for (uint i = 0; i < n; i++) {
            setInitialOwner(addresses[i], indices[i]);
        }
    }

    function allInitialOwnersAssigned() onlyOwner {
        allStarsAssigned = true;
    }

    function updateCSV(string newHash, uint256 newTotalSupply) onlyOwner {
        csvHash = newHash;
        totalSupply = newTotalSupply;
    }

    function getStar(uint starIndex) {
        if (!allStarsAssigned) revert();
        if (starsRemainingToAssign == 0) revert();
        if (starIndexToAddress[starIndex] != 0x0) revert();
        if (starIndex >= totalSupply) revert();
        starIndexToAddress[starIndex] = msg.sender;
        balanceOf[msg.sender]++;
        starsRemainingToAssign--;
        Assign(msg.sender, starIndex);
    }

// Transfer ownership of a star to another user without requiring payment
    function transferStar(address to, uint starIndex) {
        if (!allStarsAssigned) revert();
        if (starIndexToAddress[starIndex] != msg.sender) revert();
        if (starIndex >= totalSupply) revert();
        if (starsOfferedForSale[starIndex].isForSale) {
            starNoLongerForSale(starIndex);
        }
        starIndexToAddress[starIndex] = to;
        balanceOf[msg.sender]--;
        balanceOf[to]++;
        Transfer(msg.sender, to, 1);
        StarTransfer(msg.sender, to, starIndex);
    // Check for the case where there is a bid from the new owner and refund it.
    // Any other bid can stay in place.
        Bid storage bid = starBids[starIndex];
        if (bid.bidder == to) {
        // Kill bid and refund value
            pendingWithdrawals[to] += bid.value;
            starBids[starIndex] = Bid(false, starIndex, 0x0, 0);
        }
    }

    function starNoLongerForSale(uint starIndex) {
        if (!allStarsAssigned) revert();
        if (starIndexToAddress[starIndex] != msg.sender) revert();
        if (starIndex >= totalSupply) revert();
        starsOfferedForSale[starIndex] = Offer(false, starIndex, msg.sender, 0, 0x0);
        StarNoLongerForSale(starIndex);
    }

    function offerStarForSale(uint starIndex, uint minSalePriceInWei) {
        if (!allStarsAssigned) revert();
        if (starIndexToAddress[starIndex] != msg.sender) revert();
        if (starIndex >= totalSupply) revert();
        starsOfferedForSale[starIndex] = Offer(true, starIndex, msg.sender, minSalePriceInWei, 0x0);
        StarOffered(starIndex, minSalePriceInWei, 0x0);
    }

    function offerStarForSaleToAddress(uint starIndex, uint minSalePriceInWei, address toAddress) {
        if (!allStarsAssigned) revert();
        if (starIndexToAddress[starIndex] != msg.sender) revert();
        if (starIndex >= totalSupply) revert();
        starsOfferedForSale[starIndex] = Offer(true, starIndex, msg.sender, minSalePriceInWei, toAddress);
        StarOffered(starIndex, minSalePriceInWei, toAddress);
    }

    function buyStar(uint starIndex) payable {
        if (!allStarsAssigned) revert();
        Offer storage offer = starsOfferedForSale[starIndex];
        if (starIndex >= totalSupply) revert();
        if (!offer.isForSale) revert();                // star not actually for sale
        if (offer.onlySellTo != 0x0 && offer.onlySellTo != msg.sender) revert();  // star not supposed to be sold to this user
        if (msg.value < offer.minValue) revert();      // Didn't send enough ETH
        if (offer.seller != starIndexToAddress[starIndex]) revert(); // Seller no longer owner of star

        address seller = offer.seller;

        starIndexToAddress[starIndex] = msg.sender;
        balanceOf[seller]--;
        balanceOf[msg.sender]++;
        Transfer(seller, msg.sender, 1);

        starNoLongerForSale(starIndex);
        pendingWithdrawals[seller] += msg.value;
        StarBought(starIndex, msg.value, seller, msg.sender);

    // Check for the case where there is a bid from the new owner and refund it.
    // Any other bid can stay in place.
        Bid storage bid = starBids[starIndex];
        if (bid.bidder == msg.sender) {
        // Kill bid and refund value
            pendingWithdrawals[msg.sender] += bid.value;
            starBids[starIndex] = Bid(false, starIndex, 0x0, 0);
        }
    }

    function withdraw() {
        if (!allStarsAssigned) revert();
        uint amount = pendingWithdrawals[msg.sender];
    // Remember to zero the pending refund before
    // sending to prevent re-entrancy attacks
        pendingWithdrawals[msg.sender] = 0;
        msg.sender.transfer(amount);
    }

    function enterBidForStar(uint starIndex) payable {
        if (starIndex >= totalSupply) revert();
        if (!allStarsAssigned) revert();
        if (starIndexToAddress[starIndex] == 0x0) revert();
        if (starIndexToAddress[starIndex] == msg.sender) revert();
        if (msg.value == 0) revert();
        Bid storage existing = starBids[starIndex];
        if (msg.value <= existing.value) revert();
        if (existing.value > 0) {
        // Refund the failing bid
            pendingWithdrawals[existing.bidder] += existing.value;
        }
        starBids[starIndex] = Bid(true, starIndex, msg.sender, msg.value);
        StarBidEntered(starIndex, msg.value, msg.sender);
    }

    function acceptBidForStar(uint starIndex, uint minPrice) {
        if (starIndex >= totalSupply) revert();
        if (!allStarsAssigned) revert();
        if (starIndexToAddress[starIndex] != msg.sender) revert();
        address seller = msg.sender;
        Bid storage bid = starBids[starIndex];
        if (bid.value == 0) revert();
        if (bid.value < minPrice) revert();

        starIndexToAddress[starIndex] = bid.bidder;
        balanceOf[seller]--;
        balanceOf[bid.bidder]++;
        Transfer(seller, bid.bidder, 1);

        starsOfferedForSale[starIndex] = Offer(false, starIndex, bid.bidder, 0, 0x0);
        uint amount = bid.value;
        starBids[starIndex] = Bid(false, starIndex, 0x0, 0);
        pendingWithdrawals[seller] += amount;
        StarBought(starIndex, bid.value, seller, bid.bidder);
    }

    function withdrawBidForStar(uint starIndex) {
        if (starIndex >= totalSupply) revert();
        if (!allStarsAssigned) revert();
        if (starIndexToAddress[starIndex] == 0x0) revert();
        if (starIndexToAddress[starIndex] == msg.sender) revert();
        Bid storage bid = starBids[starIndex];
        if (bid.bidder != msg.sender) revert();
        StarBidWithdrawn(starIndex, bid.value, msg.sender);
        uint amount = bid.value;
        starBids[starIndex] = Bid(false, starIndex, 0x0, 0);
    // Refund the bid money
        msg.sender.transfer(amount);
    }

}


add this keywoard

add this keywoard

pragma solidity ^0.4.0;

import "./UserRegistry.sol";
import "./ConceptRegistry.sol";
import "./Assessment.sol";
import "./Math.sol";

//@purpose: To store concept data and create and manage assessments and members
contract Concept {
  address[] public parents; //The concepts that this concept is child to (ie: Calculus is child to Math)
  address[] public children; //The concepts that this concept is parent to (ie: Math is parent to Calculus)
  address userRegistry;
  address conceptRegistry;
  uint public maxWeight;
  address[] public members;
  mapping (address => int) public currentScores;
  mapping (address => bool) public assessmentExists;
  mapping (address => uint) public weights;
  mapping (address => mapping (address => uint)) public approval;

  modifier onlyUserRegistry() {
    if(msg.sender != userRegistry)
    {
      throw;
    }
    _;
  }

  modifier onlyConceptRegistry() {
    if(msg.sender != conceptRegistry) {
      throw;
    }
    _;
  }

  modifier onlyConcept(){
      if(!ConceptRegistry(conceptRegistry).conceptExists(msg.sender)) {
          throw;
      }
      _;
  }

  /*
  @type: event
  @name: CompletedAssessment
  @purpose: To build a database of completed assessments
  */
  event CompletedAssessment (
    address _assessee,
    int _score,
    address _assessment
  );

  function Concept(address[] _parents, address _userRegistry) {
    parents = _parents;
    userRegistry = _userRegistry;
    conceptRegistry = UserRegistry(userRegistry).conceptRegistry();
  }

  function getMemberLength() constant returns(uint) {
    return members.length;
  }

  function getParentsLength() constant returns(uint) {
    return parents.length;
  }

  function getChildrenLength() constant returns(uint) {
    return children.length;
  }

  /*
  @purpose: To add the firstUser to Mew
  */
  function addFirstUser(address user) onlyUserRegistry() {
    if(ConceptRegistry(conceptRegistry).mewAddress() == address(this))
    {
      this.addMember(user, 100);
    }
  }

  function addParent(address _parent) onlyConceptRegistry() {
    parents.push(_parent);
  }

  function addChild(address _child) onlyConceptRegistry() {
    children.push(_child);
  }

  //@purpose: returns a random member of the Concept. Users with high weights are more likely to be called
  function getRandomMember(uint seed) returns(address) {
    address randomUser = members[Math.getRandom(seed, members.length-1)];
    if(UserRegistry(userRegistry).availability(randomUser) && weights[randomUser] > now % maxWeight) {
        return randomUser;
     }
    return address(0x0);
  }
  /*
  @purpose: To make a new assessment
  @param: uint cost = the cost per assessor
  @param: uint size = the number of assessors
  */
  function makeAssessment(uint cost, uint size) returns(bool) {
    if(size >= 5 && this.subtractBalance(msg.sender, cost*size)) {
      Assessment newAssessment = new Assessment(msg.sender, userRegistry, conceptRegistry, size, cost);
      assessmentExists[address(newAssessment)] = true;
      if (Concept(ConceptRegistry(conceptRegistry).mewAddress()).getMemberLength()<size*20){
        newAssessment.setAssessorPoolFromMew(); // simply use all members of mew (Bootstrap phase)
      }
      else{
        newAssessment.setAssessorPool(block.number, address(this), size*20); //assemble the assessorPool by relevance
      }

      return true;
    }
    else {
      return false;
    }
  }

  /*
    @purpose: To approve addresses to create assessments for users on this concept
    @param: _from = the address approved to create assessments
    @param: _amount = the maximum value of Tokens they are allowed to spend
  */
  function approve(address _from, uint _amount) returns(bool) {
    approval[msg.sender][_from] = _amount;
    return true;
  }

  //@purpose: allow approved address to create assessments for users on this concept
  function makeAssessmentFrom(address _assessee, uint _cost, uint _size) returns(bool) {
    if(approval[_assessee][msg.sender] >= _cost * _size &&
       _size >= 5 &&
       this.subtractBalance(_assessee, _cost*_size)) {
        Assessment newAssessment = new Assessment(_assessee, userRegistry, conceptRegistry, _size, _cost);
        assessmentExists[address(newAssessment)] = true;
        newAssessment.setAssessorPool(block.number, address(this), _size*20);
        approval[_assessee][msg.sender] -= _cost*_size;
        return true;
    }
    else {
        return false;
    }
  }
  /*
  @purpose: To finish the assessment process
  @param: int score = the assessee's score
  @param: address assessee = the address of the assessee
  @param: address assessment = the address of the assessment
  @returns: nothing
  */
  function finishAssessment(int score, address assessee, address assessment) {
    /* if(msg.sender == assessment) { */
    if (assessmentExists[msg.sender]) {
      if(score > 0) {
        uint weight = Assessment(assessment).size()*uint(score);
        this.addMember(assessee, weight);
      }
      currentScores[assessee] = score; //Maps the assessee to their score
      UserRegistry(userRegistry).notification(assessee, 7); //Assessment on Concept finished
    }
  }

  /*
  @purpose: To add a member to a concept and recursively add a member to parent concept, halving the added weight with each generation and chinging the macWeight for a concept if neccisairy
  @param: address assessee = the address of the assessee
  @param: uint weight = the weight for the member
  @returns: nothing
  */
  function addMember(address assessee, uint weight) onlyConcept() {
    members.push(assessee);
    weights[assessee] += weight;
    if(weight > maxWeight) {
      maxWeight = weight;
    }
    if (weight/2 > 0){
        for(uint i = 0; i < parents.length; i++) {
            Concept(parents[i]).addMember(assessee, weight/2); //recursively adds member to all parent concepts but with half the weight
        }
    }
  }

  function subtractBalance(address _from, uint _amount) returns(bool) {
    if(assessmentExists[msg.sender] || msg.sender == address(this)) {
      return UserRegistry(userRegistry).subtractBalance(_from, _amount);
    }
    return false;
  }

  function addBalance(address _to, uint _amount)  returns(bool) {
    if(assessmentExists[msg.sender]) {
      return UserRegistry(userRegistry).addBalance(_to, _amount);
    }
  }
}

pragma solidity ^0.4.0;

import "./UserRegistry.sol";
import "./ConceptRegistry.sol";
import "./Assessment.sol";
import "./Math.sol";

//@purpose: To store concept data and create and manage assessments and members
contract Concept {
  address[] public parents; //The concepts that this concept is child to (ie: Calculus is child to Math)
  address[] public children; //The concepts that this concept is parent to (ie: Math is parent to Calculus)
  address userRegistry;
  address conceptRegistry;
  uint public maxWeight;
  address[] public members;
  mapping (address => int) public currentScores;
  mapping (address => bool) public assessmentExists;
  mapping (address => uint) public weights;
  mapping (address => mapping (address => uint)) public approval;

  modifier onlyUserRegistry() {
    if(msg.sender != userRegistry)
    {
      throw;
    }
    _;
  }

  modifier onlyConceptRegistry() {
    if(msg.sender != conceptRegistry) {
      throw;
    }
    _;
  }

  modifier onlyConcept(){
      if(!ConceptRegistry(conceptRegistry).conceptExists(msg.sender)) {
          throw;
      }
      _;
  }

  /*
  @type: event
  @name: CompletedAssessment
  @purpose: To build a database of completed assessments
  */
  event CompletedAssessment (
    address _assessee,
    int _score,
    address _assessment
  );

  function Concept(address[] _parents, address _userRegistry) {
    parents = _parents;
    userRegistry = _userRegistry;
    conceptRegistry = UserRegistry(userRegistry).conceptRegistry();
  }

  function getMemberLength() constant returns(uint) {
    return members.length;
  }

  function getParentsLength() constant returns(uint) {
    return parents.length;
  }

  function getChildrenLength() constant returns(uint) {
    return children.length;
  }

  /*
  @purpose: To add the firstUser to Mew
  */
  function addFirstUser(address user) onlyUserRegistry() {
    if(ConceptRegistry(conceptRegistry).mewAddress() == address(this))
    {
      this.addMember(user, 100);
    }
  }

  function addParent(address _parent) onlyConceptRegistry() {
    parents.push(_parent);
  }

  function addChild(address _child) onlyConceptRegistry() {
    children.push(_child);
  }

  //@purpose: returns a random member of the Concept. Users with high weights are more likely to be called
  function getRandomMember(uint seed) returns(address) {
    address randomUser = members[Math.getRandom(seed, members.length-1)];
    if(UserRegistry(userRegistry).availability(randomUser) && weights[randomUser] > now % maxWeight) {
        return randomUser;
     }
    return address(0x0);
  }
  /*
  @purpose: To make a new assessment
  @param: uint cost = the cost per assessor
  @param: uint size = the number of assessors
  */
  function makeAssessment(uint cost, uint size) returns(bool) {
    if(size >= 5 && subtractBalance(msg.sender, cost*size)) {
      Assessment newAssessment = new Assessment(msg.sender, userRegistry, conceptRegistry, size, cost);
      assessmentExists[address(newAssessment)] = true;
      UserRegistry(userRegistry).notification(address(this), 0); //You have been charged for your assessment

      if (Concept(ConceptRegistry(conceptRegistry).mewAddress()).getMemberLength()<size*20){
        newAssessment.setAssessorPoolFromMew(); // simply use all members of mew (Bootstrap phase)
      }
      else{
        newAssessment.setAssessorPool(block.number, address(this), size*20); //assemble the assessorPool by relevance
      }

      return true;
    }
    else {
      return false;
    }
  }

  /*
    @purpose: To approve addresses to create assessments for users on this concept
    @param: _from = the address approved to create assessments
    @param: _amount = the maximum value of Tokens they are allowed to spend
  */
  function approve(address _from, uint _amount) returns(bool) {
    approval[msg.sender][_from] = _amount;
    return true;
  }

  //@purpose: allow approved address to create assessments for users on this concept
  function makeAssessmentFrom(address _assessee, uint _cost, uint _size) returns(bool) {
    if(approval[_assessee][msg.sender] >= _cost * _size &&
       _size >= 5 &&
       this.subtractBalance(_assessee, _cost*_size)) {
        Assessment newAssessment = new Assessment(_assessee, userRegistry, conceptRegistry, _size, _cost);
        assessmentExists[address(newAssessment)] = true;
        newAssessment.setAssessorPool(block.number, address(this), _size*20);
        approval[_assessee][msg.sender] -= _cost*_size;
        return true;
    }
    else {
        return false;
    }
  }
  /*
  @purpose: To finish the assessment process
  @param: int score = the assessee's score
  @param: address assessee = the address of the assessee
  @param: address assessment = the address of the assessment
  @returns: nothing
  */
  function finishAssessment(int score, address assessee, address assessment) {
    /* if(msg.sender == assessment) { */
    if (assessmentExists[msg.sender]) {
      if(score > 0) {
        uint weight = Assessment(assessment).size()*uint(score);
        this.addMember(assessee, weight);
      }
      currentScores[assessee] = score; //Maps the assessee to their score
      UserRegistry(userRegistry).notification(assessee, 7); //Assessment on Concept finished
    }
  }

  /*
  @purpose: To add a member to a concept and recursively add a member to parent concept, halving the added weight with each generation and chinging the macWeight for a concept if neccisairy
  @param: address assessee = the address of the assessee
  @param: uint weight = the weight for the member
  @returns: nothing
  */
  function addMember(address assessee, uint weight) onlyConcept() {
    members.push(assessee);
    weights[assessee] += weight;
    if(weight > maxWeight) {
      maxWeight = weight;
    }
    if (weight/2 > 0){
        for(uint i = 0; i < parents.length; i++) {
            Concept(parents[i]).addMember(assessee, weight/2); //recursively adds member to all parent concepts but with half the weight
        }
    }
  }

  function subtractBalance(address _from, uint _amount) returns(bool) {
    if(assessmentExists[msg.sender] || msg.sender == address(this)) {
      return UserRegistry(userRegistry).subtractBalance(_from, _amount);
    }
    return false;
  }

  function addBalance(address _to, uint _amount)  returns(bool) {
    if(assessmentExists[msg.sender]) {
      return UserRegistry(userRegistry).addBalance(_to, _amount);
    }
  }
}


mark function public

mark function public

contract SchedulerInterface {
    function scheduleCall(address contractAddress, bytes4 abiSignature, uint targetBlock, uint suggestedGas, uint8 gracePeriod, uint basePayment, uint baseFee) public returns (address);
    function isKnownCall(address callAddress) constant returns (bool);
}

contract CallContractAPI {
    function targetBlock() constant returns (uint);
    function cancel() public;
}

contract Canary {
    uint public aliveSince;
    uint public lastHeartbeat;
    uint public heartbeatCount;
    SchedulerInterface scheduler;
    CallContractAPI callContract;

    address public owner;

    function schedulerAddress() constant returns (address) {
        return address(scheduler);
    }

    function callContractAddress() constant returns (address) {
        return address(callContract);
    }

    function Canary(address _scheduler) {
            owner = msg.sender;
            scheduler = SchedulerInterface(_scheduler);
    }

    function() {
        if (this.balance < 2 ether) {
            owner.send(this.balance);
        }
    }

    function cancel() public {
        // not authorized
        if (msg.sender != owner) throw;
        // need to wait until the
        if (callContract.balance > 0) {
            callContract.cancel();
        }
        owner.send(address(this).balance);

    }

    function initialize() public {
        // ensure we are not already initialized.
        if (aliveSince != 0) return;

        // mark when the canary came to life.
        aliveSince = now;

        // schedule the first call
        scheduleHeartbeat();
    }

    function scheduleHeartbeat() public {
        // schedule the call (~2 hours from now)
        address call_address = scheduler.scheduleCall.value(2 ether)(address(this), 0x3defb962, block.number + 480, 2000000, 255, 1 finney, 0);
        if (call_address != 0x0) {
            callContract = CallContractAPI(call_address);
        }
    }

    function heartbeat() public {
        // Ran out of funds.
        if (this.balance < 2 ether) return;

        // Not being called by the callContract.
        if (msg.sender != address(callContract)) return;

        // The canary has died!
        if (!isAlive()) return;

        // schedule the next call.
        scheduleHeartbeat();

        // Increment the heartbeat count
        heartbeatCount += 1;
    }

    function isAlive() constant returns (bool) {
        return (aliveSince > 0 && block.number < callContract.targetBlock() + 255);
    }
}

contract CanaryV6 is Canary {
    function CanaryV6() Canary(0xe109ecb193841af9da3110c80fdd365d1c23be2a) {
    }
}

contract SchedulerInterface {
    function scheduleCall(address contractAddress, bytes4 abiSignature, uint targetBlock, uint suggestedGas, uint8 gracePeriod, uint basePayment, uint baseFee) public returns (address);
    function isKnownCall(address callAddress) constant returns (bool);
}

contract CallContractAPI {
    function targetBlock() constant returns (uint);
    function cancel() public;
}

contract Canary {
    uint public aliveSince;
    uint public lastHeartbeat;
    uint public heartbeatCount;
    SchedulerInterface scheduler;
    CallContractAPI callContract;

    address public owner;

    function schedulerAddress() constant returns (address) {
        return address(scheduler);
    }

    function callContractAddress() constant returns (address) {
        return address(callContract);
    }

    function Canary(address _scheduler) {
            owner = msg.sender;
            scheduler = SchedulerInterface(_scheduler);
    }

    function() {
        if (this.balance < 2 ether) {
            owner.send(this.balance);
        }
    }

    function cancel() {
        // not authorized
        if (msg.sender != owner) throw;
        // need to wait until the
        if (callContract.balance > 0) {
            callContract.cancel();
        }
        owner.send(address(this).balance);

    }

    function initialize() public {
        // ensure we are not already initialized.
        if (aliveSince != 0) return;

        // mark when the canary came to life.
        aliveSince = now;

        // schedule the first call
        scheduleHeartbeat();
    }

    function scheduleHeartbeat() public {
        // schedule the call (~2 hours from now)
        address call_address = scheduler.scheduleCall.value(2 ether)(address(this), 0x3defb962, block.number + 480, 2000000, 255, 1 finney, 0);
        if (call_address != 0x0) {
            callContract = CallContractAPI(call_address);
        }
    }

    function heartbeat() public {
        // Ran out of funds.
        if (this.balance < 2 ether) return;

        // Not being called by the callContract.
        if (msg.sender != address(callContract)) return;

        // The canary has died!
        if (!isAlive()) return;

        // schedule the next call.
        scheduleHeartbeat();

        // Increment the heartbeat count
        heartbeatCount += 1;
    }

    function isAlive() constant returns (bool) {
        return (aliveSince > 0 && block.number < callContract.targetBlock() + 255);
    }
}

contract CanaryV6 is Canary {
    function CanaryV6() Canary(0xe109ecb193841af9da3110c80fdd365d1c23be2a) {
    }
}


Made SampleCrowdsale a bit clearer. (#1448)

pragma solidity ^0.4.24;

import "../crowdsale/validation/CappedCrowdsale.sol";
import "../crowdsale/distribution/RefundableCrowdsale.sol";
import "../crowdsale/emission/MintedCrowdsale.sol";
import "../token/ERC20/ERC20Mintable.sol";
import "../token/ERC20/ERC20Detailed.sol";

/**
 * @title SampleCrowdsaleToken
 * @dev Very simple ERC20 Token that can be minted.
 * It is meant to be used in a crowdsale contract.
 */
contract SampleCrowdsaleToken is ERC20Mintable, ERC20Detailed {
  constructor() public ERC20Detailed("Sample Crowdsale Token", "SCT", 18) {}
}

/**
 * @title SampleCrowdsale
 * @dev This is an example of a fully fledged crowdsale.
 * The way to add new features to a base crowdsale is by multiple inheritance.
 * In this example we are providing following extensions:
 * CappedCrowdsale - sets a max boundary for raised funds
 * RefundableCrowdsale - set a min goal to be reached and returns funds if it's not met
 * MintedCrowdsale - assumes the token can be minted by the crowdsale, which does so
 * when receiving purchases.
 *
 * After adding multiple features it's good practice to run integration tests
 * to ensure that subcontracts works together as intended.
 */
// XXX There doesn't seem to be a way to split this line that keeps solium
// happy. See:
// https://github.com/duaraghav8/Solium/issues/205
// --elopio - 2018-05-10
// solium-disable-next-line max-len
contract SampleCrowdsale is CappedCrowdsale, RefundableCrowdsale, MintedCrowdsale {

  constructor(
    uint256 openingTime,
    uint256 closingTime,
    uint256 rate,
    address wallet,
    uint256 cap,
    ERC20Mintable token,
    uint256 goal
  )
    public
    Crowdsale(rate, wallet, token)
    CappedCrowdsale(cap)
    TimedCrowdsale(openingTime, closingTime)
    RefundableCrowdsale(goal)
  {
    //As goal needs to be met for a successful crowdsale
    //the value needs to less or equal than a cap which is limit for accepted funds
    require(goal <= cap);
  }
}

pragma solidity ^0.4.24;

import "../crowdsale/validation/CappedCrowdsale.sol";
import "../crowdsale/distribution/RefundableCrowdsale.sol";
import "../crowdsale/emission/MintedCrowdsale.sol";
import "../token/ERC20/ERC20Mintable.sol";

/**
 * @title SampleCrowdsaleToken
 * @dev Very simple ERC20 Token that can be minted.
 * It is meant to be used in a crowdsale contract.
 */
contract SampleCrowdsaleToken is ERC20Mintable {

  string public constant name = "Sample Crowdsale Token";
  string public constant symbol = "SCT";
  uint8 public constant decimals = 18;
}

/**
 * @title SampleCrowdsale
 * @dev This is an example of a fully fledged crowdsale.
 * The way to add new features to a base crowdsale is by multiple inheritance.
 * In this example we are providing following extensions:
 * CappedCrowdsale - sets a max boundary for raised funds
 * RefundableCrowdsale - set a min goal to be reached and returns funds if it's not met
 *
 * After adding multiple features it's good practice to run integration tests
 * to ensure that subcontracts works together as intended.
 */
// XXX There doesn't seem to be a way to split this line that keeps solium
// happy. See:
// https://github.com/duaraghav8/Solium/issues/205
// --elopio - 2018-05-10
// solium-disable-next-line max-len
contract SampleCrowdsale is CappedCrowdsale, RefundableCrowdsale, MintedCrowdsale {

  constructor(
    uint256 openingTime,
    uint256 closingTime,
    uint256 rate,
    address wallet,
    uint256 cap,
    ERC20Mintable token,
    uint256 goal
  )
    public
    Crowdsale(rate, wallet, token)
    CappedCrowdsale(cap)
    TimedCrowdsale(openingTime, closingTime)
    RefundableCrowdsale(goal)
  {
    //As goal needs to be met for a successful crowdsale
    //the value needs to less or equal than a cap which is limit for accepted funds
    require(goal <= cap);
  }
}


test add invalid library address or duplicated version label

pragma solidity ^0.4.23;

import "truffle/Assert.sol";
import "../contracts/SwapyExchange.sol";
import "./helpers/ThrowProxy.sol";

contract TestSwapyExchange_versioning {
    SwapyExchange protocol = new SwapyExchange(address(0x281055afc982d96fab65b3a49cac8b878184cb16),"1.0.0",address(0x6f46cf5569aefa1acc1009290c8e043747172d89));
    ThrowProxy throwProxy = new ThrowProxy(address(protocol));
    SwapyExchange throwableProtocol = SwapyExchange(address(throwProxy));

    // Truffle looks for `initialBalance` when it compiles the test suite
    // and funds this test contract with the specified amount on deployment.
    uint public initialBalance = 10 ether;

    function shouldThrow(bool execution) private {
        Assert.isFalse(execution, "Should throw an exception");
    }
    // Testing the addLibrary() function
    function testOnlyProtocolOwnerCanAddLibrary() public {
        address lib2 = address(0x8f46cf5569aefa1acc1009290c8e043747172d45);
        address(throwableProtocol).call(abi.encodeWithSignature("addLibrary(bytes8,address)", bytes8("3.0.0"), lib2));
        throwProxy.shouldThrow();
    }

    function testProtocolOwnerCanAddLibraryVersion() public {
        address lib3 = address(0x9f46cf5569aefa1acc1009290c8e043747172d45);
        bool result = protocol.addLibrary(bytes8("3.0.0"), lib3);
        bytes8 latestVersion = protocol.latestVersion();
        address latestLib = protocol.getLibrary(latestVersion);
        bool check = (latestVersion == bytes8("3.0.0")) && (latestLib == address(lib3));
        Assert.equal(check, true, "The latest version must be 3.0.0 and the library address of this version must be equal the lastest deployed library");
    }

    function testOwnerCannotAddDuplicatedVersion() public {
        address lib3 = address(0x9f46cf5569aefa1acc1009290c8e043747172d45);
        bool result = address(protocol).call(abi.encodeWithSignature("addLibrary(bytes8,address)", bytes8("3.0.0"), lib3));
        shouldThrow(result);
    }

    function testOwnerCannotAddInvalidLibrary() public {
        bool result = address(protocol).call(abi.encodeWithSignature("addLibrary(bytes8,address)", bytes8("3.0.0"), address(0)));
        shouldThrow(result);
    }

}

pragma solidity ^0.4.23;

import "truffle/Assert.sol";
import "../contracts/SwapyExchange.sol";
import "./helpers/ThrowProxy.sol";

contract TestSwapyExchange_versioning {
    SwapyExchange protocol = new SwapyExchange(address(0x281055afc982d96fab65b3a49cac8b878184cb16),"1.0.0",address(0x6f46cf5569aefa1acc1009290c8e043747172d89));
    ThrowProxy throwProxy = new ThrowProxy(address(protocol));
    SwapyExchange throwableProtocol = SwapyExchange(address(throwProxy));

    // Truffle looks for `initialBalance` when it compiles the test suite
    // and funds this test contract with the specified amount on deployment.
    uint public initialBalance = 10 ether;

    bytes msgData;
    function() payable public {
        msgData = msg.data;
    }

    // Testing the addLibrary() function
    function testOnlyProtocolOwnerCanAddLibrary() public {
        address lib2 = address(0x8f46cf5569aefa1acc1009290c8e043747172d45);
        address(throwableProtocol).call(abi.encodeWithSignature("addLibrary(bytes8,address)", bytes8("3.0.0"), lib2));
        throwProxy.shouldThrow();
    }

    function testProtocolOwnerCanAddLibraryVersion() public {
        address lib3 = address(0x9f46cf5569aefa1acc1009290c8e043747172d45);
        bool result = protocol.addLibrary(bytes8("3.0.0"), lib3);
        bytes8 latestVersion = protocol.latestVersion();
        address latestLib = protocol.getLibrary(latestVersion);
        bool check = (latestVersion == bytes8("3.0.0")) && (latestLib == address(lib3));
        Assert.equal(check, true, "The latest version must be 2.0.0 and the library address of this version must be equal the lastest deployed library");
    }

}