quickFix: remove extranoues comment

quickFix: remove extranoues comment

pragma solidity ^0.4.11;

import "./Math.sol";
import "./Concept.sol";
import "./FathomToken.sol";

contract Assessment {
    address public assessee;
    address[] assessors;

    mapping (address => State) public assessorState;
    State public assessmentStage;
    enum State {
        None,
        Called,
        Confirmed,
        Committed,
        Done,
        Burned
    }

    address concept;
    address fathomToken;

    uint public endTime;
    // will keep track of timelimits for 1) latest possible time to confirm and
    // 2) earliest time to reveal
    uint public checkpoint;
    uint public size;
    uint public cost;

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

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

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

    function Assessment(address _assessee,
                        uint _size,
                        uint _cost,
                        uint _confirmTime,
                        uint _timeLimit) {
        assessee = _assessee;
        concept = msg.sender;
        fathomToken = Concept(concept).fathomToken();

        endTime = now + _timeLimit;
        // set checkpoint to latest possible time to confirm
        checkpoint = now + _confirmTime;
        assert(checkpoint < endTime);

        size = _size;
        cost = _cost;

        FathomToken(fathomToken).notification(assessee, 0); // assesse has started an assessment
        done = 0;
    }

    // ends the assessment, refunds the assessee and all assessors who have not been burned
    function cancelAssessment() private {
        uint assesseeRefund = assessmentStage == State.Called ? cost * size : cost * assessors.length; //in later stages size can be reduced by burned assessors
        FathomToken(fathomToken).transfer(assessee, assesseeRefund);
        FathomToken(fathomToken).notification(assessee, 3); //Assessment Cancelled and you have been refunded
        for (uint i = 0; i < assessors.length; i++) {
            if (assessorState[assessors[i]] != State.Burned) {
                FathomToken(fathomToken).transfer(assessors[i], cost);
                FathomToken(fathomToken).notification(assessors[i], 3); //Assessment Cancelled and you have been refunded
            }
        }
        suicide(concept);
    }

    //adds a user to the pool eligible to accept an assessment
    function addAssessorToPool(address assessor) internal returns(bool) {
        if (assessor != assessee && assessorState[assessor] == State.None) {
            FathomToken(fathomToken).notification(assessor, 1); //Called As A Potential Assessor
            assessorState[assessor] = State.Called;
            return true;
        }
    }

    /*
      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 total number of assessors to be called
    */
    function setAssessorPool(uint seed, address _concept, uint num) public onlyConcept() {
        uint numCalled = 0;
        uint membersOfConcept = Concept(_concept).getMemberLength();
        //we want to call at most half of the members of each concept
        uint maxFromThisPool = num > membersOfConcept/2 ? membersOfConcept/2 : num;
        for (uint k=0; k < maxFromThisPool; k++) {
            address randomUser = Concept(_concept).getWeightedRandomMember(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 + numCalled + i, Concept(_concept).parents(i), remaining/Concept(_concept).getParentsLength() + 1); //Calls the remaining users from the parent concepts proportional to their size
            }
        }
        assessmentStage = State.Called;
    }

    /*
      Function to call all members of mew to be assessors. Will be removed after
      the alpha-testing phase.
    */
    function callAllFromMew(uint _nMew, address _mew) public onlyConcept() {
        Concept mew = Concept(_mew);
        for (uint i=0; i< _nMew; i++) {
            addAssessorToPool(mew.members(i));
        }
        assessmentStage = State.Called;
    }

    // called by an assessor to confirm and stake
    function confirmAssessor() public onlyInStage(State.Called) {
        // cancel if the assessment is past its startTime
        if (now > checkpoint){
            cancelAssessment();
            return;
        }
        if (assessorState[msg.sender] == State.Called &&
            assessors.length < size &&
            FathomToken(fathomToken).takeBalance(msg.sender, address(this), cost, concept)
            ) {
            assessors.push(msg.sender);
            assessorState[msg.sender] = State.Confirmed;
            FathomToken(fathomToken).notification(msg.sender, 2); //Confirmed for assessing, stake has been taken
        }
        if (assessors.length == size) {
            notifyAssessors(uint(State.Confirmed), 4);
            FathomToken(fathomToken).notification(assessee, 4);
            assessmentStage = State.Confirmed;
        }
    }
    //called by an assessor to commit a hash of their score //TODO explain in more detail what's happening
    function commit(bytes32 _hash) public onlyInStage(State.Confirmed) {
        if (now > endTime) {
            burnStakes(State.Confirmed);
        }
        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) {
            //set checkpoint to end of 12 hour challenge period after which scores can be revealed
            checkpoint = now + 12 hours;
            notifyAssessors(uint(State.Committed), 5);
            done = 0; //Resets the done counter
            assessmentStage = State.Committed;
        }
    }

    function steal(int128 _score, string _salt, address assessor) public{
        if(assessorState[assessor] == State.Committed) {
            if(commits[assessor] == sha3(_score, _salt)) {
                FathomToken(fathomToken).transfer(msg.sender, cost/2);
                assessorState[assessor] = State.Burned;
                size--;
            }
        }
    }

    //@purpose: called by assessors to reveal their own commits or others
    // must be called between 12 hours after the latest commit and 24 hours after the
    // end of the assessment. If the last commit happens during at the last possible
    // point in time (right before endtime), this period will be 12hours
    function reveal(int128 _score, string _salt) public onlyInStage(State.Committed) {
        // scores can only be revealed after the challenge period has passed
        require(now > checkpoint);
        // If the time to reveal has passed, burn all unrevealed assessors
        if (now > endTime + 24 hours) {
            burnStakes(State.Committed);
        }

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

    //burns stakes of all assessors who are in a certain state
    function burnStakes(State _state) private {
        for (uint i = 0; i < assessors.length; i++) {
            if (assessorState[assessors[i]] == _state) {
                burnAssessor(assessors[i]);
           }
        }
    }

    /** mark an assessor as burned, reduce size and cancel assessment
        if the size is below five.
        @param _assessor address of the assessor to be burned
    */
    function burnAssessor(address _assessor) private {
        assessorState[_assessor] = State.Burned;
        if (--size < 5) {
            cancelAssessment();
        }
    }

    function notifyAssessors(uint _state, uint _topic) private {
        for (uint i=0; i < assessors.length; i++) {
            if (uint(assessorState[assessors[i]]) == _state) {
                FathomToken(fathomToken).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 = Math.calculateMAD(finalScores);
        uint finalClusterLength;
        (finalScore, finalClusterLength) = Math.getFinalScore(finalScores, mad);
        payout(mad, finalClusterLength);
        if (finalScore > 0) {
            Concept(concept).addMember(assessee, uint(finalScore) * finalClusterLength);
        }
        FathomToken(fathomToken).notification(assessee, 7);
   }

    function payout(uint mad, uint finalClusterLength) onlyInStage(State.Done) public {
        uint q = 1; //INFLATION RATE
        uint dissentBonus = 0;
        bool[] memory inAssessor = new bool[] (assessors.length);
        uint[] memory inAssessorPayout = new uint[] (assessors.length);
        // pay out dissenting assessors their reduced stake and save how much stake to redistribute to whom
        for (uint i = 0; i < assessors.length; i++) {
            if (assessorState[assessors[i]] == State.Done) {
                uint payoutValue;
                bool dissenting;
                (payoutValue, dissenting) = Math.getPayout(Math.abs(scores[assessors[i]] - finalScore), mad, cost, q);
                if (dissenting) {
                    dissentBonus += cost - payoutValue;
                    if (payoutValue > 0) {
                        FathomToken(fathomToken).transfer(assessors[i], payoutValue);
                    }
                    FathomToken(fathomToken).notification(assessors[i], 6); //All have revealed; Tokens paid out
                } else {
                    inAssessor[i] = true;
                    inAssessorPayout[i] = payoutValue;
                }
            }
        }
        // pay out the majority-assessors their share of stake + the remainders of any dissenting assessors
        for (uint j = 0; j < inAssessorPayout.length; j++) {
            if (inAssessor[j]) {
                FathomToken(fathomToken).transfer(assessors[j],
                                                    inAssessorPayout[j] + dissentBonus/finalClusterLength);
                FathomToken(fathomToken).notification(assessors[j], 6); //All have revealed; Tokens paid out
            }
        }
    }
}

pragma solidity ^0.4.11;

import "./Math.sol";
import "./Concept.sol";
import "./FathomToken.sol";

contract Assessment {
    address public assessee;
    address[] assessors;

    mapping (address => State) public assessorState;
    State public assessmentStage;
    enum State {
        None,
        Called,
        Confirmed,
        Committed,
        Done,
        Burned
    }

    address concept;
    address fathomToken;

    uint public endTime;
    // will keep track of timelimits for 1) latest possible time to confirm and
    // 2) earliest time to reveal
    uint public checkpoint;
    uint public size;
    uint public cost;

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

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

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

    function Assessment(address _assessee,
                        uint _size,
                        uint _cost,
                        uint _confirmTime,
                        uint _timeLimit) {
        assessee = _assessee;
        concept = msg.sender;
        fathomToken = Concept(concept).fathomToken();

        endTime = now + _timeLimit;
        // set checkpoint to latest possible time to confirm
        checkpoint = now + _confirmTime;
        assert(checkpoint < endTime);

        size = _size;
        cost = _cost;

        FathomToken(fathomToken).notification(assessee, 0); // assesse has started an assessment
        done = 0;
    }

    // ends the assessment, refunds the assessee and all assessors who have not been burned
    function cancelAssessment() private {
        uint assesseeRefund = assessmentStage == State.Called ? cost * size : cost * assessors.length; //in later stages size can be reduced by burned assessors
        FathomToken(fathomToken).transfer(assessee, assesseeRefund);
        FathomToken(fathomToken).notification(assessee, 3); //Assessment Cancelled and you have been refunded
        for (uint i = 0; i < assessors.length; i++) {
            if (assessorState[assessors[i]] != State.Burned) {
                FathomToken(fathomToken).transfer(assessors[i], cost);
                FathomToken(fathomToken).notification(assessors[i], 3); //Assessment Cancelled and you have been refunded
            }
        }
        suicide(concept);
    }

    //adds a user to the pool eligible to accept an assessment
    // function addAssessorToPool(address assessor) public onlyConcept() returns(bool) {
    function addAssessorToPool(address assessor) internal returns(bool) {
        if (assessor != assessee && assessorState[assessor] == State.None) {
            FathomToken(fathomToken).notification(assessor, 1); //Called As A Potential Assessor
            assessorState[assessor] = State.Called;
            return true;
        }
    }

    /*
      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 total number of assessors to be called
    */
    function setAssessorPool(uint seed, address _concept, uint num) public onlyConcept() {
        uint numCalled = 0;
        uint membersOfConcept = Concept(_concept).getMemberLength();
        //we want to call at most half of the members of each concept
        uint maxFromThisPool = num > membersOfConcept/2 ? membersOfConcept/2 : num;
        for (uint k=0; k < maxFromThisPool; k++) {
            address randomUser = Concept(_concept).getWeightedRandomMember(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 + numCalled + i, Concept(_concept).parents(i), remaining/Concept(_concept).getParentsLength() + 1); //Calls the remaining users from the parent concepts proportional to their size
            }
        }
        assessmentStage = State.Called;
    }

    /*
      Function to call all members of mew to be assessors. Will be removed after
      the alpha-testing phase.
    */
    function callAllFromMew(uint _nMew, address _mew) public onlyConcept() {
        Concept mew = Concept(_mew);
        for (uint i=0; i< _nMew; i++) {
            addAssessorToPool(mew.members(i));
        }
        assessmentStage = State.Called;
    }

    // called by an assessor to confirm and stake
    function confirmAssessor() public onlyInStage(State.Called) {
        // cancel if the assessment is past its startTime
        if (now > checkpoint){
            cancelAssessment();
            return;
        }
        if (assessorState[msg.sender] == State.Called &&
            assessors.length < size &&
            FathomToken(fathomToken).takeBalance(msg.sender, address(this), cost, concept)
            ) {
            assessors.push(msg.sender);
            assessorState[msg.sender] = State.Confirmed;
            FathomToken(fathomToken).notification(msg.sender, 2); //Confirmed for assessing, stake has been taken
        }
        if (assessors.length == size) {
            notifyAssessors(uint(State.Confirmed), 4);
            FathomToken(fathomToken).notification(assessee, 4);
            assessmentStage = State.Confirmed;
        }
    }
    //called by an assessor to commit a hash of their score //TODO explain in more detail what's happening
    function commit(bytes32 _hash) public onlyInStage(State.Confirmed) {
        if (now > endTime) {
            burnStakes(State.Confirmed);
        }
        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) {
            //set checkpoint to end of 12 hour challenge period after which scores can be revealed
            checkpoint = now + 12 hours;
            notifyAssessors(uint(State.Committed), 5);
            done = 0; //Resets the done counter
            assessmentStage = State.Committed;
        }
    }

    function steal(int128 _score, string _salt, address assessor) public{
        if(assessorState[assessor] == State.Committed) {
            if(commits[assessor] == sha3(_score, _salt)) {
                FathomToken(fathomToken).transfer(msg.sender, cost/2);
                assessorState[assessor] = State.Burned;
                size--;
            }
        }
    }

    //@purpose: called by assessors to reveal their own commits or others
    // must be called between 12 hours after the latest commit and 24 hours after the
    // end of the assessment. If the last commit happens during at the last possible
    // point in time (right before endtime), this period will be 12hours
    function reveal(int128 _score, string _salt) public onlyInStage(State.Committed) {
        // scores can only be revealed after the challenge period has passed
        require(now > checkpoint);
        // If the time to reveal has passed, burn all unrevealed assessors
        if (now > endTime + 24 hours) {
            burnStakes(State.Committed);
        }

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

    //burns stakes of all assessors who are in a certain state
    function burnStakes(State _state) private {
        for (uint i = 0; i < assessors.length; i++) {
            if (assessorState[assessors[i]] == _state) {
                burnAssessor(assessors[i]);
           }
        }
    }

    /** mark an assessor as burned, reduce size and cancel assessment
        if the size is below five.
        @param _assessor address of the assessor to be burned
    */
    function burnAssessor(address _assessor) private {
        assessorState[_assessor] = State.Burned;
        if (--size < 5) {
            cancelAssessment();
        }
    }

    function notifyAssessors(uint _state, uint _topic) private {
        for (uint i=0; i < assessors.length; i++) {
            if (uint(assessorState[assessors[i]]) == _state) {
                FathomToken(fathomToken).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 = Math.calculateMAD(finalScores);
        uint finalClusterLength;
        (finalScore, finalClusterLength) = Math.getFinalScore(finalScores, mad);
        payout(mad, finalClusterLength);
        if (finalScore > 0) {
            Concept(concept).addMember(assessee, uint(finalScore) * finalClusterLength);
        }
        FathomToken(fathomToken).notification(assessee, 7);
   }

    function payout(uint mad, uint finalClusterLength) onlyInStage(State.Done) public {
        uint q = 1; //INFLATION RATE
        uint dissentBonus = 0;
        bool[] memory inAssessor = new bool[] (assessors.length);
        uint[] memory inAssessorPayout = new uint[] (assessors.length);
        // pay out dissenting assessors their reduced stake and save how much stake to redistribute to whom
        for (uint i = 0; i < assessors.length; i++) {
            if (assessorState[assessors[i]] == State.Done) {
                uint payoutValue;
                bool dissenting;
                (payoutValue, dissenting) = Math.getPayout(Math.abs(scores[assessors[i]] - finalScore), mad, cost, q);
                if (dissenting) {
                    dissentBonus += cost - payoutValue;
                    if (payoutValue > 0) {
                        FathomToken(fathomToken).transfer(assessors[i], payoutValue);
                    }
                    FathomToken(fathomToken).notification(assessors[i], 6); //All have revealed; Tokens paid out
                } else {
                    inAssessor[i] = true;
                    inAssessorPayout[i] = payoutValue;
                }
            }
        }
        // pay out the majority-assessors their share of stake + the remainders of any dissenting assessors
        for (uint j = 0; j < inAssessorPayout.length; j++) {
            if (inAssessor[j]) {
                FathomToken(fathomToken).transfer(assessors[j],
                                                    inAssessorPayout[j] + dissentBonus/finalClusterLength);
                FathomToken(fathomToken).notification(assessors[j], 6); //All have revealed; Tokens paid out
            }
        }
    }
}


more syntax

more syntax

pragma solidity ^0.4.11;
//import "./StandardToken.sol";
// import "./PartialLockVoting.sol";
// import "./Parametrizer.sol";

// to do:
// implement events
// check on delete in solidity
// keep deposit if never challenged (?) if win (?)

contract Registry {

    /*
     * Storage
     */

    //Registry storage
    StandardToken public token;
    mapping(bytes32 => Publisher) public whitelist;
    mapping(bytes32 => Application) public appPool;
    mapping(uint => bool) public voteProcessed;
    mapping(address => mapping(uint => bool)) public voterInfo;
    //Parameter storage
    mapping(bytes32 => Application) public Proposals; // similar to appPool
    mapping(bytes32 => uint) public Parameters;

    struct Publisher {
        address owner;
        uint expTime;
        uint deposit;
    }

    struct Application {
        address owner;
        bool challenged;
        uint challengeTime; //End of challenge period
        address challenger;
        Param snapshot;
    }

    struct Param {
        // parameters concerning the whitelist and application pool
        uint minDeposit;
        uint challengeLen;
        uint registryLen;

        // parameters to be passed into the voting contract
        uint commitVoteLen;
        uint revealVoteLen;
        uint majority;

        // parameter representing the scale of how token rewards are distributed
        uint dispensationPct;
    }

    // Constructor
    /// @param _minDeposit      application & challenger deposit amounts
    /// @param _challengeLen    duration of the challenge period
    /// @param _registryLen     duration of a registration’s validity
    /// @param _commitVoteLen   duration of the commit period in token votes
    /// @param _revealVoteLen   duration of reveal period in token votes
    /// @param _dispensationPct percentage of forfeited deposit distributed to winning party; uint between 0 and 100
    /// @param _majority        percentage of votes that constitutes the majority; uint between 0 and 100

    function Registry(address _token,
       uint _minDeposit,
       uint _challengeLen,
       uint _registryLen,
       uint _commitVoteLen,
       uint _revealVoteLen,
       uint _dispensationPct,
       uint _majority) {

       token = StandardToken(_token);
       // initialize values
       Parameters[sha3("minDeposit")]        = _minDeposit;
       Parameters[sha3("challengeLen")]      = _challengeLen;
       Parameters[sha3("registryLen")]       = _registryLen;
       Parameters[sha3("commitVoteLen")]     = _commitVoteLen;
       Parameters[sha3("revealVoteLen")]     = _revealVoteLen;
       Parameters[sha3("dispensationPct")]   = _dispensationPct;
       Parameters[sha3("majority")]          = _majority;
    }

    // called by an applicant to apply (moves them into the application pool on success)
    function apply(string _domain) {
        bytes32 domainHash = sha3(_domain);
        // applicant must pay the current value of minDeposit
        uint deposit = get("minDeposit");
        // check to prevent repeat applications
        require(appPool[domainHash].owner == 0);
        // check that registry can take sufficient amount of tokens from the applicant
        require(token.allowance(msg.sender, this) >= deposit);
        token.transferFrom(msg.sender, this, deposit);
        // initialize application with a snapshot with the current values of all parameters
        initializeSnapshot(_domain);
        appPool[domainHash].challengeTime = now + appPool[domainHash].snapshot.challengeLen;
        appPool[domainHash].owner = msg.sender;
    }

    // called by any adtoken holder to challenge an application to the whitelist and start a vote
    function challenge(string _domain) {
        bytes32 domainHash = sha3(_domain);
        // check that registry can take sufficient amount of tokens from the challenger
        uint deposit = appPool[domainHash].snapshot.minDeposit;
        require(token.allowance(msg.sender, this) >= deposit);
        token.transferFrom(msg.sender, this, deposit);
        // prevent someone from challenging an unintialized application, rechallenging,
        // or challenging after the challenge period has ended
        require(appPool[domainHash].owner != 0);
        require(appPool[domainHash].challenged == false);
        require(appPool[domainHash].challengeTime > now);
        // update the application's status
        appPool[domainHash].challenged = true;
        appPool[domainHash].challenger = msg.sender;
        // start a vote
        // poll ID = callVote(voting params);
    }

    // helper function to the challenge() function. Initializes a vote through the voting contract
    function callVote(bytes32 _domainHash) private returns (bool) {
        // event that vote has started
        // ??
    }

    // a one-time function for each completed vote
    // if domain won: domain is moved to the whitelist and applicant is rewarded tokens
    // if domain lost: challenger is rewarded tokens
    function processResult(uint _pollID)
    {
        require(voteProcessed[_pollID] == false);
        // string domain = ??;
        bytes32 domainHash = sha3(domain);
        if (didProposalPass(_pollID)) {
            //??what would happen if didProposalPass() called and vote's still ongoing??
            // add to registry
            add(domain, appPool[domainHash].owner);
            delete appPool[domainHash].owner;
            // give tokens to applicant based on dist and total tokens
        }
        else {
            delete appPool[domainHash].owner;
            deposit = appPool[domainHash].snapshot[minDeposit];
            winning = appPool[domainHash].snapshot[minDeposit]*appPool[domainHash].snapshot[dispensationPct];
            tokens.transfer(appPool[domainHash].challenger, winning+ deposit);
            // check math
        }
        // ensures the result cannot be processed again
        voteProcessed[_pollID] = true;
    }

    // called by each voter to claim their reward for each completed vote
    function claimReward(uint _pollID, uint _salt) {
        // checks if a voter has claimed tokens
        require(voterInfo[msg.sender][_pollID] == false);
        uint reward = giveTokens(_pollID, _salt);
        // ensures a voter cannot claim tokens again
        transfer(msg.sender, reward);
        voterInfo[msg.sender][_pollID] = true;
    }

    // called to move an applying domain to the whitelist
    // iff the domain's challenge period has passed without a challenge
    function moveToRegistry(string _domain) {
        bytes32 domainHash = sha3(_domain);
        require(appPool[domainHash].challengeTime < now);
        require(appPool[domainHash].challenged == false);
        // prevents moving a domain to the registry without ever applying
        require(appPool[domainHash].owner != 0);
        // prevent applicant from moving to registry multiple times
        add(_domain, appPool[domainHash].owner);
        delete appPool[domainHash].owner;
    }

    // private function to add a domain name to the whitelist
    function add(string _domain, address _owner)  {
        bytes32 domainHash = sha3(_domain);
        uint expiration = appPool[domainHash].snapshot.registryLen;
        whitelist[domainHash].expTime = now + expiration;
        whitelist[domainHash].owner = _owner;
        whitelist[domainHash].deposit = appPool[domainHash].snapshot.minDeposit;
    }

    // checks if a domain name is in the whitelist and unexpired
    function isVerified(string _domain) returns (bool) {
        bytes32 domainHash = sha3(_domain);
        if (whitelist[domainHash].expTime > now) {
            return true;
        }
        else {
            return false;
        }
    }

    // private function to initialize a snapshot of parameters for each application
    function initializeSnapshot(string _domain) {
        bytes32 domainHash = sha3(_domain);
        appPool[domainHash].snapshot.minDeposit = get("minDeposit");
        appPool[domainHash].snapshot.challengeLen = get("challengeLen");
        appPool[domainHash].snapshot.registryLen = get("registryLen");
        appPool[domainHash].snapshot.commitVoteLen = get("commitVoteLen");
        appPool[domainHash].snapshot.revealVoteLen = get("revealVoteLen");
        appPool[domainHash].snapshot.majority = get("majority");
        appPool[domainHash].snapshot.dispensationPct = get("dispensationPct");
    }

    function giveTokens(uint _pollID, uint _salt) returns(uint) {
        // number of tokens person used to vote / total number of tokens for winning side
        // scale using distribution number
        // give the tokens
        // string domain = ??
        bytes32 domainHash = sha3(domain);
        uint minDeposit = appPool[domainHash].snapshot[minDeposit];
        uint dispensationPct = appPool[domainHash].snapshot[dispensationPct];
        uint totalTokens = getTotalNumberOfTokensForWinningOption(_pollID);
        uint voterTokens = getNumCorrectInvestment(_pollID, _salt);

        uint reward = voterTokens*minDeposit*(1-dispensationPct)/totalTokens;
        return reward;
    }

    // FOR TESTING
    function toHash(string _domain) returns (bytes32){
        return sha3(_domain);
    }
    function getCurrentTime() returns (uint){
        return now;
    }

/*******************************************************************/

    //called by a user who wishes to change a parameter
    //initializes a proposal to change a parameter
    function proposeUpdate(string _parameter, uint _value) {
        bytes32 parameterHash = sha3(_parameter, _value);
        // applicant must pay the current value of minDeposit
        uint deposit = get("minDeposit");
        // check that registry can take sufficient amount of tokens from the applicant
        require(token.allowance(msg.sender, this) >= deposit);
        token.transferFrom(msg.sender, this, deposit);
        // initialize application with a snapshot with the current values of all parameters
        initializeSnapshotParam(parameterHash);
        uint challengeLen = Proposals[parameterHash].snapshot[challengeLen];
        Proposals[parameterHash].challengeTime= now + challengeLen;
        Proposals[parameterHash].owner = msg.sender;

    }

    //called by user who wishes to reject a proposal
    //initializes a vote to accept/reject the param change proposal
    function challengeProposal(string _parameter, uint _value) {
        bytes32 parameterHash = sha3(_parameter, _value);

        // check that registry can take sufficient amount of tokens from the challenger
        uint deposit = Proposals[parameterHash ].snapshot.minDeposit;
        require(token.allowance(msg.sender, this) >= deposit);
        token.transferFrom(msg.sender, this, deposit);

        // prevent someone from challenging an unintialized application, rechallenging,
        // or challenging after the challenge period has ended
        require(Proposals[parameterHash].owner != 0);
        require(Proposals[parameterHash].challenged == false);
        require(Proposals[parameterHash].challengeTime> now);

        // update the application's status
        Proposals[parameterHash].challenged = true;
        Proposals[parameterHash].challenger = msg.sender;
        // start a vote
        // poll ID = callVote(voting params);
    }

    // called to change parameter
    // iff the proposal's challenge period has passed without a challenge
    function setParams(string _parameter, uint _value) {
        bytes32 parameterHash = sha3(_parameter, _value);
        require(Proposals[parameterHash].challengeTime < now);
        require(Proposals[parameterHash].challenged == false);
        // prevents moving a domain to the registry without ever applying
        require(Proposals[parameterHash].owner != 0);
        // prevent applicant from moving to registry multiple times
        Parameters[sha3(_parameter)] = _value;
        delete Proposals[parameterHash].owner;
    }

    // a one-time function for each completed vote
    // if proposal won: new parameter value is set, and applicant is rewarded tokens
    // if prospsal lost: challenger is rewarded tokens
    function processProposal(uint _pollID)
    {
        require(voteProcessed[_pollID] == false);
        // string parameter = ??;
        //uint value = ??
        bytes32 parameterHash = sha3(parameter, value);
        if (didProposalPass(_pollID)) {
            //??what would happen if didProposalPass() called and vote's still ongoing??
            // setting the value of parameter
            Parameters[sha3(parameter)] = value;
            delete Proposals[parameterHash].owner;
            // give tokens to applicant based on dist and total tokens
        }
        else {
            delete Proposals[parameterHash].owner;
            // give tokens to challenger based on dist and total tokens
        }
        // ensures the result cannot be processed again
        voteProcessed[_pollID] = true;
    }

    function claimParamReward(uint _pollID, uint _salt) {
        // checks if a voter has claimed tokens
        require(voterInfo[msg.sender][_pollID] == false);
        uint reward = giveTokens(_pollID, _salt);
        // ensures a voter cannot claim tokens again
        transfer(msg.sender, reward);
        voterInfo[msg.sender][_pollID] = true;
    }

     function giveParamTokens(uint _pollID, uint _salt) returns(uint) {
        // number of tokens person used to vote / total number of tokens for winning side
        // scale using distribution number
        // give the tokens
        // string parameter = ??
        bytes32 parameterHash = sha3(parameter, value);
        uint minDeposit = Proposals[parameterHash].snapshot[minDeposit];
        uint dispensationPct = Proposals[parameterHash].snapshot[dispensationPct];
        uint totalTokens = getTotalNumberOfTokensForWinningOption(_pollID);
        uint voterTokens = getNumCorrectInvestment(_pollID, _salt);

        uint reward = voterTokens*minDeposit*(1-dispensationPct)/totalTokens;
        return reward;
    }

     // private function to initialize a snapshot of parameters for each proposal
     function initializeSnapshotParam(bytes32 _hash) {
        Proposals[_hash].snapshot.minDeposit = get("minDeposit");
        Proposals[_hash].snapshot.challengeLen = get("challengeLen");
        Proposals[_hash].snapshot.commitVoteLen = get("commitVoteLen");
        Proposals[_hash].snapshot.revealVoteLen = get("revealVoteLen");
        Proposals[_hash].snapshot.majority = get("majority");
        Proposals[_hash].snapshot.dispensationPct = get("dispensationPct");
    }

    // interface for retrieving config parameter from hashmapping
    /// @param _keyword key for hashmap (only useful when keyword matches variable name)
    function get(string _keyword) returns (uint) {
       return Parameters[sha3(_keyword)];
    }

}

pragma solidity ^0.4.11;
//import "./StandardToken.sol";
// import "./PartialLockVoting.sol";
// import "./Parametrizer.sol";

// to do:
// implement events
// check on delete in solidity
// keep deposit if never challenged (?) if win (?)

contract Registry {

    /*
     * Storage
     */

    //Registry storage
    StandardToken public token;
    mapping(bytes32 => Publisher) public whitelist;
    mapping(bytes32 => Application) public appPool;
    mapping(uint => bool) public voteProcessed;
    mapping(address => mapping(uint => bool)) public voterInfo;
    //Parameter storage
    mapping(bytes32 => Application) public Proposals; // similar to appPool
    mapping(bytes32 => uint) public Parameters;

    struct Publisher {
        address owner;
        uint expTime;
        uint deposit;
    }

    struct Application {
        address owner;
        bool challenged;
        uint challengeTime; //End of challenge period
        address challenger;
        Param snapshot;
    }

    struct Param {
        // parameters concerning the whitelist and application pool
        uint minDeposit;
        uint challengeLen;
        uint registryLen;

        // parameters to be passed into the voting contract
        uint commitVoteLen;
        uint revealVoteLen;
        uint majority;

        // parameter representing the scale of how token rewards are distributed
        uint dispensationPct;
    }

    // Constructor
    /// @param _minDeposit      application & challenger deposit amounts
    /// @param _challengeLen    duration of the challenge period
    /// @param _registryLen     duration of a registration’s validity
    /// @param _commitVoteLen   duration of the commit period in token votes
    /// @param _revealVoteLen   duration of reveal period in token votes
    /// @param _dispensationPct percentage of forfeited deposit distributed to winning party; uint between 0 and 100
    /// @param _majority        percentage of votes that constitutes the majority; uint between 0 and 100

    function Registry(address _token,
       uint _minDeposit,
       uint _challengeLen,
       uint _registryLen,
       uint _commitVoteLen,
       uint _revealVoteLen,
       uint _dispensationPct,
       uint _majority) {

       token = StandardToken(_token);
       // initialize values
       Parameters[sha3("minDeposit")]        = _minDeposit;
       Parameters[sha3("challengeLen")]      = _challengeLen;
       Parameters[sha3("registryLen")]       = _registryLen;
       Parameters[sha3("commitVoteLen")]     = _commitVoteLen;
       Parameters[sha3("revealVoteLen")]     = _revealVoteLen;
       Parameters[sha3("dispensationPct")]   = _dispensationPct;
       Parameters[sha3("majority")]          = _majority;
    }

    // called by an applicant to apply (moves them into the application pool on success)
    function apply(string _domain) {
        bytes32 domainHash = sha3(_domain);
        // applicant must pay the current value of minDeposit
        uint deposit = get("minDeposit");
        // check to prevent repeat applications
        require(appPool[domainHash].owner == 0);
        // check that registry can take sufficient amount of tokens from the applicant
        require(token.allowance(msg.sender, this) >= deposit);
        token.transferFrom(msg.sender, this, deposit);
        // initialize application with a snapshot with the current values of all parameters
        initializeSnapshot(_domain);
        appPool[domainHash].challengeTime = now + appPool[domainHash].snapshot[challengeLen];
        appPool[domainHash].owner = msg.sender;
    }

    // called by any adtoken holder to challenge an application to the whitelist and start a vote
    function challenge(string _domain) {
        bytes32 domainHash = sha3(_domain);
        // check that registry can take sufficient amount of tokens from the challenger
        uint deposit = appPool[domainHash].snapshot.minDeposit;
        require(token.allowance(msg.sender, this) >= deposit);
        token.transferFrom(msg.sender, this, deposit);
        // prevent someone from challenging an unintialized application, rechallenging,
        // or challenging after the challenge period has ended
        require(appPool[domainHash].owner != 0);
        require(appPool[domainHash].challenged == false);
        require(appPool[domainHash].challengeTime > now);
        // update the application's status
        appPool[domainHash].challenged = true;
        appPool[domainHash].challenger = msg.sender;
        // start a vote
        // poll ID = callVote(voting params);
    }

    // helper function to the challenge() function. Initializes a vote through the voting contract
    function callVote(bytes32 _domainHash) private returns (bool) {
        // event that vote has started
        // ??
    }

    // a one-time function for each completed vote
    // if domain won: domain is moved to the whitelist and applicant is rewarded tokens
    // if domain lost: challenger is rewarded tokens
    function processResult(uint _pollID)
    {
        require(voteProcessed[_pollID] == false);
        // string domain = ??;
        bytes32 domainHash = sha3(domain);
        if (didProposalPass(_pollID)) {
            //??what would happen if didProposalPass() called and vote's still ongoing??
            // add to registry
            add(domain, appPool[domainHash].owner);
            delete appPool[domainHash].owner;
            // give tokens to applicant based on dist and total tokens
        }
        else {
            delete appPool[domainHash].owner;
            deposit = appPool[domainHash].snapshot[minDeposit];
            winning = appPool[domainHash].snapshot[minDeposit]*appPool[domainHash].snapshot[dispensationPct];
            tokens.transfer(appPool[domainHash].challenger, winning+ deposit);
            // check math
        }
        // ensures the result cannot be processed again
        voteProcessed[_pollID] = true;
    }

    // called by each voter to claim their reward for each completed vote
    function claimReward(uint _pollID, uint _salt) {
        // checks if a voter has claimed tokens
        require(voterInfo[msg.sender][_pollID] == false);
        uint reward = giveTokens(_pollID, _salt);
        // ensures a voter cannot claim tokens again
        transfer(msg.sender, reward);
        voterInfo[msg.sender][_pollID] = true;
    }

    // called to move an applying domain to the whitelist
    // iff the domain's challenge period has passed without a challenge
    function moveToRegistry(string _domain) {
        bytes32 domainHash = sha3(_domain);
        require(appPool[domainHash].challengeTime < now);
        require(appPool[domainHash].challenged == false);
        // prevents moving a domain to the registry without ever applying
        require(appPool[domainHash].owner != 0);
        // prevent applicant from moving to registry multiple times
        add(_domain, appPool[domainHash].owner);
        delete appPool[domainHash].owner;
    }

    // private function to add a domain name to the whitelist
    function add(string _domain, address _owner)  {
        bytes32 domainHash = sha3(_domain);
        uint expiration = appPool[domainHash].snapshot.registryLen;
        whitelist[domainHash].expTime = now + expiration;
        whitelist[domainHash].owner = _owner;
        whitelist[domainHash].deposit = appPool[domainHash].snapshot.minDeposit;
    }

    // checks if a domain name is in the whitelist and unexpired
    function isVerified(string _domain) returns (bool) {
        bytes32 domainHash = sha3(_domain);
        if (whitelist[domainHash].expTime > now) {
            return true;
        }
        else {
            return false;
        }
    }

    // private function to initialize a snapshot of parameters for each application
    function initializeSnapshot(string _domain) {
        bytes32 domainHash = sha3(_domain);
        appPool[domainHash].snapshot.minDeposit = get("minDeposit");
        appPool[domainHash].snapshot.challengeLen = get("challengeLen");
        appPool[domainHash].snapshot.registryLen = get("registryLen");
        appPool[domainHash].snapshot.commitVoteLen = get("commitVoteLen");
        appPool[domainHash].snapshot.revealVoteLen = get("revealVoteLen");
        appPool[domainHash].snapshot.majority = get("majority");
        appPool[domainHash].snapshot.dispensationPct = get("dispensationPct");
    }

    function giveTokens(uint _pollID, uint _salt) returns(uint) {
        // number of tokens person used to vote / total number of tokens for winning side
        // scale using distribution number
        // give the tokens
        // string domain = ??
        bytes32 domainHash = sha3(domain);
        uint minDeposit = appPool[domainHash].snapshot[minDeposit];
        uint dispensationPct = appPool[domainHash].snapshot[dispensationPct];
        uint totalTokens = getTotalNumberOfTokensForWinningOption(_pollID);
        uint voterTokens = getNumCorrectInvestment(_pollID, _salt);

        uint reward = voterTokens*minDeposit*(1-dispensationPct)/totalTokens;
        return reward;
    }

    // FOR TESTING
    function toHash(string _domain) returns (bytes32){
        return sha3(_domain);
    }
    function getCurrentTime() returns (uint){
        return now;
    }

/*******************************************************************/

    //called by a user who wishes to change a parameter
    //initializes a proposal to change a parameter
    function proposeUpdate(string _parameter, uint _value) {
        bytes32 parameterHash = sha3(_parameter, _value);
        // applicant must pay the current value of minDeposit
        uint deposit = get("minDeposit");
        // check that registry can take sufficient amount of tokens from the applicant
        require(token.allowance(msg.sender, this) >= deposit);
        token.transferFrom(msg.sender, this, deposit);
        // initialize application with a snapshot with the current values of all parameters
        initializeSnapshotParam(parameterHash);
        uint challengeLen = Proposals[parameterHash].snapshot[challengeLen];
        Proposals[parameterHash].challengeTime= now + challengeLen;
        Proposals[parameterHash].owner = msg.sender;

    }

    //called by user who wishes to reject a proposal
    //initializes a vote to accept/reject the param change proposal
    function challengeProposal(string _parameter, uint _value) {
        bytes32 parameterHash = sha3(_parameter, _value);

        // check that registry can take sufficient amount of tokens from the challenger
        uint deposit = Proposals[parameterHash ].snapshot.minDeposit;
        require(token.allowance(msg.sender, this) >= deposit);
        token.transferFrom(msg.sender, this, deposit);

        // prevent someone from challenging an unintialized application, rechallenging,
        // or challenging after the challenge period has ended
        require(Proposals[parameterHash].owner != 0);
        require(Proposals[parameterHash].challenged == false);
        require(Proposals[parameterHash].challengeTime> now);

        // update the application's status
        Proposals[parameterHash].challenged = true;
        Proposals[parameterHash].challenger = msg.sender;
        // start a vote
        // poll ID = callVote(voting params);
    }

    // called to change parameter
    // iff the proposal's challenge period has passed without a challenge
    function setParams(string _parameter, uint _value) {
        bytes32 parameterHash = sha3(_parameter, _value);
        require(Proposals[parameterHash].challengeTime < now);
        require(Proposals[parameterHash].challenged == false);
        // prevents moving a domain to the registry without ever applying
        require(Proposals[parameterHash].owner != 0);
        // prevent applicant from moving to registry multiple times
        Parameters[sha3(_parameter)] = _value;
        delete Proposals[parameterHash].owner;
    }

    // a one-time function for each completed vote
    // if proposal won: new parameter value is set, and applicant is rewarded tokens
    // if prospsal lost: challenger is rewarded tokens
    function processProposal(uint _pollID)
    {
        require(voteProcessed[_pollID] == false);
        // string parameter = ??;
        //uint value = ??
        bytes32 parameterHash = sha3(parameter, value);
        if (didProposalPass(_pollID)) {
            //??what would happen if didProposalPass() called and vote's still ongoing??
            // setting the value of parameter
            Parameters[sha3(parameter)] = value;
            delete Proposals[parameterHash].owner;
            // give tokens to applicant based on dist and total tokens
        }
        else {
            delete Proposals[parameterHash].owner;
            // give tokens to challenger based on dist and total tokens
        }
        // ensures the result cannot be processed again
        voteProcessed[_pollID] = true;
    }

    function claimParamReward(uint _pollID, uint _salt) {
        // checks if a voter has claimed tokens
        require(voterInfo[msg.sender][_pollID] == false);
        uint reward = giveTokens(_pollID, _salt);
        // ensures a voter cannot claim tokens again
        transfer(msg.sender, reward);
        voterInfo[msg.sender][_pollID] = true;
    }

     function giveParamTokens(uint _pollID, uint _salt) returns(uint) {
        // number of tokens person used to vote / total number of tokens for winning side
        // scale using distribution number
        // give the tokens
        // string parameter = ??
        bytes32 parameterHash = sha3(parameter, value);
        uint minDeposit = Proposals[parameterHash].snapshot[minDeposit];
        uint dispensationPct = Proposals[parameterHash].snapshot[dispensationPct];
        uint totalTokens = getTotalNumberOfTokensForWinningOption(_pollID);
        uint voterTokens = getNumCorrectInvestment(_pollID, _salt);

        uint reward = voterTokens*minDeposit*(1-dispensationPct)/totalTokens;
        return reward;
    }

     // private function to initialize a snapshot of parameters for each proposal
     function initializeSnapshotParam(bytes32 _hash) {
        Proposals[_hash].snapshot.minDeposit = get("minDeposit");
        Proposals[_hash].snapshot.challengeLen = get("challengeLen");
        Proposals[_hash].snapshot.commitVoteLen = get("commitVoteLen");
        Proposals[_hash].snapshot.revealVoteLen = get("revealVoteLen");
        Proposals[_hash].snapshot.majority = get("majority");
        Proposals[_hash].snapshot.dispensationPct = get("dispensationPct");
    }

    // interface for retrieving config parameter from hashmapping
    /// @param _keyword key for hashmap (only useful when keyword matches variable name)
    function get(string _keyword) returns (uint) {
       return Parameters[sha3(_keyword)];
    }

}


introduce a checker for leoAddress in redeemTokens function

pragma solidity ^0.4.17;

import "./StandardToken.sol";

/**
 * @title The Pre-Leo Token contract.
 *
 * Credit: Taking ideas from BAT token and NET token
 */
contract PXLToken is StandardToken {

    // Token metadata
    string public constant name = "Pre-Leo Token";
    string public constant symbol = "PXLT";
    uint256 public constant decimals = 18;
    string public constant version = "0.9";

    // Fundraising parameters
    enum ContractState { Fundraising, Finalized, Redeeming, Paused }
    struct redeemer {                                // pair ETH address with LEO Address)
        address ethAddress;
        string leoAddress;
    }
    mapping (uint256 => redeemer) public redeemers;  // pair index with user information

    ContractState public state;           // Current state of the contract
    ContractState private savedState;     // State of the contract before pause

    uint256 public fundingStartBlock;        // These two blocks need to be chosen to comply with the
    uint256 public fundingEndBlock;          // start date and 28 day duration requirements
    uint256 public exchangeRateChangesBlock; // block number that triggers the exchange rate change
    uint256 public redeemerCount;            // index counting redeemers

    address public admin1; // First administrator for multi-sig mechanism
    address public admin2; // Second administrator for multi-sig mechanism

    uint256 public constant TOKEN_FIRST_EXCHANGE_RATE = 200; // 200 PXLTs per 1 ETH
    uint256 public constant TOKEN_SECOND_EXCHANGE_RATE = 175; // 175 PXLTs per 1 ETH
    uint256 public constant TOKEN_CREATION_CAP = 10 * (10**6) * 10**decimals; // 10 million PXLTs
    uint256 public constant ETH_RECEIVED_CAP = 50 * (10**3) * 10**decimals; // 50 000 ETH
    uint256 public constant ETH_RECEIVED_MIN = 10 * (10**3) * 10**decimals; // 10 000 ETH
    uint256 public constant TOKEN_MIN = 1 * 10**decimals; // 1 PXLT

    // We need to keep track of how much ether have been contributed, since we have a cap for ETH too
    uint256 public totalReceivedEth = 0;

    // Since we have different exchange rates at different stages, we need to keep track
    // of how much ether each contributed in case that we need to issue a refund
    mapping (address => uint256) private ethBalances;
    mapping (address => bytes32) private multiSigHashes; // store the hashes of admins' msg.data

    // Events used for logging
    event LogRefund(address indexed _to, uint256 _value);
    event LogCreatePXLT(address indexed _to, uint256 _value);
    event LogRedeemPXLT(address indexed _from, uint256 _value, string _leoAddress);

    modifier isFinalized() {
        require(state == ContractState.Finalized);
        _;
    }

    modifier isFundraising() {
        require(state == ContractState.Fundraising);
        _;
    }

    modifier isRedeeming() {
        require(state == ContractState.Redeeming);
        _;
    }

    modifier isPaused() {
        require(state == ContractState.Paused);
        _;
    }

    modifier notPaused() {
        require(state != ContractState.Paused);
        _;
    }

    modifier isFundraisingIgnorePaused() {
        require(state == ContractState.Fundraising || (state == ContractState.Paused && savedState == ContractState.Fundraising));
        _;
    }

    modifier onlyOwner() {
        // check if transaction sender is admin.
        require (msg.sender == admin1 || msg.sender == admin2);
        // if yes, store his msg.data.
        multiSigHashes[msg.sender] = keccak256(msg.data);
        // check if his stored msg.data hash equals to the one of the other admin
        if ((multiSigHashes[admin1]) == (multiSigHashes[admin2])) {
            // if yes, both admins agreed - continue.
            _;

            // Reset hashes after successful execution
            multiSigHashes[admin1] = 0x0;
            multiSigHashes[admin2] = 0x0;
        } else {
            // if not (yet), return.
            return;
        }
    }

    modifier minimumReached() {
        require(totalReceivedEth >= ETH_RECEIVED_MIN);
        _;
    }

    /**
     * @dev Create a new PXLToken contract.
     *
     * @param _fundingStartBlock The starting block of the fundraiser (has to be in the future).
     * @param _fundingEndBlock The end block of the fundraiser (has to be after _fundingStartBlock).
     * @param _exchangeRateChangesBlock The block that changes the exchange rate (has to be between _fundingStartBlock and _fundingEndBlock).
     * @param _admin1 The first admin account that owns this contract.
     * @param _admin2 The second admin account that owns this contract.
     */
    function PXLToken(
        uint256 _fundingStartBlock,
        uint256 _fundingEndBlock,
        uint256 _exchangeRateChangesBlock,
        address _admin1,
        address _admin2)
    public
    {
        // Check that the parameters make sense
        require(block.number <= _fundingStartBlock); // The start of the fundraising should happen in the future
        require(_fundingStartBlock <= _exchangeRateChangesBlock); // The exchange rate change should happen after the start of the fundraising
        require(_exchangeRateChangesBlock <= _fundingEndBlock); // And the end of the fundraising should happen after the exchange rate change
        require (_admin1 != 0x0); // admin1 address must be set
        require (_admin2 != 0x0); // admin2 address must be set
        require (_admin1 != _admin2); // Ensure that admin accounts are different

        // Contract state
        state = ContractState.Fundraising;
        savedState = ContractState.Fundraising;
        fundingStartBlock = _fundingStartBlock;
        fundingEndBlock = _fundingEndBlock;
        exchangeRateChangesBlock = _exchangeRateChangesBlock;
        totalSupply = 0;

        admin1 = _admin1;
        admin2 = _admin2;
    }

    // Overridden method to check for end of fundraising before allowing transfer of tokens
    function transfer(address _to, uint256 _value)
    public
    isFinalized // Only allow token transfer after the fundraising has ended
    onlyPayloadSize(2)
    returns (bool success)
    {
        return super.transfer(_to, _value);
    }

    // Overridden method to check for end of fundraising before allowing transfer of tokens
    function transferFrom(address _from, address _to, uint256 _value)
    public
    isFinalized // Only allow token transfer after the fundraising has ended
    onlyPayloadSize(3)
    returns (bool success)
    {
        return super.transferFrom(_from, _to, _value);
    }

    /// @dev Accepts ether and creates new PXLT tokens
    function createTokens()
    payable
    external
    isFundraising
    {
        require(block.number >= fundingStartBlock);
        require(block.number <= fundingEndBlock);
        require(msg.value > 0);

        // First we check the ETH cap, as it's easier to calculate, return
        // the contribution if the cap has been reached already
        uint256 checkedReceivedEth = SafeMath.add(totalReceivedEth, msg.value);
        require(checkedReceivedEth <= ETH_RECEIVED_CAP);

        // If all is fine with the ETH cap, we continue to check the
        // minimum amount of tokens and the cap for how many tokens
        // have been generated so far
        uint256 tokens = SafeMath.mul(msg.value, getCurrentTokenPrice());
        require(tokens >= TOKEN_MIN);
        uint256 checkedSupply = SafeMath.add(totalSupply, tokens);
        require(checkedSupply <= TOKEN_CREATION_CAP);

        // Only when all the checks have passed, then we update the state (ethBalances,
        // totalReceivedEth, totalSupply, and balances) of the contract
        ethBalances[msg.sender] = SafeMath.add(ethBalances[msg.sender], msg.value);
        totalReceivedEth = checkedReceivedEth;
        totalSupply = checkedSupply;
        balances[msg.sender] += tokens;  // safeAdd not needed; bad semantics to use here

        // Log the creation of this tokens
        LogCreatePXLT(msg.sender, tokens);
    }

    /// @dev Returns the current token price
    function getCurrentTokenPrice()
    private
    constant
    returns (uint256 currentPrice)
    {
        if (block.number < exchangeRateChangesBlock) {
            return TOKEN_FIRST_EXCHANGE_RATE;
        } else {
            return TOKEN_SECOND_EXCHANGE_RATE;
        }
    }

    /// @dev Redeems PXLTs and records the LEO address of the sender
    function redeemTokens(string _leoAddress)
    external
    isRedeeming
    {
        uint256 PXLTVal = balances[msg.sender];
        require(PXLTVal >= TOKEN_MIN); // At least TOKEN_MIN tokens have to be redeemed

        bytes memory checkLength = bytes(_leoAddress); // Make Sure a leo address is provided
        require (checkLength > 0);

        redeemers[redeemerCount] = redeemer ({
            ethAddress : msg.sender,
            leoAddress : _leoAddress
        });

        redeemerCount++;
        // Burn Tokens on redemption
        require(super.transfer(0x0, PXLTVal));
        // Log the redeeming of this tokens
        LogRedeemPXLT(msg.sender, PXLTVal, _leoAddress);
    }

    /// @dev Allows to transfer ether from the contract as soon as the minimum is reached
    function retrieveEth(uint256 _value, address _safe)
    external
    minimumReached
    onlyOwner
    {
        require(_value <= this.balance);
        // make sure a recipient was defined !
        require (_safe != 0x0);

        // send the eth to where admins agree upon
        _safe.transfer(_value);
    }

    /// @dev Ends the fundraising period and sends the ETH to wherever the admins agree upon
    function finalize(address _safe)
    external
    isFundraising
    minimumReached
    onlyOwner  // Only the admins calling this method exactly the same way can finalize the sale.
    {
        // Only allow to finalize the contract before the ending block if we already reached any of the two caps
        require(block.number > fundingEndBlock || totalSupply >= TOKEN_CREATION_CAP || totalReceivedEth >= ETH_RECEIVED_CAP);
        // make sure a recipient was defined !
        require (_safe != 0x0);

        // Move the contract to Finalized state
        state = ContractState.Finalized;
        savedState = ContractState.Finalized;

        // Send the ETH to where admins agree upon.
        _safe.transfer(this.balance);
    }

    /// @dev Starts the redeeming period
    function startRedeeming()
    external
    isFinalized // The redeeming period can only be started after the contract is finalized
    onlyOwner   // Only both admins calling this method can initiate the redeeming period
    {
        // Move the contract to Redeeming state
        state = ContractState.Redeeming;
        savedState = ContractState.Redeeming;
    }

    /// @dev Pauses the contract
    function pause()
    external
    notPaused   // Prevent the contract getting stuck in the Paused state
    onlyOwner   // Only both admins calling this method can pause the contract
    {
        // Move the contract to Paused state
        savedState = state;
        state = ContractState.Paused;
    }

    /// @dev Proceeds with the contract
    function proceed()
    external
    isPaused
    onlyOwner   // Only both admins calling this method can proceed with the contract
    {
        // Move the contract to the previous state
        state = savedState;
    }

    /// @dev Allows contributors to recover their ether in case the minimum funding goal is not reached
    function refund()
    external
    isFundraisingIgnorePaused // Refunding is only possible in the fundraising phase (no matter if paused) by definition
    {
        require(block.number > fundingEndBlock); // Prevents refund until fundraising period is over
        require(totalReceivedEth < ETH_RECEIVED_MIN);  // No refunds if the minimum has been reached

        uint256 PXLTVal = balances[msg.sender];
        require(PXLTVal > 0);
        uint256 ethVal = ethBalances[msg.sender];
        require(ethVal > 0);

        // Update the state only after all the checks have passed
        balances[msg.sender] = 0;
        ethBalances[msg.sender] = 0;
        totalSupply = SafeMath.sub(totalSupply, PXLTVal); // Extra safe

        // Log this refund
        LogRefund(msg.sender, ethVal);

        // Send the contributions only after we have updated all the balances
        // If you're using a contract, make sure it works with .transfer() gas limits
        msg.sender.transfer(ethVal);
    }
}

pragma solidity ^0.4.17;

import "./StandardToken.sol";

/**
 * @title The Pre-Leo Token contract.
 *
 * Credit: Taking ideas from BAT token and NET token
 */
contract PXLToken is StandardToken {

    // Token metadata
    string public constant name = "Pre-Leo Token";
    string public constant symbol = "PXLT";
    uint256 public constant decimals = 18;
    string public constant version = "0.9";

    // Fundraising parameters
    enum ContractState { Fundraising, Finalized, Redeeming, Paused }
    struct redeemer {                                // pair ETH address with LEO Address)
        address ethAddress;
        string leoAddress;
    }
    mapping (uint256 => redeemer) public redeemers;  // pair index with user information

    ContractState public state;           // Current state of the contract
    ContractState private savedState;     // State of the contract before pause

    uint256 public fundingStartBlock;        // These two blocks need to be chosen to comply with the
    uint256 public fundingEndBlock;          // start date and 28 day duration requirements
    uint256 public exchangeRateChangesBlock; // block number that triggers the exchange rate change
    uint256 public redeemerCount;            // index counting redeemers

    address public admin1; // First administrator for multi-sig mechanism
    address public admin2; // Second administrator for multi-sig mechanism

    uint256 public constant TOKEN_FIRST_EXCHANGE_RATE = 200; // 200 PXLTs per 1 ETH
    uint256 public constant TOKEN_SECOND_EXCHANGE_RATE = 175; // 175 PXLTs per 1 ETH
    uint256 public constant TOKEN_CREATION_CAP = 10 * (10**6) * 10**decimals; // 10 million PXLTs
    uint256 public constant ETH_RECEIVED_CAP = 50 * (10**3) * 10**decimals; // 50 000 ETH
    uint256 public constant ETH_RECEIVED_MIN = 10 * (10**3) * 10**decimals; // 10 000 ETH
    uint256 public constant TOKEN_MIN = 1 * 10**decimals; // 1 PXLT

    // We need to keep track of how much ether have been contributed, since we have a cap for ETH too
    uint256 public totalReceivedEth = 0;

    // Since we have different exchange rates at different stages, we need to keep track
    // of how much ether each contributed in case that we need to issue a refund
    mapping (address => uint256) private ethBalances;
    mapping (address => bytes32) private multiSigHashes; // store the hashes of admins' msg.data

    // Events used for logging
    event LogRefund(address indexed _to, uint256 _value);
    event LogCreatePXLT(address indexed _to, uint256 _value);
    event LogRedeemPXLT(address indexed _from, uint256 _value, string _leoAddress);

    modifier isFinalized() {
        require(state == ContractState.Finalized);
        _;
    }

    modifier isFundraising() {
        require(state == ContractState.Fundraising);
        _;
    }

    modifier isRedeeming() {
        require(state == ContractState.Redeeming);
        _;
    }

    modifier isPaused() {
        require(state == ContractState.Paused);
        _;
    }

    modifier notPaused() {
        require(state != ContractState.Paused);
        _;
    }

    modifier isFundraisingIgnorePaused() {
        require(state == ContractState.Fundraising || (state == ContractState.Paused && savedState == ContractState.Fundraising));
        _;
    }

    modifier onlyOwner() {
        // check if transaction sender is admin.
        require (msg.sender == admin1 || msg.sender == admin2);
        // if yes, store his msg.data.
        multiSigHashes[msg.sender] = keccak256(msg.data);
        // check if his stored msg.data hash equals to the one of the other admin
        if ((multiSigHashes[admin1]) == (multiSigHashes[admin2])) {
            // if yes, both admins agreed - continue.
            _;

            // Reset hashes after successful execution
            multiSigHashes[admin1] = 0x0;
            multiSigHashes[admin2] = 0x0;
        } else {
            // if not (yet), return.
            return;
        }
    }

    modifier minimumReached() {
        require(totalReceivedEth >= ETH_RECEIVED_MIN);
        _;
    }

    /**
     * @dev Create a new PXLToken contract.
     *
     * @param _fundingStartBlock The starting block of the fundraiser (has to be in the future).
     * @param _fundingEndBlock The end block of the fundraiser (has to be after _fundingStartBlock).
     * @param _exchangeRateChangesBlock The block that changes the exchange rate (has to be between _fundingStartBlock and _fundingEndBlock).
     * @param _admin1 The first admin account that owns this contract.
     * @param _admin2 The second admin account that owns this contract.
     */
    function PXLToken(
        uint256 _fundingStartBlock,
        uint256 _fundingEndBlock,
        uint256 _exchangeRateChangesBlock,
        address _admin1,
        address _admin2)
    public
    {
        // Check that the parameters make sense
        require(block.number <= _fundingStartBlock); // The start of the fundraising should happen in the future
        require(_fundingStartBlock <= _exchangeRateChangesBlock); // The exchange rate change should happen after the start of the fundraising
        require(_exchangeRateChangesBlock <= _fundingEndBlock); // And the end of the fundraising should happen after the exchange rate change
        require (_admin1 != 0x0); // admin1 address must be set
        require (_admin2 != 0x0); // admin2 address must be set
        require (_admin1 != _admin2); // Ensure that admin accounts are different

        // Contract state
        state = ContractState.Fundraising;
        savedState = ContractState.Fundraising;
        fundingStartBlock = _fundingStartBlock;
        fundingEndBlock = _fundingEndBlock;
        exchangeRateChangesBlock = _exchangeRateChangesBlock;
        totalSupply = 0;

        admin1 = _admin1;
        admin2 = _admin2;
    }

    // Overridden method to check for end of fundraising before allowing transfer of tokens
    function transfer(address _to, uint256 _value)
    public
    isFinalized // Only allow token transfer after the fundraising has ended
    onlyPayloadSize(2)
    returns (bool success)
    {
        return super.transfer(_to, _value);
    }

    // Overridden method to check for end of fundraising before allowing transfer of tokens
    function transferFrom(address _from, address _to, uint256 _value)
    public
    isFinalized // Only allow token transfer after the fundraising has ended
    onlyPayloadSize(3)
    returns (bool success)
    {
        return super.transferFrom(_from, _to, _value);
    }

    /// @dev Accepts ether and creates new PXLT tokens
    function createTokens()
    payable
    external
    isFundraising
    {
        require(block.number >= fundingStartBlock);
        require(block.number <= fundingEndBlock);
        require(msg.value > 0);

        // First we check the ETH cap, as it's easier to calculate, return
        // the contribution if the cap has been reached already
        uint256 checkedReceivedEth = SafeMath.add(totalReceivedEth, msg.value);
        require(checkedReceivedEth <= ETH_RECEIVED_CAP);

        // If all is fine with the ETH cap, we continue to check the
        // minimum amount of tokens and the cap for how many tokens
        // have been generated so far
        uint256 tokens = SafeMath.mul(msg.value, getCurrentTokenPrice());
        require(tokens >= TOKEN_MIN);
        uint256 checkedSupply = SafeMath.add(totalSupply, tokens);
        require(checkedSupply <= TOKEN_CREATION_CAP);

        // Only when all the checks have passed, then we update the state (ethBalances,
        // totalReceivedEth, totalSupply, and balances) of the contract
        ethBalances[msg.sender] = SafeMath.add(ethBalances[msg.sender], msg.value);
        totalReceivedEth = checkedReceivedEth;
        totalSupply = checkedSupply;
        balances[msg.sender] += tokens;  // safeAdd not needed; bad semantics to use here

        // Log the creation of this tokens
        LogCreatePXLT(msg.sender, tokens);
    }

    /// @dev Returns the current token price
    function getCurrentTokenPrice()
    private
    constant
    returns (uint256 currentPrice)
    {
        if (block.number < exchangeRateChangesBlock) {
            return TOKEN_FIRST_EXCHANGE_RATE;
        } else {
            return TOKEN_SECOND_EXCHANGE_RATE;
        }
    }

    /// @dev Redeems PXLTs and records the LEO address of the sender
    function redeemTokens(string _leoAddress)
    external
    isRedeeming
    {
        uint256 PXLTVal = balances[msg.sender];
        require(PXLTVal >= TOKEN_MIN); // At least TOKEN_MIN tokens have to be redeemed

        redeemers[redeemerCount] = redeemer ({
            ethAddress : msg.sender,
            leoAddress : _leoAddress
        });

        redeemerCount++;
        // Burn Tokens on redemption
        require(super.transfer(0x0, PXLTVal));
        // Log the redeeming of this tokens
        LogRedeemPXLT(msg.sender, PXLTVal, _leoAddress);
    }

    /// @dev Allows to transfer ether from the contract as soon as the minimum is reached
    function retrieveEth(uint256 _value, address _safe)
    external
    minimumReached
    onlyOwner
    {
        require(_value <= this.balance);
        // make sure a recipient was defined !
        require (_safe != 0x0);

        // send the eth to where admins agree upon
        _safe.transfer(_value);
    }

    /// @dev Ends the fundraising period and sends the ETH to wherever the admins agree upon
    function finalize(address _safe)
    external
    isFundraising
    minimumReached
    onlyOwner  // Only the admins calling this method exactly the same way can finalize the sale.
    {
        // Only allow to finalize the contract before the ending block if we already reached any of the two caps
        require(block.number > fundingEndBlock || totalSupply >= TOKEN_CREATION_CAP || totalReceivedEth >= ETH_RECEIVED_CAP);
        // make sure a recipient was defined !
        require (_safe != 0x0);

        // Move the contract to Finalized state
        state = ContractState.Finalized;
        savedState = ContractState.Finalized;

        // Send the ETH to where admins agree upon.
        _safe.transfer(this.balance);
    }

    /// @dev Starts the redeeming period
    function startRedeeming()
    external
    isFinalized // The redeeming period can only be started after the contract is finalized
    onlyOwner   // Only both admins calling this method can initiate the redeeming period
    {
        // Move the contract to Redeeming state
        state = ContractState.Redeeming;
        savedState = ContractState.Redeeming;
    }

    /// @dev Pauses the contract
    function pause()
    external
    notPaused   // Prevent the contract getting stuck in the Paused state
    onlyOwner   // Only both admins calling this method can pause the contract
    {
        // Move the contract to Paused state
        savedState = state;
        state = ContractState.Paused;
    }

    /// @dev Proceeds with the contract
    function proceed()
    external
    isPaused
    onlyOwner   // Only both admins calling this method can proceed with the contract
    {
        // Move the contract to the previous state
        state = savedState;
    }

    /// @dev Allows contributors to recover their ether in case the minimum funding goal is not reached
    function refund()
    external
    isFundraisingIgnorePaused // Refunding is only possible in the fundraising phase (no matter if paused) by definition
    {
        require(block.number > fundingEndBlock); // Prevents refund until fundraising period is over
        require(totalReceivedEth < ETH_RECEIVED_MIN);  // No refunds if the minimum has been reached

        uint256 PXLTVal = balances[msg.sender];
        require(PXLTVal > 0);
        uint256 ethVal = ethBalances[msg.sender];
        require(ethVal > 0);

        // Update the state only after all the checks have passed
        balances[msg.sender] = 0;
        ethBalances[msg.sender] = 0;
        totalSupply = SafeMath.sub(totalSupply, PXLTVal); // Extra safe

        // Log this refund
        LogRefund(msg.sender, ethVal);

        // Send the contributions only after we have updated all the balances
        // If you're using a contract, make sure it works with .transfer() gas limits
        msg.sender.transfer(ethVal);
    }
}