change asset's status before transfers

change asset's status before transfers

pragma solidity ^0.4.18;

import './AssetEvents.sol';
import '../token/Token.sol';

// Defines methods and control modifiers for an investment
contract AssetLibrary is AssetEvents {

    // Asset owner
    address public owner;
    // Protocol
    address public protocol;
    // Asset currency
    string public currency;
    // Asset fixed value
    uint256 public value;
    //Value bought
    uint256 public boughtValue;
    // period to return the investment
    uint256 public paybackDays;
    // Gross return of investment
    uint256 public grossReturn;
    // Asset buyer
    address public investor;
    // Protocol version
    string public protocolVersion;
    // investment timestamp
    uint public investedAt;

    // asset fuel
    Token public token;
    uint256 public tokenFuel;

    // sell data
    struct Sell {
        uint256 value;
        address buyer;
    }

    Sell public sellData;

    // possible stages of an asset
    enum Status {
        AVAILABLE,
        PENDING_OWNER_AGREEMENT,
        INVESTED,
        FOR_SALE,
        PENDING_INVESTOR_AGREEMENT,
        RETURNED,
        DELAYED_RETURN
    }
    Status public status;

    // Checks the current asset's status
    modifier hasStatus(Status _status) {
        assert(status == _status);
        _;
    }

    // Checks if the owner is the caller
    modifier onlyOwner() {
        require(msg.sender == owner);
        _;
    }

    // Checks if the investor is the caller
    modifier onlyInvestor() {
        require(msg.sender == investor);
        _;
    }

    modifier protocolOrInvestor() {
        require(msg.sender == investor || msg.sender == protocol);
        _;
    }

    modifier protocolOrOwner() {
        require(msg.sender == owner || msg.sender == protocol);
        _;
    }

    modifier onlyDelayed(){
        require(isDelayed());
        _;
    }

    function isDelayed()
        view
        internal
        returns(bool)
    {
        return now > investedAt + paybackDays * 1 days;
    }

    // Refund and remove the current investor and make the asset available for investments
    function makeAvailable()
        hasStatus(Status.PENDING_OWNER_AGREEMENT)
        private
        returns(address, uint256)
    {
        status = Status.AVAILABLE;
        uint256 investedValue = this.balance;
        investor.transfer(investedValue);
        address currentInvestor = investor;
        investor = address(0);
        investedAt = uint(0);
        return (currentInvestor, investedValue);
    }

    function withdrawTokens(address _recipient, uint256 _amount)
        private
        returns(bool)
    {
        assert(tokenFuel >= _amount);
        require(token.transfer(_recipient, _amount));
        TokenWithdrawal(_recipient, _amount);
        tokenFuel -= _amount;
        return true;
    }

    // Add investment interest in this asset and retain the funds within the smart contract
    function invest(address _investor) payable
         hasStatus(Status.AVAILABLE)
         external
         returns(bool)
    {
        status = Status.PENDING_OWNER_AGREEMENT;
        investor = _investor;
        investedAt = now;
        Invested(owner, investor, this.balance);
        return true;
    }

    // Cancel the pending investment
    function cancelInvestment()
        protocolOrInvestor
        hasStatus(Status.PENDING_OWNER_AGREEMENT)
        external
        returns(bool)
    {
        var (currentInvestor, investedValue) = makeAvailable();
        Canceled(owner, currentInvestor, investedValue);
        return true;
    }

    // Accept the investor as the asset buyer and withdraw funds
    function withdrawFunds()
        protocolOrOwner
        hasStatus(Status.PENDING_OWNER_AGREEMENT)
        external
        returns(bool)
    {
        status = Status.INVESTED;
        uint256 _value = this.balance;
        owner.transfer(_value);
        Withdrawal(owner, investor, _value);
        return true;
    }

    // Refuse the pending investment
    function refuseInvestment()
        protocolOrOwner
        hasStatus(Status.PENDING_OWNER_AGREEMENT)
        external
        returns(bool)
    {
        var (currentInvestor, investedValue) = makeAvailable();
        Refused(owner, currentInvestor, investedValue);
        return true;
    }

    function sell(uint256 _sellValue)
        protocolOrInvestor
        hasStatus(Status.INVESTED)
        external
        returns(bool)
    {
        status = Status.FOR_SALE;
        sellData.value = _sellValue;
        ForSale(msg.sender, _sellValue);
        return true;
    }

    function cancelSellOrder()
        protocolOrInvestor
        hasStatus(Status.FOR_SALE)
        external
        returns(bool)
    {
        status = Status.INVESTED;
        sellData.value = uint256(0);
        CanceledSell(investor, value);
        return true;
    }

    function buy(address _buyer) payable
        hasStatus(Status.FOR_SALE)
        external
        returns(bool)
    {
        status = Status.PENDING_INVESTOR_AGREEMENT;
        sellData.buyer = _buyer;
        Invested(investor, _buyer, msg.value);
        return true;
    }

     function cancelSale()
        hasStatus(Status.PENDING_INVESTOR_AGREEMENT)
        external
        returns(bool)
    {
        require(msg.sender == protocol || msg.sender == sellData.buyer);
        status = Status.FOR_SALE;
        address buyer = sellData.buyer;
        uint256 _value = this.balance;
        buyer.transfer(_value);
        sellData.buyer = address(0);
        Canceled(investor, buyer, _value);
        return true;
    }

    // Refunds asset's buyer and became available for sale again
    function refuseSale()
        protocolOrInvestor
        hasStatus(Status.PENDING_INVESTOR_AGREEMENT)
        external
        returns(bool)
    {
        status = Status.FOR_SALE;
        address buyer = sellData.buyer;
        uint256 _value = this.balance;
        buyer.transfer(_value);
        sellData.buyer = address(0);
        Refused(investor, buyer, _value);
        return true;
    }

    // Withdraw funds, clear the sell data and change investor's address
    function acceptSale()
        protocolOrInvestor
        hasStatus(Status.PENDING_INVESTOR_AGREEMENT)
        external
        returns(bool)
    {
        status = Status.INVESTED;
        address currentInvestor = investor;
        uint256 _value = this.balance;
        currentInvestor.transfer(_value);
        investor = sellData.buyer;
        boughtValue = sellData.value;
        sellData.buyer = address(0);
        sellData.value = uint256(0);
        Withdrawal(currentInvestor, investor, _value);
        return true;
    }

    function returnInvestment() payable
        onlyOwner
        external
        returns(bool)
    {
        assert(status == Status.INVESTED || status == Status.FOR_SALE || status == Status.PENDING_INVESTOR_AGREEMENT);
        Status currentStatus = status;
        bool _isDelayed = isDelayed();
        status = _isDelayed ? Status.DELAYED_RETURN : Status.RETURNED;
        if (currentStatus == Status.PENDING_INVESTOR_AGREEMENT) {
            sellData.buyer.transfer(this.balance - msg.value);
        }
        investor.transfer(msg.value);
        if(tokenFuel > 0){
            address recipient = _isDelayed ? investor : owner;
            withdrawTokens(recipient, tokenFuel);
        }
        Returned(owner, investor, msg.value, _isDelayed);
        return true;
    }

    function supplyFuel(uint256 _amount)
        onlyOwner
        hasStatus(Status.AVAILABLE)
        external
        returns(bool)
    {
        require(token.transferFrom(msg.sender, this, _amount));
        tokenFuel += _amount;
        Supplied(owner, _amount, tokenFuel);
        return true;
    }

    function requireTokenFuel()
        onlyInvestor
        hasStatus(Status.INVESTED)
        onlyDelayed
        external
        returns(bool)
    {
        return withdrawTokens(investor, tokenFuel);
    }

}

pragma solidity ^0.4.18;

import './AssetEvents.sol';
import '../token/Token.sol';

// Defines methods and control modifiers for an investment
contract AssetLibrary is AssetEvents {

    // Asset owner
    address public owner;
    // Protocol
    address public protocol;
    // Asset currency
    string public currency;
    // Asset fixed value
    uint256 public value;
    //Value bought
    uint256 public boughtValue;
    // period to return the investment
    uint256 public paybackDays;
    // Gross return of investment
    uint256 public grossReturn;
    // Asset buyer
    address public investor;
    // Protocol version
    string public protocolVersion;
    // investment timestamp
    uint public investedAt;

    // asset fuel
    Token public token;
    uint256 public tokenFuel;

    // sell data
    struct Sell {
        uint256 value;
        address buyer;
    }

    Sell public sellData;

    // possible stages of an asset
    enum Status {
        AVAILABLE,
        PENDING_OWNER_AGREEMENT,
        INVESTED,
        FOR_SALE,
        PENDING_INVESTOR_AGREEMENT,
        RETURNED,
        DELAYED_RETURN
    }
    Status public status;

    // Checks the current asset's status
    modifier hasStatus(Status _status) {
        assert(status == _status);
        _;
    }

    // Checks if the owner is the caller
    modifier onlyOwner() {
        require(msg.sender == owner);
        _;
    }

    // Checks if the investor is the caller
    modifier onlyInvestor() {
        require(msg.sender == investor);
        _;
    }

    modifier protocolOrInvestor() {
        require(msg.sender == investor || msg.sender == protocol);
        _;
    }

    modifier protocolOrOwner() {
        require(msg.sender == owner || msg.sender == protocol);
        _;
    }

    modifier onlyDelayed(){
        require(isDelayed());
        _;
    }

    function isDelayed()
        view
        internal
        returns(bool)
    {
        return now > investedAt + paybackDays * 1 days;
    }

    // Refund and remove the current investor and make the asset available for investments
    function makeAvailable()
        hasStatus(Status.PENDING_OWNER_AGREEMENT)
        private
        returns(address, uint256)
    {
        status = Status.AVAILABLE;
        uint256 investedValue = this.balance;
        investor.transfer(investedValue);
        address currentInvestor = investor;
        investor = address(0);
        investedAt = uint(0);
        return (currentInvestor, investedValue);
    }

    function withdrawTokens(address _recipient, uint256 _amount)
        private
        returns(bool)
    {
        assert(tokenFuel >= _amount);
        require(token.transfer(_recipient, _amount));
        TokenWithdrawal(_recipient, _amount);
        tokenFuel -= _amount;
        return true;
    }

    // Add investment interest in this asset and retain the funds within the smart contract
    function invest(address _investor) payable
         hasStatus(Status.AVAILABLE)
         external
         returns(bool)
    {
        status = Status.PENDING_OWNER_AGREEMENT;
        investor = _investor;
        investedAt = now;
        Invested(owner, investor, this.balance);
        return true;
    }

    // Cancel the pending investment
    function cancelInvestment()
        protocolOrInvestor
        hasStatus(Status.PENDING_OWNER_AGREEMENT)
        external
        returns(bool)
    {
        var (currentInvestor, investedValue) = makeAvailable();
        Canceled(owner, currentInvestor, investedValue);
        return true;
    }

    // Accept the investor as the asset buyer and withdraw funds
    function withdrawFunds()
        protocolOrOwner
        hasStatus(Status.PENDING_OWNER_AGREEMENT)
        external
        returns(bool)
    {
        status = Status.INVESTED;
        uint256 _value = this.balance;
        owner.transfer(_value);
        Withdrawal(owner, investor, _value);
        return true;
    }

    // Refuse the pending investment
    function refuseInvestment()
        protocolOrOwner
        hasStatus(Status.PENDING_OWNER_AGREEMENT)
        external
        returns(bool)
    {
        var (currentInvestor, investedValue) = makeAvailable();
        Refused(owner, currentInvestor, investedValue);
        return true;
    }

    function sell(uint256 _sellValue)
        protocolOrInvestor
        hasStatus(Status.INVESTED)
        external
        returns(bool)
    {
        status = Status.FOR_SALE;
        sellData.value = _sellValue;
        ForSale(msg.sender, _sellValue);
        return true;
    }

    function cancelSellOrder()
        protocolOrInvestor
        hasStatus(Status.FOR_SALE)
        external
        returns(bool)
    {
        status = Status.INVESTED;
        sellData.value = uint256(0);
        CanceledSell(investor, value);
        return true;
    }

    function buy(address _buyer) payable
        hasStatus(Status.FOR_SALE)
        external
        returns(bool)
    {
        status = Status.PENDING_INVESTOR_AGREEMENT;
        sellData.buyer = _buyer;
        Invested(investor, _buyer, msg.value);
        return true;
    }

     function cancelSale()
        hasStatus(Status.PENDING_INVESTOR_AGREEMENT)
        external
        returns(bool)
    {
        require(msg.sender == protocol || msg.sender == sellData.buyer);
        status = Status.FOR_SALE;
        address buyer = sellData.buyer;
        uint256 _value = this.balance;
        buyer.transfer(_value);
        sellData.buyer = address(0);
        Canceled(investor, buyer, _value);
        return true;
    }

    // Refunds asset's buyer and became available for sale again
    function refuseSale()
        protocolOrInvestor
        hasStatus(Status.PENDING_INVESTOR_AGREEMENT)
        external
        returns(bool)
    {
        status = Status.FOR_SALE;
        address buyer = sellData.buyer;
        uint256 _value = this.balance;
        buyer.transfer(_value);
        sellData.buyer = address(0);
        Refused(investor, buyer, _value);
        return true;
    }

    // Withdraw funds, clear the sell data and change investor's address
    function acceptSale()
        protocolOrInvestor
        hasStatus(Status.PENDING_INVESTOR_AGREEMENT)
        external
        returns(bool)
    {
        status = Status.INVESTED;
        address currentInvestor = investor;
        uint256 _value = this.balance;
        currentInvestor.transfer(_value);
        investor = sellData.buyer;
        boughtValue = sellData.value;
        sellData.buyer = address(0);
        sellData.value = uint256(0);
        Withdrawal(currentInvestor, investor, _value);
        return true;
    }

    function returnInvestment() payable
        onlyOwner
        external
        returns(bool)
    {
        assert(status == Status.INVESTED || status == Status.FOR_SALE || status == Status.PENDING_INVESTOR_AGREEMENT);
        if (status == Status.PENDING_INVESTOR_AGREEMENT) {
            sellData.buyer.transfer(this.balance - msg.value);
        }
        bool _isDelayed = isDelayed();
        status = _isDelayed ? Status.DELAYED_RETURN : Status.RETURNED;
        investor.transfer(msg.value);
        if(tokenFuel > 0){
            address recipient = _isDelayed ? investor : owner;
            withdrawTokens(recipient, tokenFuel);
        }
        Returned(owner, investor, msg.value, _isDelayed);
        return true;
    }

    function supplyFuel(uint256 _amount)
        onlyOwner
        hasStatus(Status.AVAILABLE)
        external
        returns(bool)
    {
        require(token.transferFrom(msg.sender, this, _amount));
        tokenFuel += _amount;
        Supplied(owner, _amount, tokenFuel);
        return true;
    }

    function requireTokenFuel()
        onlyInvestor
        hasStatus(Status.INVESTED)
        onlyDelayed
        external
        returns(bool)
    {
        return withdrawTokens(investor, tokenFuel);
    }

}


Update comment - wallet description

Update comment - wallet description

As requested in review.

pragma solidity ^0.4.11;

import './token.sol';

/// @title Dutch auction contract - distribution of tokens using an auction.
contract DutchAuction {
    /*
     * Auction for the TKN Token.
     *
     * Terminology:
     * 1 token unit = Tei
     * 1 token = TKN = Tei * multiplier
     * multiplier set from token's number of decimals (i.e. 10**decimals)
     */

    /*
     * Storage
     */

    CustomToken public token;
    address public owner;
    address public wallet;

    // Price function parameters
    uint public price_factor;
    uint public price_const;

    // For calculating elapsed time for price
    uint public start_time;
    uint public end_time;
    uint public start_block;

    // Keep track of all ETH received in the bids
    uint public received_ether;

    // Keep track of funds claimed after auction has ended
    uint public funds_claimed;

    // Total number of Tei (TKN * multiplier) that will be auctioned
    uint public multiplier;
    uint public tokens_auctioned;

    // Wei per TKN (Tei * multiplier)
    uint public final_price;

    mapping (address => uint) public bids;

    Stages public stage;

    // TODO - remove after testing
    uint rounding_error_tokens;

    /*
     * Enums
     */
    enum Stages {
        AuctionDeployed,
        AuctionSetUp,
        AuctionStarted,
        AuctionEnded,
        TokensDistributed
    }

    /*
     * Modifiers
     */
    modifier atStage(Stages _stage) {
        require(stage == _stage);
        _;
    }

    modifier isOwner() {
        require(msg.sender == owner);
        _;
    }

    modifier isValidPayload() {
        require(msg.data.length == 0 || msg.data.length == 4 || msg.data.length == 36);
        _;
    }

    /*
     * Events
     */

    event Deployed(
        address indexed _auction,
        uint indexed _price_factor,
        uint indexed _price_const
    );
    event Setup();
    event SettingsChanged(uint indexed _price_factor, uint indexed _price_const);
    event AuctionStarted(uint indexed _start_time, uint indexed _block_number);
    event BidSubmission(
        address indexed _sender,
        uint indexed _amount,
        uint indexed _missing_funds
    );
    event ClaimedTokens(address indexed _recipient, uint indexed _sent_amount);
    event AuctionEnded(uint indexed _final_price);
    event TokensDistributed();

    /*
     * Public functions
     */

    /// @dev Contract constructor function sets price factor and constant for
    /// calculating the Dutch Auction price.
    /// @param _wallet Wallet address to which all contributed ETH will be forwarded.
    /// @param _price_factor Auction price factor.
    /// @param _price_const Auction price divisor constant.
    function DutchAuction(address _wallet, uint _price_factor, uint _price_const) public {
        require(_wallet != 0x0);
        wallet = _wallet;

        owner = msg.sender;
        stage = Stages.AuctionDeployed;
        Deployed(this, price_factor, price_const);
        changeSettings(_price_factor, _price_const);
    }

    /// @dev Fallback function for the contract, which calls bid() if the auction has started.
    function () public payable atStage(Stages.AuctionStarted) {
        bid(msg.sender);
    }

    /// @notice Set `_token` as the token address to be used in the auction.
    /// @dev Setup function sets external contracts addresses.
    /// @param _token Token address.
    function setup(address _token) public isOwner atStage(Stages.AuctionDeployed) {
        require(_token != 0x0);
        token = CustomToken(_token);
        require(token.owner() == owner);
        require(token.auction_address() == address(this));

        // Get number of Tei (TKN * multiplier) to be auctioned from token auction balance
        tokens_auctioned = token.balanceOf(this);

        // Set number of tokens multiplier from token decimals
        multiplier = 10**uint(token.decimals());

        stage = Stages.AuctionSetUp;
        Setup();

        // Tei auctioned
        require(tokens_auctioned > multiplier);
    }

    /// @notice Set `_price_factor` and `_price_const` as the new price factor
    /// and price divisor constant.
    /// @dev Changes auction start price factor before auction is started.
    /// @param _price_factor Updated price factor.
    /// @param _price_const Updated price divisor constant.
    function changeSettings(uint _price_factor, uint _price_const) public isOwner {
        require(stage == Stages.AuctionDeployed || stage == Stages.AuctionSetUp);
        require(_price_factor > 0);
        require(_price_const > 0);

        price_factor = _price_factor;
        price_const = _price_const;
        SettingsChanged(price_factor, price_const);
    }

    /// @notice Start the auction.
    /// @dev Starts auction and sets start_time.
    function startAuction() public isOwner atStage(Stages.AuctionSetUp) {
        stage = Stages.AuctionStarted;
        start_time = now;
        start_block = block.number;
        AuctionStarted(start_time, start_block);
    }

    /// @notice Finalize the auction - sets the final price and changes the auction
    /// stage after no bids are allowed anymore.
    /// @dev Finalize auction and set the final token price.
    function finalizeAuction() public atStage(Stages.AuctionStarted)
    {
        // Missing funds should be 0 at this point
        uint missing_funds = missingFundsToEndAuction();
        assert(missing_funds == 0);

        // Calculate the final price WEI / TKN
        final_price = received_ether / (tokens_auctioned / multiplier);

        end_time = now;
        stage = Stages.AuctionEnded;
        AuctionEnded(final_price);

        assert(final_price > 0);
    }

    /// --------------------------------- Auction Functions ------------------

    /// @notice Send `msg.value` WEI to the auction from the `msg.sender` account.
    /// @dev Allows to send a bid to the auction.
    function bid() public payable atStage(Stages.AuctionStarted) {
        bid(msg.sender);
    }

    /// @notice Send `msg.value` WEI to the auction from the `receiver` account.
    /// @dev Allows to send a bid to the auction.
    /// @param receiver Bidder account address.
    function bid(address receiver)
        public
        payable
        isValidPayload
        atStage(Stages.AuctionStarted)
    {
        require(receiver != 0x0);
        require(msg.value > 0);
        require(bids[receiver] + msg.value >= msg.value);

        uint pre_receiver_funds = bids[receiver];

        // Missing funds without the current bid value
        uint missing_funds = missingFundsToEndAuction();

        // We only allow bid values less than the missing funds to end the auction value.
        require(msg.value <= missing_funds);

        bids[receiver] += msg.value;
        received_ether += msg.value;

        // Send bid amount to wallet
        wallet.transfer(msg.value);

        BidSubmission(receiver, msg.value, missing_funds);

        assert(bids[receiver] == pre_receiver_funds + msg.value);
        assert(received_ether >= msg.value);
    }

    /// @notice Claim auction tokens for `msg.sender` after the auction has ended.
    /// @dev Claims tokens for bidder after auction. To be used if tokens can be claimed by bidders, individually.
    function claimTokens() public atStage(Stages.AuctionEnded) {
        claimTokens(msg.sender);
    }

    /// @notice Claim auction tokens for `receiver` after the auction has ended.
    /// @dev Claims tokens for bidder after auction.
    /// @param receiver Tokens will be assigned to this address if set.
    function claimTokens(address receiver)
        public
        isValidPayload
        atStage(Stages.AuctionEnded)
    {
        require(receiver != 0x0);
        require(bids[receiver] > 0);

        // Number of Tei = bidded_wei / wei_per_TKN * multiplier
        uint num = multiplier * bids[receiver] / final_price;

        // Update funds claimed with full bidded amount
        // rounding errors are included to not block the contract
        funds_claimed += bids[receiver];

        // Set receiver bid to 0 before assigning tokens
        bids[receiver] = 0;

        require(token.transfer(receiver, num));

        ClaimedTokens(receiver, num);

        // Test for a correct claimed tokens calculation
        /* TODO remove this after testing */
        uint auction_unclaimed_tokens = token.balanceOf(this);

        uint unclaimed_tokens = (received_ether - funds_claimed) * multiplier / final_price;
        unclaimed_tokens += rounding_error_tokens;

        if (auction_unclaimed_tokens != unclaimed_tokens) {
            rounding_error_tokens += 1;
            unclaimed_tokens += 1;
        }
        assert(auction_unclaimed_tokens == unclaimed_tokens);
        /* End of removable test */

        // After the last tokens are claimed, we send the auction balance to the owner
        // and change the auction stage
        if (funds_claimed == received_ether) {
            stage = Stages.TokensDistributed;
            TokensDistributed();
        }

        assert(token.balanceOf(receiver) >= num);
        assert(bids[receiver] == 0);
    }

    /*
     *  Private functions
     */

    /// @dev Calculates the token price (WEI / TKN) at the current timestamp
    /// during the auction; elapsed time = 0 before auction starts.
    /// @dev At AuctionDeployed the price is 1, because multiplier is 0
    /// @return Returns the token price - Wei per TKN.
    function calcTokenPrice() constant private returns (uint) {
        uint elapsed;
        if (stage == Stages.AuctionStarted) {
            elapsed = now - start_time;
        }
        return multiplier * price_factor / (elapsed + price_const) + 1;
    }

    /// --------------------------------- Price Functions ----------------------

    /// @notice Get the TKN price in WEI during the auction, at the moment of
    /// calling this method. Returns `0` if auction has ended.
    /// @dev Calculates current token price.
    /// @return Returns num Wei per TKN (multiplier * Tei).
    function price() public constant returns (uint) {
        if (stage == Stages.AuctionEnded ||
            stage == Stages.TokensDistributed) {
            return 0;
        }
        return calcTokenPrice();
    }

    /// @notice Get the missing funds needed to end the auction,
    /// calculated at the current TKN price.
    /// @dev The missing funds amount necessary to end the auction at the current price.
    /// @return Returns the missing funds amount.
    function missingFundsToEndAuction() constant public returns (uint) {
        uint funds_at_price = tokens_auctioned * price() / multiplier;
        if (funds_at_price < received_ether) {
            return 0;
        }
        return funds_at_price - received_ether;
    }
}

pragma solidity ^0.4.11;

import './token.sol';

/// @title Dutch auction contract - distribution of tokens using an auction.
contract DutchAuction {
    /*
     * Auction for the TKN Token.
     *
     * Terminology:
     * 1 token unit = Tei
     * 1 token = TKN = Tei * multiplier
     * multiplier set from token's number of decimals (i.e. 10**decimals)
     */

    /*
     * Storage
     */

    CustomToken public token;
    address public owner;
    address public wallet;

    // Price function parameters
    uint public price_factor;
    uint public price_const;

    // For calculating elapsed time for price
    uint public start_time;
    uint public end_time;
    uint public start_block;

    // Keep track of all ETH received in the bids
    uint public received_ether;

    // Keep track of funds claimed after auction has ended
    uint public funds_claimed;

    // Total number of Tei (TKN * multiplier) that will be auctioned
    uint public multiplier;
    uint public tokens_auctioned;

    // Wei per TKN (Tei * multiplier)
    uint public final_price;

    mapping (address => uint) public bids;

    Stages public stage;

    // TODO - remove after testing
    uint rounding_error_tokens;

    /*
     * Enums
     */
    enum Stages {
        AuctionDeployed,
        AuctionSetUp,
        AuctionStarted,
        AuctionEnded,
        TokensDistributed
    }

    /*
     * Modifiers
     */
    modifier atStage(Stages _stage) {
        require(stage == _stage);
        _;
    }

    modifier isOwner() {
        require(msg.sender == owner);
        _;
    }

    modifier isValidPayload() {
        require(msg.data.length == 0 || msg.data.length == 4 || msg.data.length == 36);
        _;
    }

    /*
     * Events
     */

    event Deployed(
        address indexed _auction,
        uint indexed _price_factor,
        uint indexed _price_const
    );
    event Setup();
    event SettingsChanged(uint indexed _price_factor, uint indexed _price_const);
    event AuctionStarted(uint indexed _start_time, uint indexed _block_number);
    event BidSubmission(
        address indexed _sender,
        uint indexed _amount,
        uint indexed _missing_funds
    );
    event ClaimedTokens(address indexed _recipient, uint indexed _sent_amount);
    event AuctionEnded(uint indexed _final_price);
    event TokensDistributed();

    /*
     * Public functions
     */

    /// @dev Contract constructor function sets price factor and constant for
    /// calculating the Dutch Auction price.
    /// @param _wallet Wallet address for contributed ETH.
    /// @param _price_factor Auction price factor.
    /// @param _price_const Auction price divisor constant.
    function DutchAuction(address _wallet, uint _price_factor, uint _price_const) public {
        require(_wallet != 0x0);
        wallet = _wallet;

        owner = msg.sender;
        stage = Stages.AuctionDeployed;
        Deployed(this, price_factor, price_const);
        changeSettings(_price_factor, _price_const);
    }

    /// @dev Fallback function for the contract, which calls bid() if the auction has started.
    function () public payable atStage(Stages.AuctionStarted) {
        bid(msg.sender);
    }

    /// @notice Set `_token` as the token address to be used in the auction.
    /// @dev Setup function sets external contracts addresses.
    /// @param _token Token address.
    function setup(address _token) public isOwner atStage(Stages.AuctionDeployed) {
        require(_token != 0x0);
        token = CustomToken(_token);
        require(token.owner() == owner);
        require(token.auction_address() == address(this));

        // Get number of Tei (TKN * multiplier) to be auctioned from token auction balance
        tokens_auctioned = token.balanceOf(this);

        // Set number of tokens multiplier from token decimals
        multiplier = 10**uint(token.decimals());

        stage = Stages.AuctionSetUp;
        Setup();

        // Tei auctioned
        require(tokens_auctioned > multiplier);
    }

    /// @notice Set `_price_factor` and `_price_const` as the new price factor
    /// and price divisor constant.
    /// @dev Changes auction start price factor before auction is started.
    /// @param _price_factor Updated price factor.
    /// @param _price_const Updated price divisor constant.
    function changeSettings(uint _price_factor, uint _price_const) public isOwner {
        require(stage == Stages.AuctionDeployed || stage == Stages.AuctionSetUp);
        require(_price_factor > 0);
        require(_price_const > 0);

        price_factor = _price_factor;
        price_const = _price_const;
        SettingsChanged(price_factor, price_const);
    }

    /// @notice Start the auction.
    /// @dev Starts auction and sets start_time.
    function startAuction() public isOwner atStage(Stages.AuctionSetUp) {
        stage = Stages.AuctionStarted;
        start_time = now;
        start_block = block.number;
        AuctionStarted(start_time, start_block);
    }

    /// @notice Finalize the auction - sets the final price and changes the auction
    /// stage after no bids are allowed anymore.
    /// @dev Finalize auction and set the final token price.
    function finalizeAuction() public atStage(Stages.AuctionStarted)
    {
        // Missing funds should be 0 at this point
        uint missing_funds = missingFundsToEndAuction();
        assert(missing_funds == 0);

        // Calculate the final price WEI / TKN
        final_price = received_ether / (tokens_auctioned / multiplier);

        end_time = now;
        stage = Stages.AuctionEnded;
        AuctionEnded(final_price);

        assert(final_price > 0);
    }

    /// --------------------------------- Auction Functions ------------------

    /// @notice Send `msg.value` WEI to the auction from the `msg.sender` account.
    /// @dev Allows to send a bid to the auction.
    function bid() public payable atStage(Stages.AuctionStarted) {
        bid(msg.sender);
    }

    /// @notice Send `msg.value` WEI to the auction from the `receiver` account.
    /// @dev Allows to send a bid to the auction.
    /// @param receiver Bidder account address.
    function bid(address receiver)
        public
        payable
        isValidPayload
        atStage(Stages.AuctionStarted)
    {
        require(receiver != 0x0);
        require(msg.value > 0);
        require(bids[receiver] + msg.value >= msg.value);

        uint pre_receiver_funds = bids[receiver];

        // Missing funds without the current bid value
        uint missing_funds = missingFundsToEndAuction();

        // We only allow bid values less than the missing funds to end the auction value.
        require(msg.value <= missing_funds);

        bids[receiver] += msg.value;
        received_ether += msg.value;

        // Send bid amount to wallet
        wallet.transfer(msg.value);

        BidSubmission(receiver, msg.value, missing_funds);

        assert(bids[receiver] == pre_receiver_funds + msg.value);
        assert(received_ether >= msg.value);
    }

    /// @notice Claim auction tokens for `msg.sender` after the auction has ended.
    /// @dev Claims tokens for bidder after auction. To be used if tokens can be claimed by bidders, individually.
    function claimTokens() public atStage(Stages.AuctionEnded) {
        claimTokens(msg.sender);
    }

    /// @notice Claim auction tokens for `receiver` after the auction has ended.
    /// @dev Claims tokens for bidder after auction.
    /// @param receiver Tokens will be assigned to this address if set.
    function claimTokens(address receiver)
        public
        isValidPayload
        atStage(Stages.AuctionEnded)
    {
        require(receiver != 0x0);
        require(bids[receiver] > 0);

        // Number of Tei = bidded_wei / wei_per_TKN * multiplier
        uint num = multiplier * bids[receiver] / final_price;

        // Update funds claimed with full bidded amount
        // rounding errors are included to not block the contract
        funds_claimed += bids[receiver];

        // Set receiver bid to 0 before assigning tokens
        bids[receiver] = 0;

        require(token.transfer(receiver, num));

        ClaimedTokens(receiver, num);

        // Test for a correct claimed tokens calculation
        /* TODO remove this after testing */
        uint auction_unclaimed_tokens = token.balanceOf(this);

        uint unclaimed_tokens = (received_ether - funds_claimed) * multiplier / final_price;
        unclaimed_tokens += rounding_error_tokens;

        if (auction_unclaimed_tokens != unclaimed_tokens) {
            rounding_error_tokens += 1;
            unclaimed_tokens += 1;
        }
        assert(auction_unclaimed_tokens == unclaimed_tokens);
        /* End of removable test */

        // After the last tokens are claimed, we send the auction balance to the owner
        // and change the auction stage
        if (funds_claimed == received_ether) {
            stage = Stages.TokensDistributed;
            TokensDistributed();
        }

        assert(token.balanceOf(receiver) >= num);
        assert(bids[receiver] == 0);
    }

    /*
     *  Private functions
     */

    /// @dev Calculates the token price (WEI / TKN) at the current timestamp
    /// during the auction; elapsed time = 0 before auction starts.
    /// @dev At AuctionDeployed the price is 1, because multiplier is 0
    /// @return Returns the token price - Wei per TKN.
    function calcTokenPrice() constant private returns (uint) {
        uint elapsed;
        if (stage == Stages.AuctionStarted) {
            elapsed = now - start_time;
        }
        return multiplier * price_factor / (elapsed + price_const) + 1;
    }

    /// --------------------------------- Price Functions ----------------------

    /// @notice Get the TKN price in WEI during the auction, at the moment of
    /// calling this method. Returns `0` if auction has ended.
    /// @dev Calculates current token price.
    /// @return Returns num Wei per TKN (multiplier * Tei).
    function price() public constant returns (uint) {
        if (stage == Stages.AuctionEnded ||
            stage == Stages.TokensDistributed) {
            return 0;
        }
        return calcTokenPrice();
    }

    /// @notice Get the missing funds needed to end the auction,
    /// calculated at the current TKN price.
    /// @dev The missing funds amount necessary to end the auction at the current price.
    /// @return Returns the missing funds amount.
    function missingFundsToEndAuction() constant public returns (uint) {
        uint funds_at_price = tokens_auctioned * price() / multiplier;
        if (funds_at_price < received_ether) {
            return 0;
        }
        return funds_at_price - received_ether;
    }
}


create issuer contract

create issuer contract

contract coin {}

contract issuer {
    address public issuerAddr;
    address public coinAddr;
    coin public pluton;

    struct Rebate {
        uint plutonRewardRate;
        uint reqieredExchangeSpeed;
        uint currentExchangeSpeedRate;
        uint lastTimestamp;
        uint baseUnitForRebate;
    }
    Rebate public rebate;

    modifier ownerCheck { if (msg.sender == issuerAddr) _ }

    /*Initial */
    function issuer(address _issuer, coin _plutonAddr) {
        issuerAddr = _issuer;
        coinAddr = _plutonAddr;
        rebate.plutonRewardRate = 3; // 3%
        rebate.baseUnitForRebate = 10;
        pluton = coin(_plutonAddr);
    }

    /* issuer functions */

    function getRebate(uint _btcAmount, string txID, address _btcSeller) ownerCheck returns(uint plutonReward) {
        rebate.currentExchangeSpeedRate =  _btcAmount / (now - rebate.lastTimestamp) / rebate.reqieredExchangeSpeed;
        rebate.plutonRewardRate = rebate.plutonRewardRate * rebate.currentExchangeSpeedRate / rebate.baseUnitForRebate;
        plutonReward = _btcAmount * rebate.plutonRewardRate;
         //  pluton.emmision(plutonReward);
        //    pluton.transfer(plutonReward, _btcSeller);
    }

}

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


Fix #5: listing cannot exit if never challenged

pragma solidity ^0.4.11;

import "./StandardToken.sol";
import "./PLCRVoting.sol";
import "./Parameterizer.sol";

contract Registry {

    // ------
    // EVENTS
    // ------

    event _Application(string domain, uint deposit);
    event _Challenge(string domain, uint deposit, uint pollID);
    event _Deposit(string domain, uint added, uint newTotal);
    event _Withdrawal(string domain, uint withdrew, uint newTotal);

    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;        // (remaining) 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 totalTokens;       // (remaining) amount of tokens used for voting by the winning side
    }

    // maps challengeIDs to associated challenge data
    mapping(uint => Challenge) public 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
    StandardToken public token;
    PLCRVoting public voting;
    Parameterizer public parameterizer;

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

    function Registry(
        address _tokenAddr,
        address _paramsAddr
    ) {
        token = StandardToken(_tokenAddr);
        parameterizer = Parameterizer(_paramsAddr);
        voting = new PLCRVoting(_tokenAddr);
    }

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

    //Allow a user to start an application
    //take tokens from user and set apply stage end time
    function apply(string domain, uint amount) external {
        require(!isWhitelisted(domain));
        require(!appExists(domain));
        require(amount >= parameterizer.get("minDeposit"));

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

        //transfer tokens
        require(token.transferFrom(listing.owner, this, amount));

        //set apply stage end time
        listing.applicationExpiry = block.timestamp + parameterizer.get("applyStageLen");
        listing.currentDeposit = amount;

        _Application(domain, amount);
    }

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

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

        listing.currentDeposit += amount;

        _Deposit(domain, amount, listing.currentDeposit);
    }

    //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 storage listing = listingMap[sha3(domain)];

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

        listing.currentDeposit -= amount;

        _Withdrawal(domain, amount, listing.currentDeposit);
    }

    //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 storage listing = listingMap[sha3(domain)];

        require(isWhitelisted(domain));
        // cannot exit during ongoing challenge
        require(listing.challengeID == 0 || 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 storage listing = listingMap[domainHash];
        //to be challenged, domain must be in apply stage or already on the whitelist
        require(appExists(domain) || listing.whitelisted);
        // prevent multiple challenges
        require(listing.challengeID == 0 || challengeMap[listing.challengeID].resolved);
        uint deposit = parameterizer.get("minDeposit");
        if (listing.currentDeposit < deposit) {
            // not enough tokens, publisher auto-delisted
            resetListing(domain);
            return 0;
        }
        //take tokens from challenger
        require(token.transferFrom(msg.sender, this, deposit));
        //start poll
        uint pollID = voting.startPoll(domain,
            parameterizer.get("voteQuorum"),
            parameterizer.get("commitPeriodLen"),
            parameterizer.get("revealPeriodLen")
        );

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

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

        _Challenge(domain, deposit, pollID);
        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 is not yet over, isPassed will throw
            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

            // store the total tokens used for voting by the winning side for reward purposes
            challengeMap[challengeID].totalTokens = voting.getTotalNumberOfTokensForWinningOption(challengeID);
        }
    }

    // ----------------
    // TOKEN FUNCTIONS:
    // ----------------

    // called by voter to claim reward for each completed vote
    // someone must call updateStatus() before this can be called
    function claimReward(uint _challengeID, uint _salt) public {
        // ensure voter has not already claimed tokens and challenge results have been processed
        require(tokenClaims[_challengeID][msg.sender] == false);
        require(challengeMap[_challengeID].resolved = true);

        uint reward = calculateTokens(_challengeID, _salt, msg.sender);
        require(token.transfer(msg.sender, reward));

        // ensures a voter cannot claim tokens again

        tokenClaims[_challengeID][msg.sender] = true;
    }

    // helper function to claimReward()
    function calculateTokens(uint _challengeID, uint _salt, address _voter) private returns (uint) {
        uint totalTokens = challengeMap[_challengeID].totalTokens;
        uint rewardPool = challengeMap[_challengeID].rewardPool;
        uint voterTokens = voting.getNumPassingTokens(_voter, _challengeID, _salt);
        uint reward = (voterTokens * rewardPool) / totalTokens;

        // subtract voter's information to preserve the participation ratios of other voters
        // compared to the remaining pool of rewards
        challengeMap[_challengeID].totalTokens -= voterTokens;
        challengeMap[_challengeID].rewardPool -= reward;

        return 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 storage listing = listingMap[domainHash];
        //transfer any remaining balance back to the owner
        if (listing.currentDeposit > 0)
            require(token.transfer(listing.owner, listing.currentDeposit));
        delete listingMap[domainHash];
    }
}

pragma solidity ^0.4.11;

import "./StandardToken.sol";
import "./PLCRVoting.sol";
import "./Parameterizer.sol";

contract Registry {

    // ------
    // EVENTS
    // ------

    event _Application(string domain, uint deposit);
    event _Challenge(string domain, uint deposit, uint pollID);
    event _Deposit(string domain, uint added, uint newTotal);
    event _Withdrawal(string domain, uint withdrew, uint newTotal);

    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;        // (remaining) 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 totalTokens;       // (remaining) amount of tokens used for voting by the winning side
    }

    // maps challengeIDs to associated challenge data
    mapping(uint => Challenge) public 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
    StandardToken public token;
    PLCRVoting public voting;
    Parameterizer public parameterizer;

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

    function Registry(
        address _tokenAddr,
        address _paramsAddr
    ) {
        token = StandardToken(_tokenAddr);
        parameterizer = Parameterizer(_paramsAddr);
        voting = new PLCRVoting(_tokenAddr);
    }

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

    //Allow a user to start an application
    //take tokens from user and set apply stage end time
    function apply(string domain, uint amount) external {
        require(!isWhitelisted(domain));
        require(!appExists(domain));
        require(amount >= parameterizer.get("minDeposit"));

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

        //transfer tokens
        require(token.transferFrom(listing.owner, this, amount));

        //set apply stage end time
        listing.applicationExpiry = block.timestamp + parameterizer.get("applyStageLen");
        listing.currentDeposit = amount;

        _Application(domain, amount);
    }

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

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

        listing.currentDeposit += amount;

        _Deposit(domain, amount, listing.currentDeposit);
    }

    //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 storage listing = listingMap[sha3(domain)];

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

        listing.currentDeposit -= amount;

        _Withdrawal(domain, amount, listing.currentDeposit);
    }

    //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 storage 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 storage listing = listingMap[domainHash];
        //to be challenged, domain must be in apply stage or already on the whitelist
        require(appExists(domain) || listing.whitelisted);
        // prevent multiple challenges
        require(listing.challengeID == 0 || challengeMap[listing.challengeID].resolved);
        uint deposit = parameterizer.get("minDeposit");
        if (listing.currentDeposit < deposit) {
            // not enough tokens, publisher auto-delisted
            resetListing(domain);
            return 0;
        }
        //take tokens from challenger
        require(token.transferFrom(msg.sender, this, deposit));
        //start poll
        uint pollID = voting.startPoll(domain,
            parameterizer.get("voteQuorum"),
            parameterizer.get("commitPeriodLen"),
            parameterizer.get("revealPeriodLen")
        );

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

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

        _Challenge(domain, deposit, pollID);
        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 is not yet over, isPassed will throw
            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

            // store the total tokens used for voting by the winning side for reward purposes
            challengeMap[challengeID].totalTokens = voting.getTotalNumberOfTokensForWinningOption(challengeID);
        }
    }

    // ----------------
    // TOKEN FUNCTIONS:
    // ----------------

    // called by voter to claim reward for each completed vote
    // someone must call updateStatus() before this can be called
    function claimReward(uint _challengeID, uint _salt) public {
        // ensure voter has not already claimed tokens and challenge results have been processed
        require(tokenClaims[_challengeID][msg.sender] == false);
        require(challengeMap[_challengeID].resolved = true);

        uint reward = calculateTokens(_challengeID, _salt, msg.sender);
        require(token.transfer(msg.sender, reward));

        // ensures a voter cannot claim tokens again

        tokenClaims[_challengeID][msg.sender] = true;
    }

    // helper function to claimReward()
    function calculateTokens(uint _challengeID, uint _salt, address _voter) private returns (uint) {
        uint totalTokens = challengeMap[_challengeID].totalTokens;
        uint rewardPool = challengeMap[_challengeID].rewardPool;
        uint voterTokens = voting.getNumPassingTokens(_voter, _challengeID, _salt);
        uint reward = (voterTokens * rewardPool) / totalTokens;

        // subtract voter's information to preserve the participation ratios of other voters
        // compared to the remaining pool of rewards
        challengeMap[_challengeID].totalTokens -= voterTokens;
        challengeMap[_challengeID].rewardPool -= reward;

        return 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 storage listing = listingMap[domainHash];
        //transfer any remaining balance back to the owner
        if (listing.currentDeposit > 0)
            require(token.transfer(listing.owner, listing.currentDeposit));
        delete listingMap[domainHash];
    }
}


Added knowledge based thesaurus

Added knowledge based thesaurus

/*
 * Interface for object comparation
 */
contract Comparable {
   function isEqual(Comparable _to) returns (bool);
}

/*
 * Contract for objects that can be morder
 */
contract Mortal {
    /* Contract owner address */
    address public owner;

    /* Store owner on creation */
    function Mortal() { owner = msg.sender; }

    /* Only owner can kill me */
    function kill() {
        if (msg.sender == owner) suicide(this);
    }
}

/*
 * Knowledge is a generic declaration of object or process
 */
contract Knowledge is Comparable, Mortal {
    /* Knowledge can have a type described below */
    int public OBJECT  = 1;
    int public PROCESS = 2;
    /* Knowledge type is a int value */
    int public knowledgeType;

    /* Constructor gets the type as argument */
    function Knowledge(int _type) { knowledgeType = _type; }

    /* Generic Knowledge comparation procedure */
    function isEqual(Knowledge _to) returns (bool) {
        // Knowledge with different types can't be equal
        if (_to.knowledgeType() != knowledgeType)
            return false;
        /*
         * Knowledge with the same type can be compared,
         * comparation procedure implemented in the inherit types
         */
        if (knowledgeType == OBJECT) {
            return KObject(this).isEqual(KObject(_to));
        } else {
            return KProcess(this).isEqual(KProcess(_to));
        }
    }
}

contract KObject is Knowledge(Knowledge.OBJECT) {

    /* Property describe attribute of presented object */
    struct Property {
        string name;
        string value;
    }
    /* List of object properties */
    Property[] public properties;
    /* Name to value mapping */
    mapping (string => string) propertyValueOf;

    /* Described object can be consist of some another objects */
    KObject[] public components;

    /*
     * The equal objects has:
     *  - equal properties
     *  - equal components
     */
    function isEqual(KObject _to) returns (bool) {
        return isEqualProperties(_to) && isEqualComponents(_to);
    }

    function isEqualProperties(KObject _to) returns (bool) {
        // Count of properties in equal objects should be same
        if (properties.length != _to.properties.length)
            return false;

        // Compare every property of objects
        for (var i = 0; i < properties.length; ++i) {
            // Take a name of current property
            var name = properties[i].name;

            // Compare value of the same properties
            if (propertyValueOf[name] != _to.propertyValueOf[name])
                return false;
        }
        return true;
    }

    function isEqualComponents(KObject _to) returns (bool) {
        // Count of components in equal objects should be same
        if (components.length != _to.components.length)
            return false;

        // Compare every components of objects
        for (var i = 0; i < components.length; ++i) {
            var equalFound = false;

            for (var j = 0; j < _to.components.length; ++j)
                equalFound |= components[i].isEqual(_to.components[j]);

            // Return false if no equal component found
            if (!equalFound)
                return false;
        }
        return true;
    }
}

contract KProcess is Knowledge(Knowledge.PROCESS) {
    /*
     * Morphism describe knowledge manipulation line
     * e.g. apple production have a morphism with
     * three objects: Ground -> AppleTree -> Apple
     * this knowledges can be stored in morphism list
     * as [ Ground, AppleTree, Apple ]
     */
    Knowledge[] morphism;

    function append(Knowledge _knowledge) {
        morphism[morphism.length++] = _knowledge;
    }

    function isEqual(KProcess _to) {
        // Count of knowledges in equal processes should be same
        if (morphism.length != _to.morphism.length)
            return false;

        for (var i = 0; i < morphism.length; ++i)
            // All knowledge in morphism line should be equal
            if (!morphism[i].isEqual(_to.morphism[i]))
                return false;
        return true;
    }
}

contract KnowledgeIndex {
    /* Available knowledge names */
    string[] public thesaurus;

    /* Mapping to knowledge from name */
    mapping (string => Knowledge) knowledgeOf;

    /*
     * Insert knowledge by name
     *   knowledge instance with the same name will be replaced
     */
    function insert(string _name, Knowledge _knowledge) {
        knowledgeOf[_name] = _knowledge;

        // Check when thesaurus already contains name
        if (!thesaurusCheck(_name))
            thesaurus[thesaurus.length++] = _name;
    }

    function thesaurusCheck(string _name) {
        for (var i = 0; i < thesaurus.length; ++i)
            if (thesaurus[i] == _name)
                return true;
        return false;
    }
}

contract thesaurus {
	string public name;
	string public desc;
	address public owner;

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

	struct Prop {
		string itemprop;
		string itemtype;
		string desc;
		string dataType;
	}

	Prop[] public propList;
	mapping (bytes32 => uint) public itempropOf;
	mapping (bytes32 => bool) public itempropExistOf;

	struct Enum {
		uint propListID;
	}

	struct Metadata {
		string itemscope;
		string desc;
		Enum[]  enumPropList;
		uint numProp;
	}

	Metadata[] schemaorgList;
	/* Help you find itemscope proplist*/
	mapping (bytes32 => uint) public itemscopeOf;
	mapping (bytes32 => bool) public itemscopeExistOf;

	function thesaurus(string _name, string _desc) {
		name = _name;
		desc = _desc;
		owner = msg.sender;
	}

	function getPropID(string _itemprop) returns(bool result, uint propID){
		if(!itempropExistOf[sha3(_itemprop)]) break;
		result = true;
		propID = itempropOf[sha3(_itemprop)];
		return(result, propID);
	}

	function getProp(uint _propID) returns(string itemprop, string itemtype, string desc, string dataType){
		Prop p = propList[_propID];
		return(p.itemprop, p.itemtype, p.desc, p.dataType);
	}

	function getMetadataID(string _itemscope) returns(bool result, uint metadataID){
		if(!itemscopeExistOf[sha3(_itemscope)]) break;
		result = true;
		metadataID = itemscopeOf[sha3(_itemscope)];
		return(result, metadataID);
	}

	function getMetadataNumProp(uint _itemscopeID) returns(string itemscope, uint numProp){
		Metadata m = schemaorgList[_itemscopeID];
		return(m.itemscope, m.numProp);
	}
}

contract thesaurusAdmin is thesaurus {

	function setProp(string _itemprop, string _itemtype, string _desc, string _dataType) ownerCheck returns(uint propID) {
		propID = propList.length++;
        Prop p = propList[propID];
        p.itemprop = _itemprop;
        p.itemtype = _itemtype;
        p.desc = _desc;
        p.dataType = _dataType;
        itempropExistOf[sha3(p.itemprop)] = true;
        itempropOf[sha3(p.itemprop)] = propID;
        return propID;
	}

	function setMetadata(string _itemscope, uint _desc, uint _propID) ownerCheck returns(uint enumPropListID) {
		uint metadataID;
		if(!itemscopeExistOf[sha3(_itemscope)]) {
			metadataID = schemaorgList.length++;
        	itemscopeExistOf[sha3(m.itemscope)] = true;
        	itemscopeOf[sha3(m.itemscope)] = metadataID;
    	} else {
    		metadataID = itemscopeOf[sha3(_itemscope)];
    	}

    	Metadata m = schemaorgList[metadataID];
        m.itemscope = _itemscope;
        m.desc = _desc;

        enumPropListID = m.enumPropList.length++;
       	Enum e = m.enumPropList[enumPropListID];
        e.propListID = _propID;
        m.numProp +=1;
    	return enumPropListID;
	}
}


assign balances to test addresses

assign balances to test addresses

pragma solidity ^0.4.13;

// This is just a simple example of a coin-like contract.
// It is not standards compatible and cannot be expected to talk to other
// coin/token contracts. If you want to create a standards-compliant
// token, see: https://github.com/ConsenSys/Tokens. Cheers!

import "./ERC223/ERC223BasicToken.sol";

contract MetaCoin is ERC223BasicToken {

	/*
		Testing addresses generated from seed.txt
	*/
    address[10] private testAddresses;
    uint private testBalance = 100;

    function assignTestAddresses() internal {
		testAddresses[0] = 0x00b35291d1844ceecf24ccb64d9d89df94c43393;
		testAddresses[1] = 0xf14ef8908770ee9edb567a8e30dfe7f35e0f9665;
		testAddresses[2] = 0x008b12c3bb5e83a99308fed2047777eca5eaac66;
		testAddresses[3] = 0x0d06d3207f4909ce883ab331273848f8e15a0f23;
		testAddresses[4] = 0xd0f38630e43b6f1d04944767b8ac0fd266b116d4;
		testAddresses[5] = 0x231fd5abf045fad239c115c36c20f9ec1e8d3cca;
		testAddresses[6] = 0x6cf26481d38988e3dbd7ef06834d56af8970c958;
		testAddresses[7] = 0xeef7e160a0d5313916d460ce86f90dc3530de0f0;
		testAddresses[8] = 0xd9ea475bc4f73307e9774c8ce0315b0e435d0490;
		testAddresses[9] = 0xecf3c1eb8cf920bd79a96a3a3f0c7cc689dd6be0;
    }

	function assignTestCoins(uint _testBalance) internal {
		for (uint8 i = 0; i < testAddresses.length; i++) {
			balances[testAddresses[i]] = _testBalance;
		}
	}

	function MetaCoin() {
		assignTestAddresses();
		assignTestCoins(testBalance);
	}

	function getBalance(address _addr) returns(uint) {
		return balances[_addr];
	}

	function sendCoin(address _to, uint _value) {
		transfer(_to, _value);
	}

}

pragma solidity ^0.4.13;

// This is just a simple example of a coin-like contract.
// It is not standards compatible and cannot be expected to talk to other
// coin/token contracts. If you want to create a standards-compliant
// token, see: https://github.com/ConsenSys/Tokens. Cheers!

import "./ERC223/ERC223BasicToken.sol";

contract MetaCoin is ERC223BasicToken {

	function MetaCoin() { }

	function sendCoin(address receiver, uint amount) returns(bool sufficient) {
		transfer(receiver, amount);
		return true;
	}

	function getBalance(address addr) returns(uint) {
		return balanceOf(addr);
	}
}


further integration

further integration

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 (?)
// ask about wallet location

contract Registry {

    address public wallet;
    StandardToken public token;

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

    mapping(bytes32 => Publisher) public whitelist;
    mapping(bytes32 => Application) public appPool;
    mapping(uint => bool) public voteProcessed;
    mapping(address => mapping(uint => bool)) public voterInfo;

    // Constructor
    function Registry(address _token, address _wallet) {
        token = StandardToken(_token);
        wallet = _wallet;
    }

    // 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, wallet, 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, wallet, 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);
    }

    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);
            appPool[domainHash].owner = 0;
            // give tokens to applicant based on dist and total tokens
        }
        else {
            appPool[domainHash].owner = 0;
            // give tokens to challenger based on dist and total tokens
        }
        // 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) {
        // checks if a voter has claimed tokens
        require(voterInfo[msg.sender][_pollID] == false);
        giveTokens(_pollID, msg.sender);
        // ensures a voter cannot claim tokens again
        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);
        appPool[domainHash].owner = 0; // use delete or write a deleter
    }

    // 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;
    }

    // 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) {
        // 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;
        //move from wallet
    }

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

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

    mapping(bytes32 => Application) public Proposals; // similar to appPool
    mapping(bytes32 => uint) public Parameters;

    function proposeUpdate(string _parameter, uint _value) {
        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, wallet, deposit);
        // initialize application with a snapshot with the current values of all parameters
        initializeSnapshotParam(parameterHash);
        Proposals[parameterHash].challengeTime= now + Proposals[parameterHash].snapshot[challengeLen];
        Proposals[parameterHash].owner = msg.sender;

    }

    function challengeProposal(string _parameter, uint _value) {
        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, wallet, 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) {
        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;
        Proposals[parameterHash].owner = 0; // use delete or write a deleter
    }

    // 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 = ??
        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;
            Proposals[parameterHash].owner = 0; // use delete or write a deleter
            // give tokens to applicant based on dist and total tokens
        }
        else {
            Proposals[parameterHash].owner = 0;
            // give tokens to challenger based on dist and total tokens
        }
        // ensures the result cannot be processed again
        voteProcessed[_pollID] = true;
    }

     function initializeSnapshotParam(byte32 _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 (?)
// ask about wallet location

contract Registry {

    address public wallet;
    StandardToken public token;

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

    struct Application {
        address owner;
        bool challenged;
        uint challengeTime; //should be challegeEndTime
        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;
    }

    mapping(bytes32 => Publisher) public whitelist;
    mapping(bytes32 => Application) public appPool;
    mapping(uint => bool) public voteProcessed;
    mapping(address => mapping(uint => bool)) public voterInfo;

    // Constructor
    function Registry(address _token, address _wallet) {
        token = StandardToken(_token);
        wallet = _wallet;
    }

    // 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, wallet, 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, wallet, 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);
    }

    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)) {
            // add to registry
            add(domain, appPool[domainHash].owner);
            appPool[domainHash].owner = 0;
            // give tokens to applicant based on dist and total tokens
        }
        else {
            appPool[domainHash].owner = 0;
            // give tokens to challenger based on dist and total tokens
        }
        // 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) {
        // checks if a voter has claimed tokens
        require(voterInfo[msg.sender][_pollID] == false);
        giveTokens(_pollID, msg.sender);
        // ensures a voter cannot claim tokens again
        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);
        appPool[domainHash].owner = 0; // use delete or write a deleter
    }

    // 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;
    }

    // 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) {
        // 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);
        getNumCorrectInvestment(_pollID, _salt)*appPool[domainHash].snapshot[minDeposit]*(1-dispensationPct)/getTotalNumberOfTokensForWinningOption(_pollID);
    }

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

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

    mapping(bytes32 => Proposals) public paramProposals;
    mapping(bytes32 => uint) public Parameters;

    struct Proposals {
        address owner;
        bool challenged;
        uint challengeEndTime; //expiry of challenge period
        address challenger;
        proposealParam snapshot;

    }

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

        // 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;
    }

    function proposeUpdate(string _parameter, uint _value) {
        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, wallet, deposit);
        // initialize application with a snapshot with the current values of all parameters
        initializeSnapshotParam(parameterHash);
        paramProposals[parameterHash ].challengeEndTime= now + paramProposals[parameterHash ].snapshot[challengeLen];
        paramProposals[parameterHash ].owner = msg.sender;

    }

    function challengeProposal(string _parameter, uint _value) {
        parameterHash = sha3(_parameter, _value);

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

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

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

     function initializeSnapshotParam(byte32 _hash) {
        Proposals[domainHash].snapshot[minDeposit] = get("minDeposit");
        Proposals[domainHash].snapshot[challengeLen] = get("challengeLen");
        Proposals[domainHash].snapshot[commitVoteLen] = get("commitVoteLen");
        Proposals[domainHash].snapshot[revealVoteLen] = get("revealVoteLen");
        Proposals[domainHash].snapshot[majority] = get("majority");
        Proposals[domainHash].snapshot[dispensationPct] = get("dispensationPct");
    }

}


Use value.call()() instead of send()

Use value.call()() instead of send()

contract DaoChallenge
{
	modifier noEther() {if (msg.value > 0) throw; _}

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

	event notifySellToken(uint256 n, address buyer);
	event notifyRefundToken(uint256 n, address tokenHolder);
	event notifyTranferToken(uint256 n, address sender, address recipient);
	event notifyTerminate(uint256 finalBalance);

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

	uint256 constant tokenPrice = 1000000000000000; // 1 finney

	// Owner of the challenge; a real DAO doesn't an owner.
	address owner;

	function DaoChallenge () {
		owner = msg.sender; // Owner of the challenge. Don't use this in a real DAO.
	}

	function () {
		address sender = msg.sender;
		uint256 amount = msg.value;

		// No fractional tokens:
		if (amount % tokenPrice != 0) {
			throw;
		}
		tokenBalanceOf[sender] += amount / tokenPrice;
		notifySellToken(amount, sender);
	}

	// This uses call.value()() rather than send(), but only sends to msg.sender
	function withdrawEtherOrThrow(uint256 amount) {
		bool result = msg.sender.call.value(amount)();
		if (!result) {
			throw;
		}
	}

	function refund() noEther {
		address sender = msg.sender;
		uint256 tokenBalance = tokenBalanceOf[sender];
		if (tokenBalance == 0) { throw; }
		tokenBalanceOf[sender] = 0;
		withdrawEtherOrThrow(tokenBalance * tokenPrice);
		notifyRefundToken(tokenBalance, sender);
	}

	function transfer(address recipient, uint256 tokens) noEther {
		address sender = msg.sender;

		if (tokenBalanceOf[sender] < tokens) throw;
		if (tokenBalanceOf[recipient] + tokens < tokenBalanceOf[recipient]) throw; // Check for overflows
		tokenBalanceOf[sender] -= tokens;
		tokenBalanceOf[recipient] += tokens;
		notifyTranferToken(tokens, sender, recipient);
	}

	// The owner of the challenge can terminate it. Don't use this in a real DAO.
	function terminate() noEther onlyOwner {
		notifyTerminate(this.balance);
		suicide(owner);
	}
}

contract DaoChallenge
{
	modifier noEther() {if (msg.value > 0) throw; _}

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

	event notifySellToken(uint256 n, address buyer);
	event notifyRefundToken(uint256 n, address tokenHolder);
	event notifyTranferToken(uint256 n, address sender, address recipient);
	event notifyTerminate(uint256 finalBalance);

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

	uint256 constant tokenPrice = 1000000000000000; // 1 finney

	// Owner of the challenge; a real DAO doesn't an owner.
	address owner;

	function sendOrThrow(address destination, uint256 amount) {
		bool result = destination.send(amount);
		if (!result) {
			throw;
		}
	}

	function DaoChallenge () {
		owner = msg.sender; // Owner of the challenge. Don't use this in a real DAO.
	}

	function () {
		address sender = msg.sender;
		uint256 amount = msg.value;

		// No fractional tokens:
		if (amount % tokenPrice != 0) {
			throw;
		}
		tokenBalanceOf[sender] += amount / tokenPrice;
		notifySellToken(amount, sender);
	}

	function refund() noEther {
		address sender = msg.sender;
		uint256 tokenBalance = tokenBalanceOf[sender];
		if (tokenBalance == 0) { throw; }
		tokenBalanceOf[sender] = 0;
		sendOrThrow(sender, tokenBalance * tokenPrice);
		notifyRefundToken(tokenBalance, sender);
	}

	function transfer(address recipient, uint256 tokens) noEther {
		address sender = msg.sender;

		if (tokenBalanceOf[sender] < tokens) throw;
		if (tokenBalanceOf[recipient] + tokens < tokenBalanceOf[recipient]) throw; // Check for overflows
		tokenBalanceOf[sender] -= tokens;
		tokenBalanceOf[recipient] += tokens;
		notifyTranferToken(tokens, sender, recipient);
	}

	// The owner of the challenge can terminate it. Don't use this in a real DAO.
	function terminate() noEther onlyOwner {
		notifyTerminate(this.balance);
		suicide(owner);
	}
}