compile error fixed

compile error fixed

pragma solidity ^0.4.11;
import "./StandardToken.sol";
import "./PLCRVoting.sol";

contract Registry {

    struct Params {
        uint minDeposit;        // minimum deposit for listing to be whitelisted
        uint applyStage;        // length of period in which applicants wait to be whitelisted
        uint dispensationPct;   // percentage of losing party's deposit distributed to winning party
        uint commitPeriodLen;   // length of commit period for voting
        uint revealPeriodLen;   // length of reveal period for voting
        uint voteQuorum;        // type of majority out of 100 necessary for vote success
    }

    struct Listing {
        uint applicationExpiry; // expiration date of apply stage
        bool whitelisted;       // indicates registry status
        address owner;          // owner of Listing
        uint currentDeposit;    // number of tokens staked
        uint challengeID;       // identifier of canonical challenge
    }

    struct Challenge {
        uint rewardPool;        // pool of tokens distributed amongst winning voters
        address challenger;     // owner of Challenge
        bool resolved;          // indication of if challenge is resolved
        uint stake;             // number of tokens at risk for either party during challenge
        uint remainder;         // remainder tokens from flooring rewards to be claimed by the winner
    }

    // maps challengeIDs to associated challenge data
    mapping(uint => Challenge) challengeMap;

    // maps domainHashes to associated listing data
    mapping(bytes32 => Listing) public listingMap;

    // maps challengeIDs and address to token claim data
    mapping(uint => mapping(address => bool)) public tokenClaims;

    // Global Variables
    Params canonicalParams;
    StandardToken token;
    PLCRVoting voting;

    uint256 constant private MULTIPLIER = 10 ** 18;  // used to help represent doubles as ints in token rewards

    // ------------
    // CONSTRUCTOR:
    // ------------

    function Registry(
        address _tokenAddr,
        uint _minDeposit,
        uint _applyStageLength,
        uint _commitPeriodLength,
        uint _revealPeriodLength,
        uint _dispensationPct,
        uint _voteQuorum
    ) {
        token = StandardToken(_tokenAddr);
        voting = new PLCRVoting(_tokenAddr);

        canonicalParams = Params({
            minDeposit: _minDeposit,
            applyStage: _applyStageLength,
            dispensationPct: _dispensationPct,
            commitPeriodLen: _commitPeriodLength,
            revealPeriodLen: _revealPeriodLength,
            voteQuorum: _voteQuorum
        });
    }

    // --------------------
    // PUBLISHER INTERFACE:
    // --------------------

    //Allow a user to start an application
    //take tokens from user and set apply stage end time
    function apply(string domain) external {
        require(!isWhitelisted(domain));
        require(!appExists(domain));

        //set owner
        Listing listing = listingMap[sha3(domain)];
        listing.owner = msg.sender;

        //transfer tokens
        uint minDeposit = canonicalParams.minDeposit;
        require(token.transferFrom(listing.owner, this, minDeposit));

        //set apply stage end time
        listing.applicationExpiry = block.timestamp + canonicalParams.applyStage;
        listing.currentDeposit = minDeposit;
    }

    //Allow the owner of a domain in the listing to increase their deposit
    function deposit(string domain, uint amount) external {
        Listing listing = listingMap[sha3(domain)];

        require(listing.owner == msg.sender);
        require(token.transferFrom(msg.sender, this, amount));

        listing.currentDeposit += amount;
    }

    //Allow the owner of a domain in the listing to withdraw
    //tokens not locked in a challenge.
    //The publisher's domain remains whitelisted
    function withdraw(string domain, uint amount) external {
        Listing listing = listingMap[sha3(domain)];

        require(listing.owner == msg.sender);
        require(amount <= listing.currentDeposit);
        require(token.transfer(msg.sender, amount));

        listing.currentDeposit -= amount;
    }

    //Allow the owner of a domain to remove the domain from the whitelist
    //Return all tokens to the owner
    function exit(string domain) external {
        Listing listing = listingMap[sha3(domain)];

        require(isWhitelisted(domain));
        // cannot exit during ongoing challenge
        require(challengeMap[listing.challengeID].resolved);

        //remove domain & return tokens
        resetListing(domain);
    }

    // -----------------------
    // TOKEN HOLDER INTERFACE:
    // -----------------------

    //start a poll for a domain in the apply stage or already on the whitelist
    //tokens are taken from the challenger and the publisher's tokens are locked
    function challenge(string domain) external returns (uint challengeID) {
        bytes32 domainHash = sha3(domain);
        Listing listing = listingMap[domainHash];

        //to be challenged, domain must be in apply stage or already on the whitelist
        require(appExists(domain) || listing.whitelisted);
        require(challengeMap[listing.challengeID].resolved); // prevent multiple challenges

        if (listing.currentDeposit < canonicalParams.minDeposit) {
            // not enough tokens, publisher auto-delisted
            resetListing(domain);
            return 0;
        }
        //take tokens from challenger
        uint deposit = canonicalParams.minDeposit;
        require(token.transferFrom(msg.sender, this, deposit));
        //start poll
        uint pollID = voting.startPoll(domain,
            canonicalParams.voteQuorum,
            canonicalParams.commitPeriodLen,
            canonicalParams.revealPeriodLen
        );

        challengeMap[pollID] = Challenge({
            challenger: msg.sender,
            rewardPool: ((100 - canonicalParams.dispensationPct) * deposit) / 100,
            stake: deposit,
            resolved: false,
            remainder: 0
        });

        listingMap[domainHash].challengeID = pollID;      // update listing to store most recent challenge
        listingMap[domainHash].currentDeposit -= deposit; // lock tokens for listing during challenge

        return pollID;
    }

    // whitelist domain if apply stage ended without a challenge
    function updateStatus(string domain) public {
        bytes32 domainHash = sha3(domain);
        uint challengeID = listingMap[domainHash].challengeID;
        require(!challengeMap[challengeID].resolved);  // require processed flag to be false

        // IF NO CHALLENGE AFTER APPLY STAGE
        if (challengeID == 0 && isExpired(listingMap[domainHash].applicationExpiry)) {
            listingMap[domainHash].whitelisted = true;
        } else {
        // PROCESS THE RESULT OF THE POLL

            // winner gets back their full staked deposit, and dispensationPct*loser's stake
            // (1-dispensationPct)*loser's stake = rewardPool
            uint stake = 2*challengeMap[challengeID].stake - challengeMap[challengeID].rewardPool;

            if (voting.isPassed(challengeID)) {
                listingMap[domainHash].whitelisted = true;
                listingMap[domainHash].currentDeposit += stake; // give stake back to applicant
            } else {
                resetListing(domain); // whitelisted = false
                require(token.transfer(challengeMap[challengeID].challenger, stake)); // give stake to challenger
            }

            challengeMap[challengeID].resolved = true; // set flag on challenge being processed
        }
    }

    // called by voter to claim reward for each completed vote
    function claimReward(uint _challengeID, uint _salt) public {
        // ensure voter has not already claimed tokens
        require(tokenClaims[_challengeID][msg.sender] == false);
        uint reward = calculateTokens(_challengeID, _salt, msg.sender);
        // ensures a voter cannot claim tokens again
        token.transfer(msg.sender, reward);
        tokenClaims[_challengeID][msg.sender] = true;
    }

    // helper function to claimReward()
    // number of tokens person used to vote / total number of tokens for winning side
    // scale using distribution number, give the tokens
    function calculateTokens(uint _challengeID, uint _salt, address _voter) private returns(uint) {
        uint256 totalTokens = voting.getTotalNumberOfTokensForWinningOption(_challengeID);
        uint256 voterTokens = voting.getNumPassingTokens(_voter, _challengeID, _salt);

        uint256 rewardPool = challengeMap[_challengeID].rewardPool * MULTIPLIER;
        uint256 numerator = voterTokens * rewardPool;
        uint256 denominator = totalTokens * MULTIPLIER;
        uint256 remainder = numerator % denominator;

        // save remainder tokens in the form of decimal numbers with 18 places represented
        // as a uint256
        challengeMap[_challengeID].remainder += remainder;

        return numerator / denominator;
    }

    // gives reminder tokens from poll to a designated claimer
    // the claimer is the winner of the challenge
    // for every poll there will be ~0.5 nano AdTokens burned,
    // since the winner cannot withdraw a decimal amount of nano AdToken
    function claimExtraReward(uint _challengeID, string _domain) public {
        // uint256 totalTokens = voting.getTotalNumberOfTokensForWinningOption(_challengeID);
        uint256 reward = challengeMap[_challengeID].remainder / (MULTIPLIER);
        // reward = reward / totalTokens; // should this be here?
        challengeMap[_challengeID].remainder -= (reward * MULTIPLIER);
        if (voting.isPassed(_challengeID)) {
            // if challenger won, transfer tokens to challenger
            token.transfer(challengeMap[_challengeID].challenger, reward);
        } else {
            // if publisher won, give tokens to the domain's deposit
            listingMap[sha3(_domain)].currentDeposit += reward;
        }
    }

    // --------
    // HELPERS:
    // --------

    //return true if domain is whitelisted
    function isWhitelisted(string domain) constant public returns (bool whitelisted) {
        return listingMap[sha3(domain)].whitelisted;
    }

    //return true if apply(domain) was called for this domain
    function appExists(string domain) constant public returns (bool exists) {
        return listingMap[sha3(domain)].applicationExpiry > 0;
    }

    //return true if termDate has passed
    function isExpired(uint termDate) constant public returns (bool expired) {
        return termDate > block.timestamp;
    }

    //delete listing from whitelist and return tokens to owner
    function resetListing(string domain) internal {
        bytes32 domainHash = sha3(domain);
        Listing listing = listingMap[domainHash];

        require(token.transfer(listing.owner, listing.currentDeposit));

        delete listingMap[domainHash];
    }
}

pragma solidity ^0.4.11;
import "./StandardToken.sol";
import "./PLCRVoting.sol";

contract Registry {

    struct Params {
        uint minDeposit;        // minimum deposit for listing to be whitelisted
        uint applyStage;        // length of period in which applicants wait to be whitelisted
        uint dispensationPct;   // percentage of losing party's deposit distributed to winning party
        uint commitPeriodLen;   // length of commit period for voting
        uint revealPeriodLen;   // length of reveal period for voting
        uint voteQuorum;        // type of majority out of 100 necessary for vote success
    }

    struct Listing {
        uint applicationExpiry; // expiration date of apply stage
        bool whitelisted;       // indicates registry status
        address owner;          // owner of Listing
        uint currentDeposit;    // number of tokens staked
        uint challengeID;       // identifier of canonical challenge
    }

    struct Challenge {
        uint rewardPool;        // pool of tokens distributed amongst winning voters
        address challenger;     // owner of Challenge
        bool resolved;          // indication of if challenge is resolved
        uint stake;             // number of tokens at risk for either party during challenge
        uint remainder;         // remainder tokens from flooring rewards to be claimed by the winner
    }

    // maps challengeIDs to associated challenge data
    mapping(uint => Challenge) challengeMap;

    // maps domainHashes to associated listing data
    mapping(bytes32 => Listing) public listingMap;

    // maps challengeIDs and address to token claim data
    mapping(uint => mapping(address => bool)) public tokenClaims;

    // Global Variables
    Params canonicalParams;
    StandardToken token;
    PLCRVoting voting;

    uint256 constant private MULTIPLIER = 10 ** 18;  // used to help represent doubles as ints in token rewards

    // ------------
    // CONSTRUCTOR:
    // ------------

    function Registry(
        address _tokenAddr,
        uint _minDeposit,
        uint _applyStageLength,
        uint _commitPeriodLength,
        uint _revealPeriodLength,
        uint _dispensationPct,
        uint _voteQuorum
    ) {
        token = StandardToken(_tokenAddr);
        voting = new PLCRVoting(_tokenAddr);

        canonicalParams = Params({
            minDeposit: _minDeposit,
            applyStage: _applyStageLength,
            dispensationPct: _dispensationPct,
            commitPeriodLen: _commitPeriodLength,
            revealPeriodLen: _revealPeriodLength,
            voteQuorum: _voteQuorum
        });
    }

    // --------------------
    // PUBLISHER INTERFACE:
    // --------------------

    //Allow a user to start an application
    //take tokens from user and set apply stage end time
    function apply(string domain) external {
        require(!isWhitelisted(domain));
        require(!appExists(domain));

        //set owner
        Listing listing = listingMap[sha3(domain)];
        listing.owner = msg.sender;

        //transfer tokens
        uint minDeposit = canonicalParams.minDeposit;
        require(token.transferFrom(listing.owner, this, minDeposit));

        //set apply stage end time
        listing.applicationExpiry = block.timestamp + canonicalParams.applyStage;
        listing.currentDeposit = minDeposit;
    }

    //Allow the owner of a domain in the listing to increase their deposit
    function deposit(string domain, uint amount) external {
        Listing listing = listingMap[sha3(domain)];

        require(listing.owner == msg.sender);
        require(token.transferFrom(msg.sender, this, amount));

        listing.currentDeposit += amount;
    }

    //Allow the owner of a domain in the listing to withdraw
    //tokens not locked in a challenge.
    //The publisher's domain remains whitelisted
    function withdraw(string domain, uint amount) external {
        Listing listing = listingMap[sha3(domain)];

        require(listing.owner == msg.sender);
        require(amount <= listing.currentDeposit);
        require(token.transfer(msg.sender, amount));

        listing.currentDeposit -= amount;
    }

    //Allow the owner of a domain to remove the domain from the whitelist
    //Return all tokens to the owner
    function exit(string domain) external {
        Listing listing = listingMap[sha3(domain)];

        require(isWhitelisted(domain));
        // cannot exit during ongoing challenge
        require(challengeMap[listing.challengeID].resolved);

        //remove domain & return tokens
        resetListing(domain);
    }

    // -----------------------
    // TOKEN HOLDER INTERFACE:
    // -----------------------

    //start a poll for a domain in the apply stage or already on the whitelist
    //tokens are taken from the challenger and the publisher's tokens are locked
    function challenge(string domain) external returns (uint challengeID) {
        bytes32 domainHash = sha3(domain);
        Listing listing = listingMap[domainHash];

        //to be challenged, domain must be in apply stage or already on the whitelist
        require(appExists(domain) || listing.whitelisted);
        require(challengeMap[listing.challengeID].resolved); // prevent multiple challenges

        if (listing.currentDeposit < canonicalParams.minDeposit) {
            // not enough tokens, publisher auto-delisted
            resetListing(domain);
            return 0;
        }
        //take tokens from challenger
        uint deposit = canonicalParams.minDeposit;
        require(token.transferFrom(msg.sender, this, deposit));
        //start poll
        uint pollID = voting.startPoll(domain,
            canonicalParams.voteQuorum,
            canonicalParams.commitPeriodLen,
            canonicalParams.revealPeriodLen
        );

        challengeMap[pollID] = Challenge({
            challenger: msg.sender,
            // rewardPool: ((100 - canonicalParams.dispensationPct) * deposit) / 100
            stake: deposit,
            resolved: false
        });

        listingMap[domainHash].challengeID = pollID;      // update listing to store most recent challenge
        listingMap[domainHash].currentDeposit -= deposit; // lock tokens for listing during challenge

        return pollID;
    }

    // whitelist domain if apply stage ended without a challenge
    function updateStatus(string domain) public {
        bytes32 domainHash = sha3(domain);
        uint challengeID = listingMap[domainHash].challengeID;
        require(!challengeMap[challengeID].resolved);  // require processed flag to be false

        // IF NO CHALLENGE AFTER APPLY STAGE
        if (challengeID == 0 && isExpired(listingMap[domainHash].applicationExpiry)) {
            listingMap[domainHash].whitelisted = true;
        } else {
        // PROCESS THE RESULT OF THE POLL

            // winner gets back their full staked deposit, and dispensationPct*loser's stake
            // (1-dispensationPct)*loser's stake = rewardPool
            uint stake = 2*challengeMap[challengeID].stake - rewardPool;

            if (voting.isPassed(challengeID)) {
                listingMap[domainHash].whitelisted = true;
                listingMap[domainHash].currentDeposit += stake; // give stake back to applicant
            } else {
                resetListing(domain); // whitelisted = false
                require(token.transfer(challengeMap[challengeID].challenger, stake)); // give stake to challenger
            }

            challengeMap[challengeID].resolved = true; // set flag on challenge being processed
        }
    }

    // called by voter to claim reward for each completed vote
    function claimReward(uint _challengeID, uint _salt) public {
        // ensure voter has not already claimed tokens
        require(tokenClaims[_challengeID][msg.sender] == false);
        uint reward = calculateTokens(_challengeID, _salt, msg.sender);
        // ensures a voter cannot claim tokens again
        token.transfer(msg.sender, reward);
        tokenClaims[_challengeID][msg.sender] = true;
    }

    // helper function to claimReward()
    // number of tokens person used to vote / total number of tokens for winning side
    // scale using distribution number, give the tokens
    function calculateTokens(uint _challengeID, uint _salt, address _voter) private returns(uint) {
        uint256 stake = challengeMap[_challengeID].stake;
        uint256 totalTokens = voting.getTotalNumberOfTokensForWinningOption(_challengeID);
        uint256 voterTokens = voting.getNumPassingTokens(_challengeID, _salt, _voter);

        uint256 rewardPool = challengeMap[_challengeID].rewardPool * MULTIPLIER;
        uint256 numerator = voterTokens * rewardPool;
        uint256 denominator = totalTokens * MULTIPLIER;
        uint256 remainder = numerator % denominator;

        // save remainder tokens in the form of decimal numbers with 18 places represented
        // as a uint256
        challengeMap[_challengeID].remainder += remainder;

        return numerator / denominator;
    }

    // gives reminder tokens from poll to a designated claimer
    // the claimer is the winner of the challenge
    // for every poll there will be ~0.5 nano AdTokens burned,
    // since the winner cannot withdraw a decimal amount of nano AdToken
    function claimExtraReward(uint _challengeID, string _domain) public {
        // uint256 totalTokens = voting.getTotalNumberOfTokensForWinningOption(_challengeID);
        uint256 reward = challengeMap[_challengeID].remainder / (MULTIPLIER);
        // reward = reward / totalTokens; // should this be here?
        challengeMap[_challengeID].remainder -= (reward * MULTIPLIER);
        if (voting.isPassed(_challengeID)) {
            // if challenger won, transfer tokens to challenger
            token.transfer(challengeMap[_challengeID].challenger, reward);
        } else {
            // if publisher won, give tokens to the domain's deposit
            listingMap[sha3(_domain)].currentDeposit += reward;
        }
    }

    // --------
    // HELPERS:
    // --------

    //return true if domain is whitelisted
    function isWhitelisted(string domain) constant public returns (bool whitelisted) {
        return listingMap[sha3(domain)].whitelisted;
    }

    //return true if apply(domain) was called for this domain
    function appExists(string domain) constant public returns (bool exists) {
        return listingMap[sha3(domain)].applicationExpiry > 0;
    }

    //return true if termDate has passed
    function isExpired(uint termDate) constant public returns (bool expired) {
        return termDate > block.timestamp;
    }

    //delete listing from whitelist and return tokens to owner
    function resetListing(string domain) internal {
        bytes32 domainHash = sha3(domain);
        Listing listing = listingMap[domainHash];

        require(token.transfer(listing.owner, listing.currentDeposit));

        delete listingMap[domainHash];
    }
}


Returned back Claim function

Returned back Claim function

pragma solidity ^0.4.8;

//This contract is backed by the constitution of SuperDAO deployed at : .
//The constitution of the superdao is the social contract, terms, founding principles and definitions of the vision,
//mission, anti-missions, rules and operation guidelines of Superdao.
//The total number of 3,000,000 represents 3% of 100,000,000 immutable number of superdao tokens,
//which is the alloted budget of operation for the earliest funding activities.
//Every prommissory token is exchangeable for the real SuperDAO tokens on a one on one basis.
//Promissiory contract will be deployed with the actual superdao token contract.
//Early backers can call the "redeem" function on the actual token contract to exchange promissory tokens for the final tokens.

/**
 * @title Promisory Token Contract
 * @author ola
 * --- Collaborators ---
 * @author zlatinov
 * @author panos
 * @author yemi
 * @author archil
 * @author anthony
 */
contract PromissoryToken {

    event FounderSwitchRequestEvent(address _newFounderAddr);
    event FounderSwitchedEvent(address _newFounderAddr);
    event CofounderSwitchedEvent(address _newCofounderAddr);

    event AddedPrepaidTokensEvent(address backer, uint index, uint price, uint amount);
    event PrepaidTokensClaimedEvent(address backer, uint index, uint price, uint amount);
    event TokensClaimedEvent(address backer, uint index, uint price, uint amount);

    event RedeemEvent(address backer, uint amount);

    event WithdrawalCreatedEvent(uint withdrawalId, uint amount, bytes reason);
    event WithdrawalVotedEvent(uint withdrawalId, address backer, uint backerStakeWeigth, uint totalStakeWeight);
    event WithdrawalApproved(uint withdrawalId, uint stakeWeight, bool isMultiPayment, uint amount, bytes reason);

    address founder; //deployer of constitution and PromissoryToken
    bytes32 founderHash; // hash must be confirmed in order to replace founder address
    mapping(address => bytes32) tempHashes; // structure to contain new address to hash storage,
    address cofounder;//helper to aid founder key exchange in case of key loss
    address [] public previousFounders; //list of addresses replaced using the switching process.
    uint constant discountAmount = 60; //discount amount
    uint constant divisor = 100; //divisor to get discount value

    uint public constant minimumPrepaidClaimedPercent = 65;
    uint public promissoryUnits = 3000000; //amount of tokens contants set
    uint public prepaidUnits = 0; //prepaid and set by founder out of 3 million tokens
    uint public claimedUnits = 0; //claimed tokens out of 3 million tokens
    uint public claimedPrepaidUnits = 0; //claimed tokens out of the early backer's tokens/prepaidUnits
    uint public redeemedTokens = 0; //number of tokens out of claimed tokens, redeemed by superdao token call
    uint public lastPrice; //latest price of token acquired by backer in Wei
    uint public numOfBackers; //number of early backers

    struct backerData {
       uint tokenPrice;
       uint tokenAmount;
       bytes32 privateHash;
       bool prepaid;
       bool claimed;
       uint backerRank;
    }

    address[] public earlyBackerList; //addresses of earliest backers
    address[] public backersAddresses; //addresses of all backers
    mapping(address => backerData[]) public backers;// backer address to backer info mapping
    mapping(address => bool) public backersRedeemed;

    struct withdrawalData {
       uint Amount;
       bool approved;
       bool spent;
       bytes reason;
       address[] backerApprovals;
       uint totalStake;
       address[] destination;
    }

    withdrawalData[] public withdrawals; // Data structure specifying withdrawal
    mapping(address => mapping(uint => bool)) public withdrawalsVotes;

    /**
    * @notice Deploy PromissoryToken contract with `msg.sender.address()` as founder with `_prepaidBackers.number()` prepaid backers
    * @dev This is the constructor of the promisory token contract
    * @param _founderHash Founders password hash, preferable a message digest to further obfuscate duplicaion
    * @param _cofounderAddress The helper cofounder to aid founder key exchange in case of key loss/
    * @param _numOfBackers The number of Early backers. Will be used to control setting early backers
    */
    function PromissoryToken( bytes32 _founderHash, address _cofounderAddress, uint _numOfBackers){
        founder = msg.sender;
        founderHash = sha3(_founderHash);
        cofounder = _cofounderAddress;
        numOfBackers = _numOfBackers;
    }

    /**
    * @notice `msg.sender.address()` updating cofounder address to `_newFounderAddr.address()`
    * @dev allows cofounder to switch out addres for a new one.Can be repeated as many times as needed
    * @param _newCofounderAddr New Address of Cofounder
    * @return True if the coFounder address successfully updated
    */
    function cofounderSwitchAddress(address _newCofounderAddr) external returns (bool success){
        if (msg.sender != cofounder) throw;

        cofounder = _newCofounderAddr;
        CofounderSwitchedEvent(_newCofounderAddr);

        return true;
    }

    /**
    * @notice Founder address update to `_newFounderAddr.address()` is being requested
    * @dev founderSwitchAddress founder indicates intent to switch addresses with new address,
    * hash of pass phrase and a "onetime shared phrase shared with coufounder"
    * @param _founderHash Secret Key to be used to confirm Address update
    * @param _oneTimesharedPhrase Secret phrase to be shared with coFounder to approve Address update
    * @return True if Address switch request successfully created and Temporary hash Values set
    */
    function founderSwitchRequest(bytes32 _founderHash, bytes32 _oneTimesharedPhrase) returns (bool success){
        if(sha3(_founderHash) != founderHash) throw;

        tempHashes[msg.sender] = sha3(msg.sender, founderHash, _oneTimesharedPhrase);
        FounderSwitchRequestEvent(msg.sender);

        return true;
    }

   /**
    * @notice `msg.sender.address()` approving `_newFounderAddr.address()` as new founder address
    * @dev CofounderSwitchAddress which allows previously set cofounder to approve address
    * switch by founder. Must have a one time shared phrase thats is shared with founder that corresponding with a
    * hashed value.
    * @param _newFounderAddr The address of Founder to be newly set
    * @param _oneTimesharedPhrase Secret Keyword to be provide access to the approval function
    * @return True if new Founder address successfully approved
    */
    function cofounderApproveSwitchRequest(address _newFounderAddr, bytes32 _oneTimesharedPhrase) external returns (bool success){
        if(msg.sender != cofounder || sha3(_newFounderAddr, founderHash, _oneTimesharedPhrase) != tempHashes[_newFounderAddr]) throw;

        previousFounders.push(founder);
        founder = _newFounderAddr;
        FounderSwitchedEvent(_newFounderAddr);

        return true;
    }

    /**
    * @notice Adding `_backer.address()` as an early backer
    * @dev Add Early backers to Contract setting the transacton details
    * @param _backer The address of the Superdao backer
    * @param _tokenPrice The price/rate at which the Superdao tokens were bought
    * @param _tokenAmount The total number of Superdao token purcgased at the indicated rate
    * @param _privatePhrase Secret or passphrase
    * @param _backerRank Rank of the backer in the backers list
    * @return Thre index of _backer  in the backers list
    */
    function setPrepaid(address _backer, uint _tokenPrice, uint _tokenAmount, string _privatePhrase, uint _backerRank)
        external
        founderCall
        returns (uint)
    {
        if (_tokenPrice == 0 || _tokenAmount == 0 || claimedPrepaidUnits>0 ||
            _tokenAmount + prepaidUnits + claimedUnits > promissoryUnits) throw;
        if (earlyBackerList.length == numOfBackers && backers[_backer].length == 0) throw ;
        if (backers[_backer].length == 0) {
            earlyBackerList.push(_backer);
            backersAddresses.push(_backer);
        }
        backers[_backer].push(backerData(_tokenPrice, _tokenAmount, sha3(_privatePhrase, _backer), true, false, _backerRank));

        prepaidUnits +=_tokenAmount;
        lastPrice = _tokenPrice;

        AddedPrepaidTokensEvent(_backer, backers[_backer].length - 1, _tokenPrice, _tokenAmount);

        return backers[_backer].length - 1;
    }

    /**
    * @notice Claiming `_tokenAmount.number()` Superdao tokens by `msg.sender.address()`
    * @dev Claim Superdao Early backer tokens
    * @param _index index of tokens to claim
    * @param _boughtTokensPrice Price at which the Superdao tokens were bought
    * @param _tokenAmount Number of Superdao tokens to be claimed
    * @param _privatePhrase Secret key for Offline shared pre-hashed phrase offline price negotiation for online attestation of uperdao tokens ownership
    * @param _backerRank Backer rank of the backer in the Superdao
    */
    function claimPrepaid(uint _index, uint _boughtTokensPrice, uint _tokenAmount, string _privatePhrase, uint _backerRank)
        external
        EarliestBackersSet
    {
        if(backers[msg.sender][_index].prepaid == true &&
           backers[msg.sender][_index].claimed == false &&
           backers[msg.sender][_index].tokenAmount == _tokenAmount &&
           backers[msg.sender][_index].tokenPrice == _boughtTokensPrice &&
           backers[msg.sender][_index].privateHash == sha3( _privatePhrase, msg.sender) &&
           backers[msg.sender][_index].backerRank == _backerRank)
        {
            backers[msg.sender][_index].claimed = true;
            claimedPrepaidUnits += _tokenAmount;

            PrepaidTokensClaimedEvent(msg.sender, _index, _boughtTokensPrice, _tokenAmount);
        } else {
            throw;
        }
    }

    /**
    * @notice `msg.sender.address()` is Purchasing `(msg.value / lastPrice).toFixed(0)` Superdao Tokens at `lastPrice`
    * @dev Purchase new Superdao Tokens if the amount of tokens are still available for purchase
    */
    function claim()
        payable
        external
        MinimumBackersClaimed
   {
        if (lastPrice == 0) throw;

        //Effective discount for Pre-crowdfunding backers of 40% Leaving effective rate of 60%
        uint discountPrice = lastPrice * discountAmount / divisor;

        uint tokenAmount = (msg.value / discountPrice);//Effect the discount rate 0f 40%

        if (tokenAmount + claimedUnits + prepaidUnits > promissoryUnits) throw;

        if (backers[msg.sender].length == 0) {
            backersAddresses.push(msg.sender);
        }
        backers[msg.sender].push(backerData(discountPrice, tokenAmount, sha3(msg.sender), false, true, 0));

        claimedUnits += tokenAmount;

        TokensClaimedEvent(msg.sender, backers[msg.sender].length - 1, discountPrice, tokenAmount);
    }

    /**
     * @notice checking `_backerAddress.address()` Superdao Token balance: `index`
     * @dev Check Token balance by index of backer, return values can be used to instantiate a backerData struct
     * @param _backerAddress The Backer's address
     * @param index The balance to check
     * @return tokenPrice The Price at which the tokens were bought
     * @return tokenAmount The number of tokens that were bought
     * @return privateHash Secret phrase for authentication by the backer
     * @return prepaid True if backer is an early backer
     * @return claimed True if the Token has already been claimed by the backer
     */
    function checkBalance(address _backerAddress, uint index) constant returns (uint, uint, bytes32, bool, bool){
        return (
            backers[_backerAddress][index].tokenPrice,
            backers[_backerAddress][index].tokenAmount,
            backers[_backerAddress][index].privateHash,
            backers[_backerAddress][index].prepaid,
            backers[_backerAddress][index].claimed
            );
    }

    /**
    * @notice Approving withdrawal `_withdrawalID`
    * @dev Approve a withdrawal from the Superdao and mark the withdrawal as spent
    * @param _withdrawalID The ID of the withdrawal
    */
    function approveWithdraw(uint _withdrawalID)
        external
        backerCheck(_withdrawalID)
    {
        withdrawalsVotes[msg.sender][_withdrawalID] = true;

        uint backerStake = 0;
        for (uint i = 0; i < backers[msg.sender].length; i++) {
            backerStake += backers[msg.sender][i].tokenAmount;
        }
        withdrawals[_withdrawalID].backerApprovals.push(msg.sender);
        withdrawals[_withdrawalID].totalStake += backerStake;

        WithdrawalVotedEvent(_withdrawalID, msg.sender, backerStake, withdrawals[_withdrawalID].totalStake);

        if(withdrawals[_withdrawalID].totalStake >= (claimedPrepaidUnits + claimedUnits) / 3) {
            uint amountPerAddr;
            bool isMultiPayment = withdrawals[_withdrawalID].destination.length > 1;

            if(isMultiPayment == false){
                amountPerAddr = withdrawals[_withdrawalID].Amount;
            }
            else {
                amountPerAddr = withdrawals[_withdrawalID].Amount / withdrawals[_withdrawalID].destination.length;
            }

            withdrawals[_withdrawalID].approved = true;
            withdrawals[_withdrawalID].spent = true;

            for(i = 0; i < withdrawals[_withdrawalID].destination.length; i++){
                if(!withdrawals[_withdrawalID].destination[i].send(amountPerAddr)) throw;
            }

            WithdrawalApproved(_withdrawalID,
                withdrawals[_withdrawalID].totalStake,
                isMultiPayment,
                withdrawals[_withdrawalID].Amount,
                withdrawals[_withdrawalID].reason);
        }
    }

    /**
    * @notice Requestng withdrawal of `_totalAmount` to `_destination.address()`
    * @dev Create a new withdrawal request
    * @param _totalAmount The total amount of tokens to be withdrawan, should be equal to the total number of owned tokens
    * @param _reason Reason/Description for the withdrawal
    * @param _destination The receiving address
    */
    function withdraw(uint _totalAmount, bytes _reason, address[] _destination)
        external
        founderCall
    {
        if (this.balance < _totalAmount) throw;

        uint withdrawalID = withdrawals.length++;

        withdrawals[withdrawalID].Amount = _totalAmount;
        withdrawals[withdrawalID].reason = _reason;
        withdrawals[withdrawalID].destination = _destination;
        withdrawals[withdrawalID].approved = false;
        withdrawals[withdrawalID].spent = false;

        WithdrawalCreatedEvent(withdrawalID, _totalAmount, _reason);
    }

    /**
    * @notice Backer `_bacherAddr.address()` is redeeming `_amount` Superdao Tokens
    * @dev Check if backer tokens have been claimed but not redeemed, then redeem them
    * @param _amount The total number of redeemable tokens
    * @param _backerAddr The address of the backer
    * @return True if tokens were successfully redeemed else false
    */
    function redeem(uint _amount, address _backerAddr) returns(bool){
        if (backersRedeemed[_backerAddr] == true) {
            return false;
        }

        uint totalTokens = 0;

        for (uint i = 0; i < backers[_backerAddr].length; i++) {
            if (backers[_backerAddr][i].claimed == false) {
                return false;
            }
            totalTokens += backers[_backerAddr][i].tokenAmount;
        }

        if (totalTokens == _amount){
            backersRedeemed[_backerAddr] = true;

            RedeemEvent(_backerAddr, totalTokens);

            return true;
        }
        else {
            return false;
        }
    }

    /**
    * @notice check withdrawal status of `_withdrawalID`
    * @dev Get the withdrawal of a withdrawal. Return values can be used to instantiate a withdrawalData struct
    * @param _withdrawalID The ID of the withdrawal
    * @return Amount The Amount requested in the withdrawal
    * @return approved True if the withdrawal has been approved
    * @return reason Reason/Description of the Withdrawal
    * @return backerApprovals Addresses of backers who approved the withdrawal
    * @return totalStake Total number of tokens which backed the withdrawal(Total number of tokens owned by backers who approved the withdrawal)
    * @return destination Receiving address of the withdrawal
    */
    function getWithdrawalData(uint _withdrawalID) constant public returns (uint, bool, bytes, address[], uint, address[]){
        return (
            withdrawals[_withdrawalID].Amount,
            withdrawals[_withdrawalID].approved,
            withdrawals[_withdrawalID].reason,
            withdrawals[_withdrawalID].backerApprovals,
            withdrawals[_withdrawalID].totalStake,
            withdrawals[_withdrawalID].destination);
    }

    modifier founderCall{
        if (msg.sender != founder) throw;
        _;
    }

    modifier backerCheck(uint _withdrawalID){
        if(backers[msg.sender].length == 0 || withdrawals[_withdrawalID].spent == true || withdrawalsVotes[msg.sender][_withdrawalID] == true) throw;
        _;
    }

    modifier EarliestBackersSet{
       if(earlyBackerList.length < numOfBackers) throw;
       _;
    }

    modifier MinimumBackersClaimed(){
      if(prepaidUnits == 0 ||
        claimedPrepaidUnits == 0 ||
        (claimedPrepaidUnits * 100 / prepaidUnits) < minimumPrepaidClaimedPercent) {
            throw;
        }
      _;
    }

    /*
     * Safeguard function.
     * This function gets executed if a transaction with invalid data is sent to
     * the contract or just ether without data.
     */
    function () {
        throw;
    }

}

pragma solidity ^0.4.8;

//This contract is backed by the constitution of superDAO deployed at : .
//The constitution of the superDAO is the social contract, terms, founding principles and definitions of the vision,
//mission, anti-missions, rules and operation guidelines of superDAO.
//The total number of 3,000,000 represents 3% of 100,000,000 immutable number of superDAO tokens,
//which is the alloted budget of operation for the earliest funding activities.
//Every prommissory token is exchangeable for the real superDAO tokens on a one on one basis.
//Promissiory contract will be deployed with the actual superDAO token contract.
//Early backers can call the "redeem" function on the actual token contract to exchange promissory tokens for the final tokens.

/**
 * @title Promisory Token Contract
 * @author ola
 * --- Collaborators ---
 * @author zlatinov
 * @author panos
 * @author yemi
 * @author archil
 * @author anthony
 */
contract PromissoryToken {

    event FounderSwitchRequestEvent(address _newFounderAddr);
    event FounderSwitchedEvent(address _newFounderAddr);
    event CofounderSwitchedEvent(address _newCofounderAddr);

    event AddedPrepaidTokensEvent(address backer, uint index, uint price, uint amount);
    event PrepaidTokensClaimedEvent(address backer, uint index, uint price, uint amount);
    event TokensClaimedEvent(address backer, uint index, uint price, uint amount);

    event RedeemEvent(address backer, uint amount);

    event WithdrawalCreatedEvent(uint withdrawalId, uint amount, bytes reason);
    event WithdrawalVotedEvent(uint withdrawalId, address backer, uint backerStakeWeigth, uint totalStakeWeight);
    event WithdrawalApproved(uint withdrawalId, uint stakeWeight, bool isMultiPayment, uint amount, bytes reason);

    address founder; //deployer of constitution and PromissoryToken
    bytes32 founderHash; // hash must be confirmed in order to replace founder address
    mapping(address => bytes32) tempHashes; // structure to contain new address to hash storage,
    address cofounder;//helper to aid founder key exchange in case of key loss
    address [] public previousFounders; //list of addresses replaced using the switching process.
    uint constant discountAmount = 60; //discount amount
    uint constant divisor = 100; //divisor to get discount value

    uint public constant minimumPrepaidClaimedPercent = 65;
    uint public promissoryUnits = 3000000; //amount of tokens contants set
    uint public prepaidUnits = 0; //prepaid and set by founder out of 3 million tokens
    uint public claimedUnits = 0; //claimed tokens out of 3 million tokens
    uint public claimedPrepaidUnits = 0; //claimed tokens out of the early backer's tokens/prepaidUnits
    uint public redeemedTokens = 0; //number of tokens out of claimed tokens, redeemed by superDAO token call
    uint public lastPrice = 0; //latest price of token acquired by backer in Wei
    uint public numOfBackers; //number of early backers

    struct backerData {
       uint tokenPrice;
       uint tokenAmount;
       bytes32 privateHash;
       bool prepaid;
       bool claimed;
       uint backerRank;
    }

    address[] public earlyBackerList; //addresses of earliest backers
    address[] public backersAddresses; //addresses of all backers
    mapping(address => backerData[]) public backers;// backer address to backer info mapping
    mapping(address => bool) public backersRedeemed;

    struct withdrawalData {
       uint Amount;
       bool approved;
       bool spent;
       bytes reason;
       address[] backerApprovals;
       uint totalStake;
       address[] destination;
    }

    withdrawalData[] public withdrawals; // Data structure specifying withdrawal
    mapping(address => mapping(uint => bool)) public withdrawalsVotes;

    /**
    * @notice Deploy PromissoryToken contract with `msg.sender.address()` as founder with `_prepaidBackers.number()` prepaid backers
    * @dev This is the constructor of the promisory token contract
    * @param _founderHash Founders password hash, preferable a message digest to further obfuscate duplicaion
    * @param _cofounderAddress The helper cofounder to aid founder key exchange in case of key loss/
    * @param _numOfBackers The number of Early backers. Will be used to control setting early backers
    */
    function PromissoryToken( bytes32 _founderHash, address _cofounderAddress, uint _numOfBackers){
        founder = msg.sender;
        founderHash = sha3(_founderHash);
        cofounder = _cofounderAddress;
        numOfBackers = _numOfBackers;
    }

    /**
    * @notice `msg.sender.address()` updating cofounder address to `_newFounderAddr.address()`
    * @dev allows cofounder to switch out addres for a new one.Can be repeated as many times as needed
    * @param _newCofounderAddr New Address of Cofounder
    * @return True if the coFounder address successfully updated
    */
    function cofounderSwitchAddress(address _newCofounderAddr) external returns (bool success){
        if (msg.sender != cofounder) throw;

        cofounder = _newCofounderAddr;
        CofounderSwitchedEvent(_newCofounderAddr);

        return true;
    }

    /**
    * @notice Founder address update to `_newFounderAddr.address()` is being requested
    * @dev founderSwitchAddress founder indicates intent to switch addresses with new address,
    * hash of pass phrase and a "onetime shared phrase shared with coufounder"
    * @param _founderHash Secret Key to be used to confirm Address update
    * @param _oneTimesharedPhrase Secret phrase to be shared with coFounder to approve Address update
    * @return True if Address switch request successfully created and Temporary hash Values set
    */
    function founderSwitchRequest(bytes32 _founderHash, bytes32 _oneTimesharedPhrase) returns (bool success){
        if(sha3(_founderHash) != founderHash) throw;

        tempHashes[msg.sender] = sha3(msg.sender, founderHash, _oneTimesharedPhrase);
        FounderSwitchRequestEvent(msg.sender);

        return true;
    }

   /**
    * @notice `msg.sender.address()` approving `_newFounderAddr.address()` as new founder address
    * @dev CofounderSwitchAddress which allows previously set cofounder to approve address
    * switch by founder. Must have a one time shared phrase thats is shared with founder that corresponding with a
    * hashed value.
    * @param _newFounderAddr The address of Founder to be newly set
    * @param _oneTimesharedPhrase Secret Keyword to be provide access to the approval function
    * @return True if new Founder address successfully approved
    */
    function cofounderApproveSwitchRequest(address _newFounderAddr, bytes32 _oneTimesharedPhrase) external returns (bool success){
        if(msg.sender != cofounder || sha3(_newFounderAddr, founderHash, _oneTimesharedPhrase) != tempHashes[_newFounderAddr]) throw;

        previousFounders.push(founder);
        founder = _newFounderAddr;
        FounderSwitchedEvent(_newFounderAddr);

        return true;
    }

    /**
    * @notice Adding `_backer.address()` as an early backer
    * @dev Add Early backers to Contract setting the transacton details
    * @param _backer The address of the superDAO backer
    * @param _tokenPrice The price/rate at which the superDAO tokens were bought
    * @param _tokenAmount The total number of superDAO token purcgased at the indicated rate
    * @param _privatePhrase Secret or passphrase
    * @param _backerRank Rank of the backer in the backers list
    * @return Thre index of _backer  in the backers list
    */
    function setPrepaid(address _backer, uint _tokenPrice, uint _tokenAmount, string _privatePhrase, uint _backerRank)
        external
        founderCall
        returns (uint)
    {
        if (_tokenPrice == 0 || _tokenAmount == 0 || claimedPrepaidUnits>0 ||
            _tokenAmount + prepaidUnits + claimedUnits > promissoryUnits) throw;
        if (earlyBackerList.length == numOfBackers && backers[_backer].length == 0) throw ;
        if (backers[_backer].length == 0) {
            earlyBackerList.push(_backer);
            backersAddresses.push(_backer);
        }
        backers[_backer].push(backerData(_tokenPrice, _tokenAmount, sha3(_privatePhrase, _backer), true, false, _backerRank));

        prepaidUnits +=_tokenAmount;
        lastPrice = _tokenPrice;

        AddedPrepaidTokensEvent(_backer, backers[_backer].length - 1, _tokenPrice, _tokenAmount);

        return backers[_backer].length - 1;
    }

    /**
    * @notice Claiming `_tokenAmount.number()` superDAO tokens by `msg.sender.address()`
    * @dev Claim superDAO Early backer tokens
    * @param _index index of tokens to claim
    * @param _boughtTokensPrice Price at which the superDAO tokens were bought
    * @param _tokenAmount Number of superDAO tokens to be claimed
    * @param _privatePhrase Secret key for Offline shared pre-hashed phrase offline price negotiation for online attestation of superDAO tokens ownership
    * @param _backerRank Backer rank of the backer in the superDAO
    */
    function claimPrepaid(uint _index, uint _boughtTokensPrice, uint _tokenAmount, string _privatePhrase, uint _backerRank)
        external
        EarliestBackersSet
    {
        if(backers[msg.sender][_index].prepaid == true &&
           backers[msg.sender][_index].claimed == false &&
           backers[msg.sender][_index].tokenAmount == _tokenAmount &&
           backers[msg.sender][_index].tokenPrice == _boughtTokensPrice &&
           backers[msg.sender][_index].privateHash == sha3( _privatePhrase, msg.sender) &&
           backers[msg.sender][_index].backerRank == _backerRank)
        {
            backers[msg.sender][_index].claimed = true;
            claimedPrepaidUnits += _tokenAmount;

            PrepaidTokensClaimedEvent(msg.sender, _index, _boughtTokensPrice, _tokenAmount);
        } else {
            throw;
        }
    }

    /**
    * @notice `msg.sender.address()` is Purchasing `(msg.value / lastPrice).toFixed(0)` superDAO Tokens at `lastPrice`
    * @dev Purchase new superDAO Tokens if the amount of tokens are still available for purchase
    */
    function ()
        payable
        MinimumBackersClaimed
   {
        if (lastPrice == 0) throw;

        //don`t accept transactions with zero value
        if (msg.value == 0) throw;

        //Effective discount for Pre-crowdfunding backers of 40% Leaving effective rate of 60%
        uint discountPrice = lastPrice * discountAmount / divisor;

        uint tokenAmount = (msg.value / discountPrice);//Effect the discount rate 0f 40%

        if (tokenAmount + claimedUnits + prepaidUnits > promissoryUnits) throw;

        if (backers[msg.sender].length == 0) {
            backersAddresses.push(msg.sender);
        }
        backers[msg.sender].push(backerData(discountPrice, tokenAmount, sha3(msg.sender), false, true, 0));

        claimedUnits += tokenAmount;

        TokensClaimedEvent(msg.sender, backers[msg.sender].length - 1, discountPrice, tokenAmount);
    }

    /**
     * @notice checking `_backerAddress.address()` superDAO Token balance: `index`
     * @dev Check Token balance by index of backer, return values can be used to instantiate a backerData struct
     * @param _backerAddress The Backer's address
     * @param index The balance to check
     * @return tokenPrice The Price at which the tokens were bought
     * @return tokenAmount The number of tokens that were bought
     * @return privateHash Secret phrase for authentication by the backer
     * @return prepaid True if backer is an early backer
     * @return claimed True if the Token has already been claimed by the backer
     */
    function checkBalance(address _backerAddress, uint index) constant returns (uint, uint, bytes32, bool, bool){
        return (
            backers[_backerAddress][index].tokenPrice,
            backers[_backerAddress][index].tokenAmount,
            backers[_backerAddress][index].privateHash,
            backers[_backerAddress][index].prepaid,
            backers[_backerAddress][index].claimed
            );
    }

    /**
    * @notice Approving withdrawal `_withdrawalID`
    * @dev Approve a withdrawal from the superDAO and mark the withdrawal as spent
    * @param _withdrawalID The ID of the withdrawal
    */
    function approveWithdraw(uint _withdrawalID)
        external
        backerCheck(_withdrawalID)
    {
        withdrawalsVotes[msg.sender][_withdrawalID] = true;

        uint backerStake = 0;
        for (uint i = 0; i < backers[msg.sender].length; i++) {
            backerStake += backers[msg.sender][i].tokenAmount;
        }
        withdrawals[_withdrawalID].backerApprovals.push(msg.sender);
        withdrawals[_withdrawalID].totalStake += backerStake;

        WithdrawalVotedEvent(_withdrawalID, msg.sender, backerStake, withdrawals[_withdrawalID].totalStake);

        if(withdrawals[_withdrawalID].totalStake >= (claimedPrepaidUnits + claimedUnits) / 3) {
            uint amountPerAddr;
            bool isMultiPayment = withdrawals[_withdrawalID].destination.length > 1;

            if(isMultiPayment == false){
                amountPerAddr = withdrawals[_withdrawalID].Amount;
            }
            else {
                amountPerAddr = withdrawals[_withdrawalID].Amount / withdrawals[_withdrawalID].destination.length;
            }

            withdrawals[_withdrawalID].approved = true;
            withdrawals[_withdrawalID].spent = true;

            for(i = 0; i < withdrawals[_withdrawalID].destination.length; i++){
                if(!withdrawals[_withdrawalID].destination[i].send(amountPerAddr)) throw;
            }

            WithdrawalApproved(_withdrawalID,
                withdrawals[_withdrawalID].totalStake,
                isMultiPayment,
                withdrawals[_withdrawalID].Amount,
                withdrawals[_withdrawalID].reason);
        }
    }

    /**
    * @notice Requestng withdrawal of `_totalAmount` to `_destination.address()`
    * @dev Create a new withdrawal request
    * @param _totalAmount The total amount of tokens to be withdrawan, should be equal to the total number of owned tokens
    * @param _reason Reason/Description for the withdrawal
    * @param _destination The receiving address
    */
    function withdraw(uint _totalAmount, bytes _reason, address[] _destination)
        external
        founderCall
    {
        if (this.balance < _totalAmount) throw;

        uint withdrawalID = withdrawals.length++;

        withdrawals[withdrawalID].Amount = _totalAmount;
        withdrawals[withdrawalID].reason = _reason;
        withdrawals[withdrawalID].destination = _destination;
        withdrawals[withdrawalID].approved = false;
        withdrawals[withdrawalID].spent = false;

        WithdrawalCreatedEvent(withdrawalID, _totalAmount, _reason);
    }

    /**
    * @notice Backer `_bacherAddr.address()` is redeeming `_amount` superDAO Tokens
    * @dev Check if backer tokens have been claimed but not redeemed, then redeem them
    * @param _amount The total number of redeemable tokens
    * @param _backerAddr The address of the backer
    * @return True if tokens were successfully redeemed else false
    */
    function redeem(uint _amount, address _backerAddr) returns(bool){
        if (backersRedeemed[_backerAddr] == true) {
            return false;
        }

        uint totalTokens = 0;

        for (uint i = 0; i < backers[_backerAddr].length; i++) {
            if (backers[_backerAddr][i].claimed == false) {
                return false;
            }
            totalTokens += backers[_backerAddr][i].tokenAmount;
        }

        if (totalTokens == _amount){
            backersRedeemed[_backerAddr] = true;

            RedeemEvent(_backerAddr, totalTokens);

            return true;
        }
        else {
            return false;
        }
    }

    /**
    * @notice check withdrawal status of `_withdrawalID`
    * @dev Get the withdrawal of a withdrawal. Return values can be used to instantiate a withdrawalData struct
    * @param _withdrawalID The ID of the withdrawal
    * @return Amount The Amount requested in the withdrawal
    * @return approved True if the withdrawal has been approved
    * @return reason Reason/Description of the Withdrawal
    * @return backerApprovals Addresses of backers who approved the withdrawal
    * @return totalStake Total number of tokens which backed the withdrawal(Total number of tokens owned by backers who approved the withdrawal)
    * @return destination Receiving address of the withdrawal
    */
    function getWithdrawalData(uint _withdrawalID) constant public returns (uint, bool, bytes, address[], uint, address[]){
        return (
            withdrawals[_withdrawalID].Amount,
            withdrawals[_withdrawalID].approved,
            withdrawals[_withdrawalID].reason,
            withdrawals[_withdrawalID].backerApprovals,
            withdrawals[_withdrawalID].totalStake,
            withdrawals[_withdrawalID].destination);
    }

    modifier founderCall{
        if (msg.sender != founder) throw;
        _;
    }

    modifier backerCheck(uint _withdrawalID){
        if(backers[msg.sender].length == 0 || withdrawals[_withdrawalID].spent == true || withdrawalsVotes[msg.sender][_withdrawalID] == true) throw;
        _;
    }

    modifier EarliestBackersSet{
       if(earlyBackerList.length < numOfBackers) throw;
       _;
    }

    modifier MinimumBackersClaimed(){
      if(prepaidUnits == 0 ||
        claimedPrepaidUnits == 0 ||
        (claimedPrepaidUnits * divisor / prepaidUnits) < minimumPrepaidClaimedPercent) {
            throw;
        }
      _;
    }

    /*
     * Safeguard function.
     * This function gets executed if a transaction with invalid data is sent to
     * the contract or just ether without data.
     */
     /*
        function () {
            throw;
        }
    */

}


Contracts for QueueManager, Queue and Resource

pragma solidity ^0.4.11;

// We have to specify what version of compiler this code will compile with

contract QueueManager {

    struct QueueInfo {
        bytes32 mDesc;
        bytes32 mTitle;
        address mOwnerAddress;
        address mQueueAddress;
        bytes32 mResourceType;
        bool mResourceLimited;
    }

    QueueInfo[] public queues;

    struct ResourceInfo {
        bytes32 mType;
        bytes32 mDesc;
        bytes32 mTitle;
        address mOwnerAddress;
        address mResourceAddress;
    }

    mapping(bytes32=>address) public resources;

    //todo: Protect this function call only to contract creator or
    //who pays for the service
    function createQueue (bytes32 title, bytes32 desc, bool freeToEnter, bytes32 data, bytes32 resourceType, bool limitedResource) returns (address)  {
        address newQueueAddress = new Queue(title, desc, freeToEnter, data, msg.sender);
        queues.push(QueueInfo({
            mDesc: desc,
            mTitle: title,
            mOwnerAddress: msg.sender,
            mQueueAddress: newQueueAddress,
            mResourceType: resourceType,
            mResourceLimited: limitedResource
        }));
        return newQueueAddress;
    }

    function createResource(bytes32 t, bytes32 desc, bytes32 title)
    {
        address newResourceAddress = new Resource(t, title, desc, msg.sender);
        resources[t] = newResourceAddress;
    }

    function getQueuesLength() constant returns (uint) {
        return queues.length;
    }

    function QueueManager()
    {
        createQueue("transpaltacija srca", "d", false, "data", "srce", true);
        createResource("srce", "srca za transplataciju", "srca");
    }
}
contract Queue {

    event ClientAdded(
        address cliendAddress,
        bytes32 data
    );
    event ClientRemoved(
        address clientAddress
    );

    struct Client {
        address id;
        uint timestamp;
        bytes32 data;
    }

    bytes32 title;
    bytes32 description;
    address creator;
    bool freeEntrance;
    uint startIndex;
    uint count;
    uint timestamp;
    bytes32 data;

    mapping(uint => Client) clients;

    // Add client to queue
    function pushClient(address clientAddress, bytes32 userData){
        if(freeEntrance || msg.sender == creator){
            clients[startIndex + count] = Client({
                id: clientAddress,
                timestamp: now,
                data: userData
            });

            count++;

            ClientAdded(clientAddress, userData);
        }
    }
    function popClient() returns (address, uint, bytes32){
        if(msg.sender == creator){
            if(count > 0){
                address removedAddress = clients[startIndex].id;
                uint removedTimestamp = clients[startIndex].timestamp;
                bytes32 removedData = clients[startIndex].data;
                delete clients[startIndex]; //brisanje sa pocetka
                startIndex++;
                count--;

                if(count == 0){
                    startIndex = 0;
                }

                ClientRemoved(removedAddress);
                return (removedAddress, removedTimestamp, removedData);
            }
        }
    }
    function getNumberOfClients() constant returns (uint){
        return count;
    }

    function getClientAtIndex(uint index) constant returns (address, uint, bytes32) {
        require(index >= 0 && index < count);

        uint offset = startIndex + index;
        return (clients[offset].id, clients[offset].timestamp, clients[offset].data);
    }

    function Queue (bytes32 tit, bytes32 desc, bool isFreeToEnter, bytes32 dat, address cr) {
        title = tit;
        description = desc;
        creator = cr;
        freeEntrance = isFreeToEnter;
        startIndex = 0;
        data = dat;
        timestamp = now;
        count = 0;
    }
}

contract Resource
{

    event ResourceAvailable(
        bytes32 resourceType,
        uint32 count
    );

    bytes32 resourceType;
    bytes32 title;
    bytes32 description;
    address creator;
    uint32 count;

    function Resource(bytes32 typ, bytes32 tit, bytes32 desc, address cr)
    {
        resourceType = typ;
        title = tit;
        description = desc;
        creator = cr;
        count = 0;
    }

    function Add (uint32 quantity)
    {
        require(msg.sender == creator);

        count += quantity;
        ResourceAvailable(resourceType, count);
    }

    function Get() returns(bool)
    {
        require(msg.sender == creator);

        if(count > 0)
        {
            --count;
            return true;
        }
        else
        {
            return false;
        }
    }
}

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


Add note about default admin role security (#2211)

* Add note about default admin security

* Update contracts/access/AccessControl.sol

Co-Authored-By: Francisco Giordano <4223852eec80914c4c190cdc031e06592b151a67@gmail.com>

Co-authored-by: Francisco Giordano <4223852eec80914c4c190cdc031e06592b151a67@gmail.com>

pragma solidity ^0.6.0;

import "../utils/EnumerableSet.sol";
import "../utils/Address.sol";
import "../GSN/Context.sol";

/**
 * @dev Contract module that allows children to implement role-based access
 * control mechanisms.
 *
 * Roles are referred to by their `bytes32` identifier. These should be exposed
 * in the external API and be unique. The best way to achieve this is by
 * using `public constant` hash digests:
 *
 * ```
 * bytes32 public constant MY_ROLE = keccak256("MY_ROLE");
 * ```
 *
 * Roles can be used to represent a set of permissions. To restrict access to a
 * function call, use {hasRole}:
 *
 * ```
 * function foo() public {
 *     require(hasRole(MY_ROLE, _msgSender()));
 *     ...
 * }
 * ```
 *
 * Roles can be granted and revoked dynamically via the {grantRole} and
 * {revokeRole} functions. Each role has an associated admin role, and only
 * accounts that have a role's admin role can call {grantRole} and {revokeRole}.
 *
 * By default, the admin role for all roles is `DEFAULT_ADMIN_ROLE`, which means
 * that only accounts with this role will be able to grant or revoke other
 * roles. More complex role relationships can be created by using
 * {_setRoleAdmin}.
 *
 * WARNING: The `DEFAULT_ADMIN_ROLE` is also its own admin: it has permission to
 * grant and revoke this role. Extra precautions should be taken to secure
 * accounts that have been granted it.
 */
abstract contract AccessControl is Context {
    using EnumerableSet for EnumerableSet.AddressSet;
    using Address for address;

    struct RoleData {
        EnumerableSet.AddressSet members;
        bytes32 adminRole;
    }

    mapping (bytes32 => RoleData) private _roles;

    bytes32 public constant DEFAULT_ADMIN_ROLE = 0x00;

    /**
     * @dev Emitted when `account` is granted `role`.
     *
     * `sender` is the account that originated the contract call, an admin role
     * bearer except when using {_setupRole}.
     */
    event RoleGranted(bytes32 indexed role, address indexed account, address indexed sender);

    /**
     * @dev Emitted when `account` is revoked `role`.
     *
     * `sender` is the account that originated the contract call:
     *   - if using `revokeRole`, it is the admin role bearer
     *   - if using `renounceRole`, it is the role bearer (i.e. `account`)
     */
    event RoleRevoked(bytes32 indexed role, address indexed account, address indexed sender);

    /**
     * @dev Returns `true` if `account` has been granted `role`.
     */
    function hasRole(bytes32 role, address account) public view returns (bool) {
        return _roles[role].members.contains(account);
    }

    /**
     * @dev Returns the number of accounts that have `role`. Can be used
     * together with {getRoleMember} to enumerate all bearers of a role.
     */
    function getRoleMemberCount(bytes32 role) public view returns (uint256) {
        return _roles[role].members.length();
    }

    /**
     * @dev Returns one of the accounts that have `role`. `index` must be a
     * value between 0 and {getRoleMemberCount}, non-inclusive.
     *
     * Role bearers are not sorted in any particular way, and their ordering may
     * change at any point.
     *
     * WARNING: When using {getRoleMember} and {getRoleMemberCount}, make sure
     * you perform all queries on the same block. See the following
     * https://forum.openzeppelin.com/t/iterating-over-elements-on-enumerableset-in-openzeppelin-contracts/2296[forum post]
     * for more information.
     */
    function getRoleMember(bytes32 role, uint256 index) public view returns (address) {
        return _roles[role].members.at(index);
    }

    /**
     * @dev Returns the admin role that controls `role`. See {grantRole} and
     * {revokeRole}.
     *
     * To change a role's admin, use {_setRoleAdmin}.
     */
    function getRoleAdmin(bytes32 role) public view returns (bytes32) {
        return _roles[role].adminRole;
    }

    /**
     * @dev Grants `role` to `account`.
     *
     * If `account` had not been already granted `role`, emits a {RoleGranted}
     * event.
     *
     * Requirements:
     *
     * - the caller must have ``role``'s admin role.
     */
    function grantRole(bytes32 role, address account) public virtual {
        require(hasRole(_roles[role].adminRole, _msgSender()), "AccessControl: sender must be an admin to grant");

        _grantRole(role, account);
    }

    /**
     * @dev Revokes `role` from `account`.
     *
     * If `account` had been granted `role`, emits a {RoleRevoked} event.
     *
     * Requirements:
     *
     * - the caller must have ``role``'s admin role.
     */
    function revokeRole(bytes32 role, address account) public virtual {
        require(hasRole(_roles[role].adminRole, _msgSender()), "AccessControl: sender must be an admin to revoke");

        _revokeRole(role, account);
    }

    /**
     * @dev Revokes `role` from the calling account.
     *
     * Roles are often managed via {grantRole} and {revokeRole}: this function's
     * purpose is to provide a mechanism for accounts to lose their privileges
     * if they are compromised (such as when a trusted device is misplaced).
     *
     * If the calling account had been granted `role`, emits a {RoleRevoked}
     * event.
     *
     * Requirements:
     *
     * - the caller must be `account`.
     */
    function renounceRole(bytes32 role, address account) public virtual {
        require(account == _msgSender(), "AccessControl: can only renounce roles for self");

        _revokeRole(role, account);
    }

    /**
     * @dev Grants `role` to `account`.
     *
     * If `account` had not been already granted `role`, emits a {RoleGranted}
     * event. Note that unlike {grantRole}, this function doesn't perform any
     * checks on the calling account.
     *
     * [WARNING]
     * ====
     * This function should only be called from the constructor when setting
     * up the initial roles for the system.
     *
     * Using this function in any other way is effectively circumventing the admin
     * system imposed by {AccessControl}.
     * ====
     */
    function _setupRole(bytes32 role, address account) internal virtual {
        _grantRole(role, account);
    }

    /**
     * @dev Sets `adminRole` as ``role``'s admin role.
     */
    function _setRoleAdmin(bytes32 role, bytes32 adminRole) internal virtual {
        _roles[role].adminRole = adminRole;
    }

    function _grantRole(bytes32 role, address account) private {
        if (_roles[role].members.add(account)) {
            emit RoleGranted(role, account, _msgSender());
        }
    }

    function _revokeRole(bytes32 role, address account) private {
        if (_roles[role].members.remove(account)) {
            emit RoleRevoked(role, account, _msgSender());
        }
    }
}

pragma solidity ^0.6.0;

import "../utils/EnumerableSet.sol";
import "../utils/Address.sol";
import "../GSN/Context.sol";

/**
 * @dev Contract module that allows children to implement role-based access
 * control mechanisms.
 *
 * Roles are referred to by their `bytes32` identifier. These should be exposed
 * in the external API and be unique. The best way to achieve this is by
 * using `public constant` hash digests:
 *
 * ```
 * bytes32 public constant MY_ROLE = keccak256("MY_ROLE");
 * ```
 *
 * Roles can be used to represent a set of permissions. To restrict access to a
 * function call, use {hasRole}:
 *
 * ```
 * function foo() public {
 *     require(hasRole(MY_ROLE, _msgSender()));
 *     ...
 * }
 * ```
 *
 * Roles can be granted and revoked dynamically via the {grantRole} and
 * {revokeRole} functions. Each role has an associated admin role, and only
 * accounts that have a role's admin role can call {grantRole} and {revokeRole}.
 *
 * By default, the admin role for all roles is `DEFAULT_ADMIN_ROLE`, which means
 * that only accounts with this role will be able to grant or revoke other
 * roles. More complex role relationships can be created by using
 * {_setRoleAdmin}.
 */
abstract contract AccessControl is Context {
    using EnumerableSet for EnumerableSet.AddressSet;
    using Address for address;

    struct RoleData {
        EnumerableSet.AddressSet members;
        bytes32 adminRole;
    }

    mapping (bytes32 => RoleData) private _roles;

    bytes32 public constant DEFAULT_ADMIN_ROLE = 0x00;

    /**
     * @dev Emitted when `account` is granted `role`.
     *
     * `sender` is the account that originated the contract call, an admin role
     * bearer except when using {_setupRole}.
     */
    event RoleGranted(bytes32 indexed role, address indexed account, address indexed sender);

    /**
     * @dev Emitted when `account` is revoked `role`.
     *
     * `sender` is the account that originated the contract call:
     *   - if using `revokeRole`, it is the admin role bearer
     *   - if using `renounceRole`, it is the role bearer (i.e. `account`)
     */
    event RoleRevoked(bytes32 indexed role, address indexed account, address indexed sender);

    /**
     * @dev Returns `true` if `account` has been granted `role`.
     */
    function hasRole(bytes32 role, address account) public view returns (bool) {
        return _roles[role].members.contains(account);
    }

    /**
     * @dev Returns the number of accounts that have `role`. Can be used
     * together with {getRoleMember} to enumerate all bearers of a role.
     */
    function getRoleMemberCount(bytes32 role) public view returns (uint256) {
        return _roles[role].members.length();
    }

    /**
     * @dev Returns one of the accounts that have `role`. `index` must be a
     * value between 0 and {getRoleMemberCount}, non-inclusive.
     *
     * Role bearers are not sorted in any particular way, and their ordering may
     * change at any point.
     *
     * WARNING: When using {getRoleMember} and {getRoleMemberCount}, make sure
     * you perform all queries on the same block. See the following
     * https://forum.openzeppelin.com/t/iterating-over-elements-on-enumerableset-in-openzeppelin-contracts/2296[forum post]
     * for more information.
     */
    function getRoleMember(bytes32 role, uint256 index) public view returns (address) {
        return _roles[role].members.at(index);
    }

    /**
     * @dev Returns the admin role that controls `role`. See {grantRole} and
     * {revokeRole}.
     *
     * To change a role's admin, use {_setRoleAdmin}.
     */
    function getRoleAdmin(bytes32 role) public view returns (bytes32) {
        return _roles[role].adminRole;
    }

    /**
     * @dev Grants `role` to `account`.
     *
     * If `account` had not been already granted `role`, emits a {RoleGranted}
     * event.
     *
     * Requirements:
     *
     * - the caller must have ``role``'s admin role.
     */
    function grantRole(bytes32 role, address account) public virtual {
        require(hasRole(_roles[role].adminRole, _msgSender()), "AccessControl: sender must be an admin to grant");

        _grantRole(role, account);
    }

    /**
     * @dev Revokes `role` from `account`.
     *
     * If `account` had been granted `role`, emits a {RoleRevoked} event.
     *
     * Requirements:
     *
     * - the caller must have ``role``'s admin role.
     */
    function revokeRole(bytes32 role, address account) public virtual {
        require(hasRole(_roles[role].adminRole, _msgSender()), "AccessControl: sender must be an admin to revoke");

        _revokeRole(role, account);
    }

    /**
     * @dev Revokes `role` from the calling account.
     *
     * Roles are often managed via {grantRole} and {revokeRole}: this function's
     * purpose is to provide a mechanism for accounts to lose their privileges
     * if they are compromised (such as when a trusted device is misplaced).
     *
     * If the calling account had been granted `role`, emits a {RoleRevoked}
     * event.
     *
     * Requirements:
     *
     * - the caller must be `account`.
     */
    function renounceRole(bytes32 role, address account) public virtual {
        require(account == _msgSender(), "AccessControl: can only renounce roles for self");

        _revokeRole(role, account);
    }

    /**
     * @dev Grants `role` to `account`.
     *
     * If `account` had not been already granted `role`, emits a {RoleGranted}
     * event. Note that unlike {grantRole}, this function doesn't perform any
     * checks on the calling account.
     *
     * [WARNING]
     * ====
     * This function should only be called from the constructor when setting
     * up the initial roles for the system.
     *
     * Using this function in any other way is effectively circumventing the admin
     * system imposed by {AccessControl}.
     * ====
     */
    function _setupRole(bytes32 role, address account) internal virtual {
        _grantRole(role, account);
    }

    /**
     * @dev Sets `adminRole` as ``role``'s admin role.
     */
    function _setRoleAdmin(bytes32 role, bytes32 adminRole) internal virtual {
        _roles[role].adminRole = adminRole;
    }

    function _grantRole(bytes32 role, address account) private {
        if (_roles[role].members.add(account)) {
            emit RoleGranted(role, account, _msgSender());
        }
    }

    function _revokeRole(bytes32 role, address account) private {
        if (_roles[role].members.remove(account)) {
            emit RoleRevoked(role, account, _msgSender());
        }
    }
}


Fix get commit no to use recent logic.

Fix get commit no to use recent logic.

pragma solidity ^0.4.8;

contract PayForPrivKey {
	// Begin config.
	uint constant min_blocks = 7;
	// End config.

	bool debug = false;
	address public pub_key;
	address public owner;
	uint deposit_amount;
	struct CommitInfo
	{
		bytes32 solution_hash;
		uint block_height;
		bool is_valid;
    }

    uint public commit_no;
	mapping(uint => CommitInfo) public commitments;

	// Solution.
	struct Solution
	{
		bytes32 h1;
		uint8 v1;
		bytes32 r1;
		bytes32 s1;
		bytes32 h2;
		bytes32 s2;
		bool is_valid;
	}
	Solution public solution;

	uint start_chain_height;

	function PayForPrivKey(address _pub_key) payable
	{
		pub_key = _pub_key;
		owner = msg.sender; // Not used.
		deposit_amount = msg.value;
		start_chain_height = block.number;
	}

	function refund() public payable
	{
		// Expired - allow contract to be destroyed.
		if(block.number - start_chain_height >= min_blocks * 4 || debug)
		{
			if(msg.sender == owner)
			{
				suicide(owner);
			}
		}
	}

	function get_solution() public returns (bytes32, uint8, bytes32, bytes32, bytes32, bytes32, bool){
		return (solution.h1, solution.v1, solution.r1, solution.s1, solution.h2, solution.s2, solution.is_valid);
	}

	function get_commit_no() public returns (uint){
		return commit_no;
	}

	function toBytes(address x) returns (bytes b) {
		b = new bytes(20);
		for (uint i = 0; i < 20; i++)
			b[i] = byte(uint8(uint(x) / (2**(8*(19 - i)))));
	}

	function CommitSolutionHash(bytes32 _solution_hash) public returns (uint)
	{
		// Don't allow new submissions after a certain timeout.
		if(block.number - start_chain_height >= min_blocks * 2 && !debug)
		{
			throw;
		}

		commit_no = commit_no++;
		commitments[commit_no] = CommitInfo(_solution_hash, block.number, true);

		return commit_no;
	}

	function ProvePrivKey(bytes32 h1, uint8 v1, bytes32 r1, bytes32 s1, bytes32 h2, bytes32 s2, address destination, uint index) public payable returns(address)
	{
		// Don't allow new submissions after a certain timeout.
		if(block.number - start_chain_height >= min_blocks * 2 && !debug)
		{
			throw;
		}

	    // Check this is a commitment first.
	    bytes32 solution_hash = sha3(h1, v1, r1, s1, h2, s2, toBytes(destination));
	    if(commitments[index].solution_hash != solution_hash)
	    {
			throw;
	    }

	    // Now this is important -- check enough block have passed since the commitment was made.
	    // This is necessary for security reasons (race conditions from malicious observers)
	    if(block.number - commitments[index].block_height < min_blocks && !debug)
	    {
	        throw;
	    }

		// Sig values must be unique.
		if(s1 == s2)
		{
			throw;
		}

		// Hash values must be unique.
		// Well they should be if s* is but we'll check anyway.
		if(h1 == h2)
		{
			throw;
		}

		// Recover the first public key and check it.
		address pub_key_1 = ecrecover(h1, v1, r1, s1);
		if(pub_key_1 == 0x0)
		{
			throw;
		}

		// Recover the second public key and check it.
		address pub_key_2 = ecrecover(h2, v1, r1, s2);
		if(pub_key_2 == 0x0)
		{
			throw;
		}

		// Check recovered public key is for the target key.
		if(pub_key_1 == pub_key_2 && pub_key_2 == pub_key)
		{
			// Send the Ether to their provided address.
			if(!destination.send(deposit_amount))
			{
			    throw;
			}

			// Save solution.
			solution.v1 = v1;
			solution.r1 = r1;
			solution.h1 = h1;
			solution.h2 = h2;
			solution.s1 = s1;
			solution.s2 = s2;
			solution.is_valid = true;

			return pub_key_1;
		}
		else
		{
			throw;
		}
	}

}

pragma solidity ^0.4.8;

contract PayForPrivKey {
	// Begin config.
	uint constant min_blocks = 7;
	// End config.

	bool debug = false;
	address public pub_key;
	address public owner;
	uint deposit_amount;
	struct CommitInfo
	{
		bytes32 solution_hash;
		uint block_height;
		bool is_valid;
    }

    uint public commit_no;
	mapping(uint => CommitInfo) public commitments;

	// Solution.
	struct Solution
	{
		bytes32 h1;
		uint8 v1;
		bytes32 r1;
		bytes32 s1;
		bytes32 h2;
		bytes32 s2;
		bool is_valid;
	}
	Solution public solution;

	uint start_chain_height;

	function PayForPrivKey(address _pub_key) payable
	{
		pub_key = _pub_key;
		owner = msg.sender; // Not used.
		deposit_amount = msg.value;
		start_chain_height = block.number;
	}

	function refund() public payable
	{
		// Expired - allow contract to be destroyed.
		if(block.number - start_chain_height >= min_blocks * 4 || debug)
		{
			if(msg.sender == owner)
			{
				suicide(owner);
			}
		}
	}

	function get_solution() public returns (bytes32, uint8, bytes32, bytes32, bytes32, bytes32, bool){
		return (solution.h1, solution.v1, solution.r1, solution.s1, solution.h2, solution.s2, solution.is_valid);
	}

	function get_commit_no() public returns (uint){
		return commit_no - 1;
	}

	function toBytes(address x) returns (bytes b) {
		b = new bytes(20);
		for (uint i = 0; i < 20; i++)
			b[i] = byte(uint8(uint(x) / (2**(8*(19 - i)))));
	}

	function CommitSolutionHash(bytes32 _solution_hash) public returns (uint)
	{
		// Don't allow new submissions after a certain timeout.
		if(block.number - start_chain_height >= min_blocks * 2 && !debug)
		{
			throw;
		}

		commit_no = commit_no++;
		commitments[commit_no] = CommitInfo(_solution_hash, block.number, true);

		return commit_no;
	}

	function ProvePrivKey(bytes32 h1, uint8 v1, bytes32 r1, bytes32 s1, bytes32 h2, bytes32 s2, address destination, uint index) public payable returns(address)
	{
		// Don't allow new submissions after a certain timeout.
		if(block.number - start_chain_height >= min_blocks * 2 && !debug)
		{
			throw;
		}

	    // Check this is a commitment first.
	    bytes32 solution_hash = sha3(h1, v1, r1, s1, h2, s2, toBytes(destination));
	    if(commitments[index].solution_hash != solution_hash)
	    {
			throw;
	    }

	    // Now this is important -- check enough block have passed since the commitment was made.
	    // This is necessary for security reasons (race conditions from malicious observers)
	    if(block.number - commitments[index].block_height < min_blocks && !debug)
	    {
	        throw;
	    }

		// Sig values must be unique.
		if(s1 == s2)
		{
			throw;
		}

		// Hash values must be unique.
		// Well they should be if s* is but we'll check anyway.
		if(h1 == h2)
		{
			throw;
		}

		// Recover the first public key and check it.
		address pub_key_1 = ecrecover(h1, v1, r1, s1);
		if(pub_key_1 == 0x0)
		{
			throw;
		}

		// Recover the second public key and check it.
		address pub_key_2 = ecrecover(h2, v1, r1, s2);
		if(pub_key_2 == 0x0)
		{
			throw;
		}

		// Check recovered public key is for the target key.
		if(pub_key_1 == pub_key_2 && pub_key_2 == pub_key)
		{
			// Send the Ether to their provided address.
			if(!destination.send(deposit_amount))
			{
			    throw;
			}

			// Save solution.
			solution.v1 = v1;
			solution.r1 = r1;
			solution.h1 = h1;
			solution.h2 = h2;
			solution.s1 = s1;
			solution.s2 = s2;
			solution.is_valid = true;

			return pub_key_1;
		}
		else
		{
			throw;
		}
	}

}


Removed unnecessary methods

Removed unnecessary methods

pragma solidity ^0.4.2;

import "./priced.sol";
import "./stateMachine.sol";
import "./accessRestricted.sol";

/// @title Brehon Contract
contract BrehonContract is
    priced,
    stateMachine,
    accessRestricted {
  struct Party {
    address addr;
    bool contractAccepted;
    bool primaryBrehonApproval;
    bool secondaryBrehonApproval;
    bool tertiaryBrehonApproval;
  }

  struct Brehon {
    address addr;
    bool contractAccepted;
    uint fixedFee;
    uint disputeFee;
  }

  uint transactionAmount;
  Party partyA;
  Party partyB;
  Brehon primaryBrehon;
  Brehon secondaryBrehon;
  Brehon tertiaryBrehon;

  modifier eitherByParty(Party _party1, Party _party2)
  {
      if (msg.sender != _party1.addr ||
          msg.sender != _party2.addr)
          throw;
      _;

  }

  modifier eitherByBrehon(Brehon _brehon1, Brehon _brehon2, Brehon _brehon3)
  {
      if (msg.sender != _brehon1.addr ||
          msg.sender != _brehon2.addr ||
          msg.sender != _brehon3.addr)
          throw;
      _;

  }

  function BrehonContract(
      address _partyA,
      address _partyB,
      uint _transactionAmount,
      address _primaryBrehon,
      uint _primaryBrehonFixedFee,
      uint _primaryBrehonDisputeFee,
      address _secondaryBrehon,
      uint _secondaryBrehonFixedFee,
      uint _secondaryBrehonDisputeFee,
      address _tertiaryBrehon,
      uint _tertiaryBrehonFixedFee,
      uint _tertiaryBrehonDisputeFee
  ) {
    partyA.addr = _partyA;
    partyA.primaryBrehonApproval = false;
    partyA.secondaryBrehonApproval = false;
    partyA.tertiaryBrehonApproval = false;

    transactionAmount = _transactionAmount;

    partyB.addr = _partyB;
    partyB.primaryBrehonApproval = false;
    partyB.secondaryBrehonApproval = false;
    partyB.tertiaryBrehonApproval = false;

    primaryBrehon.addr = _primaryBrehon;
    primaryBrehon.fixedFee = _primaryBrehonFixedFee;
    primaryBrehon.disputeFee = _primaryBrehonDisputeFee;

    secondaryBrehon.addr = _secondaryBrehon;
    secondaryBrehon.fixedFee = _secondaryBrehonFixedFee;
    secondaryBrehon.disputeFee = _secondaryBrehonDisputeFee;

    tertiaryBrehon.addr = _tertiaryBrehon;
    tertiaryBrehon.fixedFee = _tertiaryBrehonFixedFee;
    tertiaryBrehon.disputeFee = _tertiaryBrehonDisputeFee;

    //Defaults
    stage = Stages.Negotiation;
    partyA.contractAccepted = false;
    partyB.contractAccepted = false;
    primaryBrehon.contractAccepted = false;
    secondaryBrehon.contractAccepted = false;
    tertiaryBrehon.contractAccepted = false;
  }

  function acceptContract()
    atStage(Stages.Negotiation)
    eitherByParty(partyA, partyB)
    eitherByBrehon(primaryBrehon, secondaryBrehon, tertiaryBrehon)
  {
      if (msg.sender == partyA.addr) {
          partyA.contractAccepted = true;
      } else if (msg.sender == partyB.addr) {
          partyB.contractAccepted = true;
      } else if(msg.sender == primaryBrehon.addr) {
          primaryBrehon.contractAccepted = true;
      } else if(msg.sender == secondaryBrehon.addr) {
          secondaryBrehon.contractAccepted = true;
      } else if(msg.sender == tertiaryBrehon.addr) {
          tertiaryBrehon.contractAccepted = true;
      } else throw;
  }

  function deposit() {
  }

  function startContract() {
  }

  function raiseDispute() {
  }

  function getActiveBrehon() {
  }

  function arbitrate() {
  }

  function claimFunds() {
  }

  function raiseAppeal() {
  }

  function raise2ndAppeal() {
  }
}

pragma solidity ^0.4.2;

import "./priced.sol";
import "./stateMachine.sol";
import "./accessRestricted.sol";

/// @title Brehon Contract
contract BrehonContract is
    priced,
    stateMachine,
    accessRestricted {
  struct Party {
    address addr;
    bool contractAccepted;
    bool primaryBrehonApproval;
    bool secondaryBrehonApproval;
    bool tertiaryBrehonApproval;
  }

  struct Brehon {
    address addr;
    bool contractAccepted;
    uint fixedFee;
    uint disputeFee;
  }

  uint transactionAmount;
  Party partyA;
  Party partyB;
  Brehon primaryBrehon;
  Brehon secondaryBrehon;
  Brehon tertiaryBrehon;

  modifier eitherByParty(Party _party1, Party _party2)
  {
      if (msg.sender != _party1.addr ||
          msg.sender != _party2.addr)
          throw;
      _;

  }

  modifier eitherByBrehon(Brehon _brehon1, Brehon _brehon2, Brehon _brehon3)
  {
      if (msg.sender != _brehon1.addr ||
          msg.sender != _brehon2.addr ||
          msg.sender != _brehon3.addr)
          throw;
      _;

  }

  function BrehonContract(
      address _partyA,
      address _partyB,
      uint _transactionAmount,
      address _primaryBrehon,
      uint _primaryBrehonFixedFee,
      uint _primaryBrehonDisputeFee,
      address _secondaryBrehon,
      uint _secondaryBrehonFixedFee,
      uint _secondaryBrehonDisputeFee,
      address _tertiaryBrehon,
      uint _tertiaryBrehonFixedFee,
      uint _tertiaryBrehonDisputeFee
  ) {
    partyA.addr = _partyA;
    partyA.primaryBrehonApproval = false;
    partyA.secondaryBrehonApproval = false;
    partyA.tertiaryBrehonApproval = false;

    transactionAmount = _transactionAmount;

    partyB.addr = _partyB;
    partyB.primaryBrehonApproval = false;
    partyB.secondaryBrehonApproval = false;
    partyB.tertiaryBrehonApproval = false;

    primaryBrehon.addr = _primaryBrehon;
    primaryBrehon.fixedFee = _primaryBrehonFixedFee;
    primaryBrehon.disputeFee = _primaryBrehonDisputeFee;

    secondaryBrehon.addr = _secondaryBrehon;
    secondaryBrehon.fixedFee = _secondaryBrehonFixedFee;
    secondaryBrehon.disputeFee = _secondaryBrehonDisputeFee;

    tertiaryBrehon.addr = _tertiaryBrehon;
    tertiaryBrehon.fixedFee = _tertiaryBrehonFixedFee;
    tertiaryBrehon.disputeFee = _tertiaryBrehonDisputeFee;

    //Defaults
    stage = Stages.Negotiation;
    partyA.contractAccepted = false;
    partyB.contractAccepted = false;
    primaryBrehon.contractAccepted = false;
    secondaryBrehon.contractAccepted = false;
    tertiaryBrehon.contractAccepted = false;
  }

  function acceptContract()
    atStage(Stages.Negotiation)
    eitherByParty(partyA, partyB)
    eitherByBrehon(primaryBrehon, secondaryBrehon, tertiaryBrehon)
  {
      if (msg.sender == partyA.addr) {
          partyA.contractAccepted = true;
      } else if (msg.sender == partyB.addr) {
          partyB.contractAccepted = true;
      } else if(msg.sender == primaryBrehon.addr) {
          primaryBrehon.contractAccepted = true;
      } else if(msg.sender == secondaryBrehon.addr) {
          secondaryBrehon.contractAccepted = true;
      } else if(msg.sender == tertiaryBrehon.addr) {
          tertiaryBrehon.contractAccepted = true;
      }
  }

  function nominatePrimaryBrehon(address _primaryBrehon, uint _fixedFee, uint _disputeFee)
    atStage(Stages.Negotiation)
    eitherByParty(partyA, partyB)
  {
    if(msg.sender == partyA.addr &&
      !partyA.primaryBrehonApproval) {
      partyA.primaryBrehonApproval = true;
    }
    if(msg.sender == partyB.addr &&
      !partyB.primaryBrehonApproval) {
      partyB.primaryBrehonApproval = true;
    }
    primaryBrehon.addr = _primaryBrehon;
    primaryBrehon.fixedFee = _fixedFee;
    primaryBrehon.disputeFee = _disputeFee;
  }

  function assignSecondaryBrehon(address _secondaryBrehon, uint _fixedFee, uint _disputeFee)
    atStage(Stages.Negotiation)
  {
    secondaryBrehon.addr = _secondaryBrehon;
    secondaryBrehon.fixedFee = _fixedFee;
    secondaryBrehon.disputeFee = _disputeFee;
  }

  function assignTertiaryBrehon(address _tertiaryBrehon, uint _fixedFee, uint _disputeFee)
    atStage(Stages.Negotiation)
  {
    tertiaryBrehon.addr = _tertiaryBrehon;
    tertiaryBrehon.fixedFee = _fixedFee;
    tertiaryBrehon.disputeFee = _disputeFee;
  }

  function deposit() {
  }

  function startContract() {
  }

  function raiseDispute() {
  }

  function getActiveBrehon() {
  }

  function arbitrate() {
  }

  function claimFunds() {
  }

  function raiseAppeal() {
  }

  function raise2ndAppeal() {
  }
}