thats numberwang

thats numberwang

pragma solidity ^0.4.11;
import "./base/Owned.sol";
import "./base/StandardToken.sol";
import "./interface/SalesAgentInterface.sol";
import "./lib/SafeMath.sol";

/// @title The main Rocket Pool Token (RPL) contract
/// @author David Rugendyke - http://www.rocketpool.net

/*****************************************************************
*   This is the main Rocket Pool Token (RPL) contract. It features
*   Smart Agent compatibility. The Sale Agent is a new type of
*   contract that can authorise the minting of tokens on behalf of
*   the traditional ERC20 token contract. This allows you to
*   distribute your ICO tokens through multiple Sale Agents,
*   at various times, of various token quantities and of varying
*   fund targets. Once you’ve written a new Sale Agent contract,
*   you can register him with the main ERC20 token contract,
*   he’s then permitted to sell it’s tokens on your behalf using
*   guidelines such as the amount of tokens he’s allowed to sell,
*   the maximum ether he’s allowed to raise, the start block and
*   end blocks he’s allowed to sell between and more.
/****************************************************************/

contract RocketPoolToken is StandardToken, Owned {

     /**** Properties ***********/

    string public name = "Rocket Pool";
    string public symbol = "RPL";
    string public version = "1.0";
    // Set our token units
    uint8 public constant decimals = 18;
    uint256 public exponent = 10**uint256(decimals);
    uint256 public totalSupply = 0;                             // The total of tokens currently minted by sales agent contracts
    uint256 public totalSupplyCap = 36 * (10**6) * exponent;    // 36 Million tokens

    /**** Libs *****************/

    using SafeMath for uint;

    /*** Sale Addresses *********/

    mapping (address => SalesAgent) private salesAgents;   // Our contract addresses of our sales contracts
    address[] private salesAgentsAddresses;                // Keep an array of all our sales agent addresses for iteration

    /*** Structs ***************/

    struct SalesAgent {                     // These are contract addresses that are authorised to mint tokens
        address saleContractAddress;        // Address of the contract
        bytes32 saleContractType;           // Type of the contract ie. presale, crowdsale
        uint256 targetEthMax;               // The max amount of ether the agent is allowed raise
        uint256 targetEthMin;               // The min amount of ether to raise to consider this contracts sales a success
        uint256 tokensLimit;                // The maximum amount of tokens this sale contract is allowed to distribute
        uint256 tokensMinted;               // The current amount of tokens minted by this agent
        uint256 minDeposit;                 // The minimum deposit amount allowed
        uint256 maxDeposit;                 // The maximum deposit amount allowed
        uint256 startBlock;                 // The start block when allowed to mint tokens
        uint256 endBlock;                   // The end block when to finish minting tokens
        address depositAddress;             // The address that receives the ether for that sale contract
        bool depositAddressCheckedIn;       // The address that receives the ether for that sale contract must check in with its sale contract to verify its a valid address that can interact
        bool finalised;                     // Has this sales contract been completed and the ether sent to the deposit address?
        bool exists;                        // Check to see if the mapping exists
    }

    /*** Events ****************/

    event MintToken(address _agent, address _address, uint256 _value);
    event SaleFinalised(address _agent, address _address, uint256 _value);

    /*** Tests *****************/

    event FlagUint(uint256 flag);
    event FlagAddress(address flag);

    /*** Modifiers *************/

    /// @dev Only allow access from the latest version of a sales contract
    modifier isSalesContract(address _sender) {
        // Is this an authorised sale contract?
        assert(salesAgents[_sender].exists == true);
        _;
    }

    /**** Methods ***********/

    /// @dev RPL Token Init
    function RocketPoolToken() {}

    // @dev General validation for a sales agent contract receiving a contribution, additional validation can be done in the sale contract if required
    // @param _value The value of the contribution in wei
    // @return A boolean that indicates if the operation was successful.
    function validateContribution(uint256 _value) isSalesContract(msg.sender) returns (bool) {
        // Get an instance of the sale agent contract
        SalesAgentInterface saleAgent = SalesAgentInterface(msg.sender);
        // Did they send anything from a proper address?
        assert(_value > 0);
        // Check the depositAddress has been verified by the account holder
        assert(salesAgents[msg.sender].depositAddressCheckedIn == true);
        // Check if we're ok to receive contributions, have we started?
        assert(block.number > salesAgents[msg.sender].startBlock);
        // Already ended? Or if the end block is 0, it's an open ended sale until finalised by the depositAddress
        assert(block.number < salesAgents[msg.sender].endBlock || salesAgents[msg.sender].endBlock == 0);
        // Is it above the min deposit amount?
        assert(_value >= salesAgents[msg.sender].minDeposit);
        // Is it below the max deposit allowed?
        assert(_value <= salesAgents[msg.sender].maxDeposit);
        // No contributions if the sale contract has finalised
        assert(salesAgents[msg.sender].finalised == false);
        // Does this deposit put it over the max target ether for the sale contract?
        assert(saleAgent.contributedTotal().add(_value) <= salesAgents[msg.sender].targetEthMax);
        // All good
        return true;
    }

    // @dev General validation for a sales agent contract that requires the user claim the tokens after the sale has finished
    // @param _sender The address sent the request
    // @return A boolean that indicates if the operation was successful.
    function validateClaimTokens(address _sender) isSalesContract(msg.sender) returns (bool) {
        // Get an instance of the sale agent contract
        SalesAgentInterface saleAgent = SalesAgentInterface(msg.sender);
        // Must have previously contributed
        assert(saleAgent.getContributionOf(_sender) > 0);
        // Sale contract completed
        assert(block.number > salesAgents[msg.sender].endBlock);
        // All good
        return true;
    }

    // @dev Mint the Rocket Pool Tokens (RPL)
    // @param _to The address that will receive the minted tokens.
    // @param _amount The amount of tokens to mint.
    // @return A boolean that indicates if the operation was successful.
    function mint(address _to, uint _amount) isSalesContract(msg.sender) returns (bool) {
        // Check if we're ok to mint new tokens, have we started?
        // We dont check for the end block as some sale agents mint tokens during the sale, and some after its finished (proportional sales)
        assert(block.number > salesAgents[msg.sender].startBlock);
        // Check the depositAddress has been verified by the designated account holder that will receive the funds from that agent
        assert(salesAgents[msg.sender].depositAddressCheckedIn == true);
        // No minting if the sale contract has finalised
        assert(salesAgents[msg.sender].finalised == false);
        // Check we don't exceed the assigned tokens of the sale agent
        assert(salesAgents[msg.sender].tokensLimit >= salesAgents[msg.sender].tokensMinted.add(_amount));
        // Verify ok balances and values
        assert(_amount > 0);
         // Check we don't exceed the supply limit
        assert(totalSupply.add(_amount) <= totalSupplyCap);
         // Ok all good, automatically checks for overflow with safeMath
        balances[_to] = balances[_to].add(_amount);
        // Add to the total minted for that agent, automatically checks for overflow with safeMath
        salesAgents[msg.sender].tokensMinted = salesAgents[msg.sender].tokensMinted.add(_amount);
        // Add to the overall total minted, automatically checks for overflow with safeMath
        totalSupply = totalSupply.add(_amount);
        // Fire the event
        MintToken(msg.sender, _to, _amount);
        // Fire the transfer event
        Transfer(0x0, _to, _amount);
        // Completed
        return true;
    }

    /// @dev Returns the amount of tokens that can still be minted
    function getRemainingTokens() public constant returns(uint256) {
        return totalSupplyCap.sub(totalSupply);
    }

    /// @dev Set the address of a new crowdsale/presale contract agent if needed, usefull for upgrading
    /// @param _saleAddress The address of the new token sale contract
    /// @param _saleContractType Type of the contract ie. presale, crowdsale, quarterly
    /// @param _targetEthMin The min amount of ether to raise to consider this contracts sales a success
    /// @param _targetEthMax The max amount of ether the agent is allowed raise
    /// @param _tokensLimit The maximum amount of tokens this sale contract is allowed to distribute
    /// @param _minDeposit The minimum deposit amount allowed
    /// @param _maxDeposit The maximum deposit amount allowed
    /// @param _startBlock The start block when allowed to mint tokens
    /// @param _endBlock The end block when to finish minting tokens
    /// @param _depositAddress The address that receives the ether for that sale contract
    function setSaleAgentContract(
        address _saleAddress,
         string _saleContractType,
        uint256 _targetEthMin,
        uint256 _targetEthMax,
        uint256 _tokensLimit,
        uint256 _minDeposit,
        uint256 _maxDeposit,
        uint256 _startBlock,
        uint256 _endBlock,
        address _depositAddress
    )
    // Only the owner can register a new sale agent
    public onlyOwner
    {
        // Valid addresses?
        assert(_saleAddress != 0x0 && _depositAddress != 0x0);
        // Must have some available tokens
        assert(_tokensLimit > 0 && _tokensLimit <= totalSupplyCap);
        // Make sure the min deposit is less than or equal to the max
        assert(_minDeposit <= _maxDeposit);
        // Add the new sales contract
        salesAgents[_saleAddress] = SalesAgent({
            saleContractAddress: _saleAddress,
            saleContractType: sha3(_saleContractType),
            targetEthMin: _targetEthMin,
            targetEthMax: _targetEthMax,
            tokensLimit: _tokensLimit,
            tokensMinted: 0,
            minDeposit: _minDeposit,
            maxDeposit: _maxDeposit,
            startBlock: _startBlock,
            endBlock: _endBlock,
            depositAddress: _depositAddress,
            depositAddressCheckedIn: false,
            finalised: false,
            exists: true
        });
        // Store our agent address so we can iterate over it if needed
        salesAgentsAddresses.push(_saleAddress);
    }

    /// @dev Sets the contract sale agent process as completed, that sales agent is now retired
    function setSaleContractFinalised(address _sender) isSalesContract(msg.sender) public returns(bool) {
        // Get an instance of the sale agent contract
        SalesAgentInterface saleAgent = SalesAgentInterface(msg.sender);
        // Finalise the crowdsale funds
        assert(!salesAgents[msg.sender].finalised);
        // The address that will receive this contracts deposit, should match the original senders
        assert(salesAgents[msg.sender].depositAddress == _sender);
        // If the end block is 0, it means an open ended crowdsale, once it's finalised, the end block is set to the current one
        if (salesAgents[msg.sender].endBlock == 0) {
            salesAgents[msg.sender].endBlock = block.number;
        }
        // Not yet finished?
        assert(block.number >= salesAgents[msg.sender].endBlock);
        // Not enough raised?
        assert(saleAgent.contributedTotal() >= salesAgents[msg.sender].targetEthMin);
        // We're done now
        salesAgents[msg.sender].finalised = true;
        // Fire the event
        SaleFinalised(msg.sender, _sender, salesAgents[msg.sender].tokensMinted);
        // All good
        return true;
    }

    /// @dev Verifies if the current address matches the depositAddress
    /// @param _verifyAddress The address to verify it matches the depositAddress given for the sales agent
    function setSaleContractDepositAddressVerified(address _verifyAddress) isSalesContract(msg.sender) public {
        // Check its verified
        assert(salesAgents[msg.sender].depositAddress == _verifyAddress && _verifyAddress != 0x0);
        // Ok set it now
        salesAgents[msg.sender].depositAddressCheckedIn = true;
    }

    /// @dev Returns true if this sales contract has finalised
    /// @param _salesAgentAddress The address of the token sale agent contract
    function getSaleContractIsFinalised(address _salesAgentAddress) constant isSalesContract(_salesAgentAddress) public returns(bool) {
        return salesAgents[_salesAgentAddress].finalised;
    }

    /// @dev Returns the min target amount of ether the contract wants to raise
    /// @param _salesAgentAddress The address of the token sale agent contract
    function getSaleContractTargetEtherMin(address _salesAgentAddress) constant isSalesContract(_salesAgentAddress) public returns(uint256) {
        return salesAgents[_salesAgentAddress].targetEthMin;
    }

    /// @dev Returns the max target amount of ether the contract can raise
    /// @param _salesAgentAddress The address of the token sale agent contract
    function getSaleContractTargetEtherMax(address _salesAgentAddress) constant isSalesContract(_salesAgentAddress) public returns(uint256) {
        return salesAgents[_salesAgentAddress].targetEthMax;
    }

    /// @dev Returns the min deposit amount of ether
    /// @param _salesAgentAddress The address of the token sale agent contract
    function getSaleContractDepositEtherMin(address _salesAgentAddress) constant isSalesContract(_salesAgentAddress) public returns(uint256) {
        return salesAgents[_salesAgentAddress].minDeposit;
    }

    /// @dev Returns the max deposit amount of ether
    /// @param _salesAgentAddress The address of the token sale agent contract
    function getSaleContractDepositEtherMax(address _salesAgentAddress) constant isSalesContract(_salesAgentAddress) public returns(uint256) {
        return salesAgents[_salesAgentAddress].maxDeposit;
    }

    /// @dev Returns the address where the sale contracts ether will be deposited
    /// @param _salesAgentAddress The address of the token sale agent contract
    function getSaleContractDepositAddress(address _salesAgentAddress) constant isSalesContract(_salesAgentAddress) public returns(address) {
        return salesAgents[_salesAgentAddress].depositAddress;
    }

    /// @dev Returns the true if the sale agents deposit address has been verified
    /// @param _salesAgentAddress The address of the token sale agent contract
    function getSaleContractDepositAddressVerified(address _salesAgentAddress) constant isSalesContract(_salesAgentAddress) public returns(bool) {
        return salesAgents[_salesAgentAddress].depositAddressCheckedIn;
    }

    /// @dev Returns the start block for the sale agent
    /// @param _salesAgentAddress The address of the token sale agent contract
    function getSaleContractStartBlock(address _salesAgentAddress) constant isSalesContract(_salesAgentAddress) public returns(uint256) {
        return salesAgents[_salesAgentAddress].startBlock;
    }

    /// @dev Returns the start block for the sale agent
    /// @param _salesAgentAddress The address of the token sale agent contract
    function getSaleContractEndBlock(address _salesAgentAddress) constant isSalesContract(_salesAgentAddress) public returns(uint256) {
        return salesAgents[_salesAgentAddress].endBlock;
    }

    /// @dev Returns the max tokens for the sale agent
    /// @param _salesAgentAddress The address of the token sale agent contract
    function getSaleContractTokensLimit(address _salesAgentAddress) constant isSalesContract(_salesAgentAddress) public returns(uint256) {
        return salesAgents[_salesAgentAddress].tokensLimit;
    }

    /// @dev Returns the token total currently minted by the sale agent
    /// @param _salesAgentAddress The address of the token sale agent contract
    function getSaleContractTokensMinted(address _salesAgentAddress) constant isSalesContract(_salesAgentAddress) public returns(uint256) {
        return salesAgents[_salesAgentAddress].tokensMinted;
    }

}

pragma solidity ^0.4.11;
import "./base/Owned.sol";
import "./base/StandardToken.sol";
import "./interface/SalesAgentInterface.sol";
import "./lib/SafeMath.sol";

/// @title The main Rocket Pool Token (RPL) contract
/// @author David Rugendyke - http://www.rocketpool.net

/*****************************************************************
*   This is the main Rocket Pool Token (RPL) contract. It features
*   Smart Agent compatibility. The Sale Agent is a new type of
*   contract that can authorise the minting of tokens on behalf of
*   the traditional ERC20 token contract. This allows you to
*   distribute your ICO tokens through multiple Sale Agents,
*   at various times, of various token quantities and of varying
*   fund targets. Once you’ve written a new Sale Agent contract,
*   you can register him with the main ERC20 token contract,
*   he’s then permitted to sell it’s tokens on your behalf using
*   guidelines such as the amount of tokens he’s allowed to sell,
*   the maximum ether he’s allowed to raise, the start block and
*   end blocks he’s allowed to sell between and more.
/****************************************************************/

contract RocketPoolToken is StandardToken, Owned {

     /**** Properties ***********/

    string public name = "Rocket Pool";
    string public symbol = "RPL";
    string public version = "1.0";
    // Set our token units
    uint8 public constant DECIMALS = 18;
    uint256 public exponent = 10**uint256(DECIMALS);
    uint256 public totalSupply = 0;                             // The total of tokens currently minted by sales agent contracts
    uint256 public totalSupplyCap = 36 * (10**6) * exponent;    // 36 Million tokens

    /**** Libs *****************/

    using SafeMath for uint;

    /*** Sale Addresses *********/

    mapping (address => SalesAgent) private salesAgents;   // Our contract addresses of our sales contracts
    address[] private salesAgentsAddresses;                // Keep an array of all our sales agent addresses for iteration

    /*** Structs ***************/

    struct SalesAgent {                     // These are contract addresses that are authorised to mint tokens
        address saleContractAddress;        // Address of the contract
        bytes32 saleContractType;           // Type of the contract ie. presale, crowdsale
        uint256 targetEthMax;               // The max amount of ether the agent is allowed raise
        uint256 targetEthMin;               // The min amount of ether to raise to consider this contracts sales a success
        uint256 tokensLimit;                // The maximum amount of tokens this sale contract is allowed to distribute
        uint256 tokensMinted;               // The current amount of tokens minted by this agent
        uint256 minDeposit;                 // The minimum deposit amount allowed
        uint256 maxDeposit;                 // The maximum deposit amount allowed
        uint256 startBlock;                 // The start block when allowed to mint tokens
        uint256 endBlock;                   // The end block when to finish minting tokens
        address depositAddress;             // The address that receives the ether for that sale contract
        bool depositAddressCheckedIn;       // The address that receives the ether for that sale contract must check in with its sale contract to verify its a valid address that can interact
        bool finalised;                     // Has this sales contract been completed and the ether sent to the deposit address?
        bool exists;                        // Check to see if the mapping exists
    }

    /*** Events ****************/

    event MintToken(address _agent, address _address, uint256 _value);
    event SaleFinalised(address _agent, address _address, uint256 _value);

    /*** Tests *****************/

    event FlagUint(uint256 flag);
    event FlagAddress(address flag);

    /*** Modifiers *************/

    /// @dev Only allow access from the latest version of a sales contract
    modifier isSalesContract(address _sender) {
        // Is this an authorised sale contract?
        assert(salesAgents[_sender].exists == true);
        _;
    }

    /**** Methods ***********/

    /// @dev RPL Token Init
    function RocketPoolToken() {}

    // @dev General validation for a sales agent contract receiving a contribution, additional validation can be done in the sale contract if required
    // @param _value The value of the contribution in wei
    // @return A boolean that indicates if the operation was successful.
    function validateContribution(uint256 _value) isSalesContract(msg.sender) returns (bool) {
        // Get an instance of the sale agent contract
        SalesAgentInterface saleAgent = SalesAgentInterface(msg.sender);
        // Did they send anything from a proper address?
        assert(_value > 0);
        // Check the depositAddress has been verified by the account holder
        assert(salesAgents[msg.sender].depositAddressCheckedIn == true);
        // Check if we're ok to receive contributions, have we started?
        assert(block.number > salesAgents[msg.sender].startBlock);
        // Already ended? Or if the end block is 0, it's an open ended sale until finalised by the depositAddress
        assert(block.number < salesAgents[msg.sender].endBlock || salesAgents[msg.sender].endBlock == 0);
        // Is it above the min deposit amount?
        assert(_value >= salesAgents[msg.sender].minDeposit);
        // Is it below the max deposit allowed?
        assert(_value <= salesAgents[msg.sender].maxDeposit);
        // No contributions if the sale contract has finalised
        assert(salesAgents[msg.sender].finalised == false);
        // Does this deposit put it over the max target ether for the sale contract?
        assert(saleAgent.contributedTotal().add(_value) <= salesAgents[msg.sender].targetEthMax);
        // All good
        return true;
    }

    // @dev General validation for a sales agent contract that requires the user claim the tokens after the sale has finished
    // @param _sender The address sent the request
    // @return A boolean that indicates if the operation was successful.
    function validateClaimTokens(address _sender) isSalesContract(msg.sender) returns (bool) {
        // Get an instance of the sale agent contract
        SalesAgentInterface saleAgent = SalesAgentInterface(msg.sender);
        // Must have previously contributed
        assert(saleAgent.getContributionOf(_sender) > 0);
        // Sale contract completed
        assert(block.number > salesAgents[msg.sender].endBlock);
        // All good
        return true;
    }

    // @dev Mint the Rocket Pool Tokens (RPL)
    // @param _to The address that will receive the minted tokens.
    // @param _amount The amount of tokens to mint.
    // @return A boolean that indicates if the operation was successful.
    function mint(address _to, uint _amount) isSalesContract(msg.sender) returns (bool) {
        // Check if we're ok to mint new tokens, have we started?
        // We dont check for the end block as some sale agents mint tokens during the sale, and some after its finished (proportional sales)
        assert(block.number > salesAgents[msg.sender].startBlock);
        // Check the depositAddress has been verified by the designated account holder that will receive the funds from that agent
        assert(salesAgents[msg.sender].depositAddressCheckedIn == true);
        // No minting if the sale contract has finalised
        assert(salesAgents[msg.sender].finalised == false);
        // Check we don't exceed the assigned tokens of the sale agent
        assert(salesAgents[msg.sender].tokensLimit >= salesAgents[msg.sender].tokensMinted.add(_amount));
        // Verify ok balances and values
        assert(_amount > 0);
         // Check we don't exceed the supply limit
        assert(totalSupply.add(_amount) <= totalSupplyCap);
         // Ok all good, automatically checks for overflow with safeMath
        balances[_to] = balances[_to].add(_amount);
        // Add to the total minted for that agent, automatically checks for overflow with safeMath
        salesAgents[msg.sender].tokensMinted = salesAgents[msg.sender].tokensMinted.add(_amount);
        // Add to the overall total minted, automatically checks for overflow with safeMath
        totalSupply = totalSupply.add(_amount);
        // Fire the event
        MintToken(msg.sender, _to, _amount);
        // Fire the transfer event
        Transfer(0x0, _to, _amount);
        // Completed
        return true;
    }

    /// @dev Returns the amount of tokens that can still be minted
    function getRemainingTokens() public constant returns(uint256) {
        return totalSupplyCap.sub(totalSupply);
    }

    /// @dev Set the address of a new crowdsale/presale contract agent if needed, usefull for upgrading
    /// @param _saleAddress The address of the new token sale contract
    /// @param _saleContractType Type of the contract ie. presale, crowdsale, quarterly
    /// @param _targetEthMin The min amount of ether to raise to consider this contracts sales a success
    /// @param _targetEthMax The max amount of ether the agent is allowed raise
    /// @param _tokensLimit The maximum amount of tokens this sale contract is allowed to distribute
    /// @param _minDeposit The minimum deposit amount allowed
    /// @param _maxDeposit The maximum deposit amount allowed
    /// @param _startBlock The start block when allowed to mint tokens
    /// @param _endBlock The end block when to finish minting tokens
    /// @param _depositAddress The address that receives the ether for that sale contract
    function setSaleAgentContract(
        address _saleAddress,
         string _saleContractType,
        uint256 _targetEthMin,
        uint256 _targetEthMax,
        uint256 _tokensLimit,
        uint256 _minDeposit,
        uint256 _maxDeposit,
        uint256 _startBlock,
        uint256 _endBlock,
        address _depositAddress
    )
    // Only the owner can register a new sale agent
    public onlyOwner
    {
        // Valid addresses?
        assert(_saleAddress != 0x0 && _depositAddress != 0x0);
        // Must have some available tokens
        assert(_tokensLimit > 0 && _tokensLimit <= totalSupplyCap);
        // Make sure the min deposit is less than or equal to the max
        assert(_minDeposit <= _maxDeposit);
        // Add the new sales contract
        salesAgents[_saleAddress] = SalesAgent({
            saleContractAddress: _saleAddress,
            saleContractType: sha3(_saleContractType),
            targetEthMin: _targetEthMin,
            targetEthMax: _targetEthMax,
            tokensLimit: _tokensLimit,
            tokensMinted: 0,
            minDeposit: _minDeposit,
            maxDeposit: _maxDeposit,
            startBlock: _startBlock,
            endBlock: _endBlock,
            depositAddress: _depositAddress,
            depositAddressCheckedIn: false,
            finalised: false,
            exists: true
        });
        // Store our agent address so we can iterate over it if needed
        salesAgentsAddresses.push(_saleAddress);
    }

    /// @dev Sets the contract sale agent process as completed, that sales agent is now retired
    function setSaleContractFinalised(address _sender) isSalesContract(msg.sender) public returns(bool) {
        // Get an instance of the sale agent contract
        SalesAgentInterface saleAgent = SalesAgentInterface(msg.sender);
        // Finalise the crowdsale funds
        assert(!salesAgents[msg.sender].finalised);
        // The address that will receive this contracts deposit, should match the original senders
        assert(salesAgents[msg.sender].depositAddress == _sender);
        // If the end block is 0, it means an open ended crowdsale, once it's finalised, the end block is set to the current one
        if (salesAgents[msg.sender].endBlock == 0) {
            salesAgents[msg.sender].endBlock = block.number;
        }
        // Not yet finished?
        assert(block.number >= salesAgents[msg.sender].endBlock);
        // Not enough raised?
        assert(saleAgent.contributedTotal() >= salesAgents[msg.sender].targetEthMin);
        // We're done now
        salesAgents[msg.sender].finalised = true;
        // Fire the event
        SaleFinalised(msg.sender, _sender, salesAgents[msg.sender].tokensMinted);
        // All good
        return true;
    }

    /// @dev Verifies if the current address matches the depositAddress
    /// @param _verifyAddress The address to verify it matches the depositAddress given for the sales agent
    function setSaleContractDepositAddressVerified(address _verifyAddress) isSalesContract(msg.sender) public {
        // Check its verified
        assert(salesAgents[msg.sender].depositAddress == _verifyAddress && _verifyAddress != 0x0);
        // Ok set it now
        salesAgents[msg.sender].depositAddressCheckedIn = true;
    }

    /// @dev Returns true if this sales contract has finalised
    /// @param _salesAgentAddress The address of the token sale agent contract
    function getSaleContractIsFinalised(address _salesAgentAddress) constant isSalesContract(_salesAgentAddress) public returns(bool) {
        return salesAgents[_salesAgentAddress].finalised;
    }

    /// @dev Returns the min target amount of ether the contract wants to raise
    /// @param _salesAgentAddress The address of the token sale agent contract
    function getSaleContractTargetEtherMin(address _salesAgentAddress) constant isSalesContract(_salesAgentAddress) public returns(uint256) {
        return salesAgents[_salesAgentAddress].targetEthMin;
    }

    /// @dev Returns the max target amount of ether the contract can raise
    /// @param _salesAgentAddress The address of the token sale agent contract
    function getSaleContractTargetEtherMax(address _salesAgentAddress) constant isSalesContract(_salesAgentAddress) public returns(uint256) {
        return salesAgents[_salesAgentAddress].targetEthMax;
    }

    /// @dev Returns the min deposit amount of ether
    /// @param _salesAgentAddress The address of the token sale agent contract
    function getSaleContractDepositEtherMin(address _salesAgentAddress) constant isSalesContract(_salesAgentAddress) public returns(uint256) {
        return salesAgents[_salesAgentAddress].minDeposit;
    }

    /// @dev Returns the max deposit amount of ether
    /// @param _salesAgentAddress The address of the token sale agent contract
    function getSaleContractDepositEtherMax(address _salesAgentAddress) constant isSalesContract(_salesAgentAddress) public returns(uint256) {
        return salesAgents[_salesAgentAddress].maxDeposit;
    }

    /// @dev Returns the address where the sale contracts ether will be deposited
    /// @param _salesAgentAddress The address of the token sale agent contract
    function getSaleContractDepositAddress(address _salesAgentAddress) constant isSalesContract(_salesAgentAddress) public returns(address) {
        return salesAgents[_salesAgentAddress].depositAddress;
    }

    /// @dev Returns the true if the sale agents deposit address has been verified
    /// @param _salesAgentAddress The address of the token sale agent contract
    function getSaleContractDepositAddressVerified(address _salesAgentAddress) constant isSalesContract(_salesAgentAddress) public returns(bool) {
        return salesAgents[_salesAgentAddress].depositAddressCheckedIn;
    }

    /// @dev Returns the start block for the sale agent
    /// @param _salesAgentAddress The address of the token sale agent contract
    function getSaleContractStartBlock(address _salesAgentAddress) constant isSalesContract(_salesAgentAddress) public returns(uint256) {
        return salesAgents[_salesAgentAddress].startBlock;
    }

    /// @dev Returns the start block for the sale agent
    /// @param _salesAgentAddress The address of the token sale agent contract
    function getSaleContractEndBlock(address _salesAgentAddress) constant isSalesContract(_salesAgentAddress) public returns(uint256) {
        return salesAgents[_salesAgentAddress].endBlock;
    }

    /// @dev Returns the max tokens for the sale agent
    /// @param _salesAgentAddress The address of the token sale agent contract
    function getSaleContractTokensLimit(address _salesAgentAddress) constant isSalesContract(_salesAgentAddress) public returns(uint256) {
        return salesAgents[_salesAgentAddress].tokensLimit;
    }

    /// @dev Returns the token total currently minted by the sale agent
    /// @param _salesAgentAddress The address of the token sale agent contract
    function getSaleContractTokensMinted(address _salesAgentAddress) constant isSalesContract(_salesAgentAddress) public returns(uint256) {
        return salesAgents[_salesAgentAddress].tokensMinted;
    }

}


Fix AssertAddressArray.sol

Fix AssertAddressArray.sol

//SPDX-License-Identifier: MIT
pragma solidity >= 0.4.15 < 0.9.0;

library AssertAddressArray {

    uint8 constant ZERO = uint8(bytes1('0'));
    uint8 constant A = uint8(bytes1('a'));

    /*
        Event: TestEvent

        Fired when an assertion is made.

        Params:
            result (bool) - Whether or not the assertion holds.
            message (string) - A message to display if the assertion does not hold.
    */
    event TestEvent(bool indexed result, string message);

    // ************************************** address[] **************************************

    /*
        Function: equal(address[])

        Assert that two 'address[]' are equal.

        : arrA.length == arrB.length

        and, for all valid indices 'i'

        : arrA[i] == arrB[i]

        Params:
            A (address[]) - The first array.
            B (address[]) - The second array.
            message (string) - A message that is sent if the assertion fails.

        Returns:
            result (bool) - The result.
    */
    function equal(address[] memory arrA, address[] memory arrB, string memory message) public returns (bool result) {
        result = arrA.length == arrB.length;
        if (result) {
            for (uint i = 0; i < arrA.length; i++) {
                if (arrA[i] != arrB[i]) {
                    result = false;
                    break;
                }
            }
        }
        _report(result, message);
    }

    /*
        Function: notEqual(address[])

        Assert that two 'address[]' are not equal.

        : arrA.length != arrB.length

        or, for some valid index 'i'

        : arrA[i] != arrB[i]

        Params:
            A (address[]) - The first string.
            B (address[]) - The second string.
            message (string) - A message that is sent if the assertion fails.

        Returns:
            result (bool) - The result.
    */
    function notEqual(address[] memory arrA, address[] memory arrB, string memory message) public returns (bool result) {
        result = arrA.length == arrB.length;
        if (result) {
            for (uint i = 0; i < arrA.length; i++) {
                if (arrA[i] != arrB[i]) {
                    result = false;
                    break;
                }
            }
        }
        result = !result;
        _report(result, message);
    }

    /*
        Function: lengthEqual(address[])

        Assert that the length of an 'address[]' is equal to a given value.

        : arr.length == length

        Params:
            arr (address[]) - The array.
            length (uint) - The length.
            message (string) - A message that is sent if the assertion fails.

        Returns:
            result (bool) - The result.
    */
    function lengthEqual(address[] memory arr, uint length, string memory message) public returns (bool result) {
        uint arrLength = arr.length;
        if (arrLength == length)
            _report(result, "");
        else
            _report(result, _appendTagged(_tag(arrLength, "Tested"), _tag(length, "Against"), message));
    }

    /*
        Function: lengthNotEqual(address[])

        Assert that the length of an 'address[]' is not equal to a given value.

        : arr.length != length

        Params:
            arr (address[]) - The array.
            length (uint) - The length.
            message (string) - A message that is sent if the assertion fails.

        Returns:
            result (bool) - The result.
    */
    function lengthNotEqual(address[] memory arr, uint length, string memory message) public returns (bool result) {
        uint arrLength = arr.length;
        if (arrLength != arr.length)
            _report(result, "");
        else
            _report(result, _appendTagged(_tag(arrLength, "Tested"), _tag(length, "Against"), message));
    }

    /******************************** internal ********************************/

        /*
            Function: _report

            Internal function for triggering <TestEvent>.

            Params:
                result (bool) - The test result (true or false).
                message (string) - The message that is sent if the assertion fails.
        */
    function _report(bool result, string memory message) internal {
        if(result)
            emit TestEvent(true, "");
        else
            emit TestEvent(false, message);
    }

    /*
        Function: _utoa(uint)

        Convert an  unsigned integer to a string.

        Params:
            n (uint) - The unsigned integer.
            radix (uint8) - A number between 2 and 16 (inclusive). Characters used are 0-9,a-f

        Returns:
            result (string) - The resulting string.
    */
    function _utoa(uint n, uint8 radix) internal pure returns (string memory) {
        if (n == 0 || radix < 2 || radix > 16)
            return '0';
        bytes memory bts = new bytes(256);
        uint i;
        while (n > 0) {
            bts[i++] = _utoa(uint8(n % radix)); // Turn it to ascii.
            n /= radix;
        }
        // Reverse
        bytes memory rev = new bytes(i);
        for (uint j = 0; j < i; j++)
            rev[j] = bts[i - j - 1];
        return string(rev);
    }

    /*
        Function: _utoa(uint8)

        Convert an unsigned 8-bit integer to its ASCII byte representation. Numbers 0-9 are converted to '0'-'9',
        numbers 10-16 to 'a'-'f'. Numbers larger then 16 return the null byte.

        Params:
            u (uint8) - The unsigned 8-bit integer.

        Returns:
            result (string) - The ASCII byte.
    */
    function _utoa(uint8 u) internal pure returns (bytes1) {
        if (u < 10)
            return bytes1(u + ZERO);
        else if (u < 16)
            return bytes1(u - 10 + A);
        else
            return 0;
    }

    /*
    function htoa(address addr) constant returns (string) {
        bytes memory bts = new bytes(40);
        bytes20 addrBts = bytes20(addr);
        for (uint i = 0; i < 20; i++) {
            bts[2*i] = addrBts[i] % 16;
            bts[2*i + 1] = (addrBts[i] / 16) % 16;
        }
        return string(bts);
    }
    */

    /*
        Function: _tag(string)

        Add a tag to a string. The 'value' and 'tag' strings are returned on the form "tag: value".

        Params:
            value (string) - The value.
            tag (string) - The tag.

        Returns:
            result (string) - "tag: value"
    */
    function _tag(string memory value, string memory tag) internal pure returns (string memory) {

        bytes memory valueB = bytes(value);
        bytes memory tagB = bytes(tag);

        uint vl = valueB.length;
        uint tl = tagB.length;

        bytes memory newB = new bytes(vl + tl + 2);

        uint i;
        uint j;

        for (i = 0; i < tl; i++)
            newB[j++] = tagB[i];
        newB[j++] = ':';
        newB[j++] = ' ';
        for (i = 0; i < vl; i++)
            newB[j++] = valueB[i];

        return string(newB);
    }

    /*
        Function: _tag(uint)

        Add a tag to an uint.

        Params:
            value (uint) - The value.
            tag (string) - The tag.

        Returns:
            result (string) - "tag: _utoa(value)"
    */
    function _tag(uint value, string memory tag) internal pure returns (string memory) {
        string memory nstr = _utoa(value, 10);
        return _tag(nstr, tag);
    }

    /*
        Function: _appendTagged(string, string)

        Append two tagged values to a string.

        Params:
            tagged0 (string) - The first tagged value.
            tagged1 (string) - The second tagged value.
            str (string) - The string.

        Returns:
            result (string) - "str (tagged0, tagged1)"
    */
    function _appendTagged(string memory tagged0, string memory tagged1, string memory str) internal pure returns (string memory) {

        bytes memory tagged0B = bytes(tagged0);
        bytes memory tagged1B = bytes(tagged1);
        bytes memory strB = bytes(str);

        uint sl = strB.length;
        uint t0l = tagged0B.length;
        uint t1l = tagged1B.length;

        bytes memory newB = new bytes(sl + t0l + t1l + 5);

        uint i;
        uint j;

        for (i = 0; i < sl; i++)
            newB[j++] = strB[i];
        newB[j++] = ' ';
        newB[j++] = '(';
        for (i = 0; i < t0l; i++)
            newB[j++] = tagged0B[i];
        newB[j++] = ',';
        newB[j++] = ' ';
        for (i = 0; i < t1l; i++)
            newB[j++] = tagged1B[i];
        newB[j++] = ')';

        return string(newB);
    }
}

//SPDX-License-Identifier: MIT
pragma solidity >= 0.4.15 < 0.9.0;

library AssertAddressArray {

    uint8 constant ZERO = uint8(byte('0'));
    uint8 constant A = uint8(byte('a'));

    /*
        Event: TestEvent

        Fired when an assertion is made.

        Params:
            result (bool) - Whether or not the assertion holds.
            message (string) - A message to display if the assertion does not hold.
    */
    event TestEvent(bool indexed result, string message);

    // ************************************** address[] **************************************

    /*
        Function: equal(address[])

        Assert that two 'address[]' are equal.

        : arrA.length == arrB.length

        and, for all valid indices 'i'

        : arrA[i] == arrB[i]

        Params:
            A (address[]) - The first array.
            B (address[]) - The second array.
            message (string) - A message that is sent if the assertion fails.

        Returns:
            result (bool) - The result.
    */
    function equal(address[] memory arrA, address[] memory arrB, string memory message) public returns (bool result) {
        result = arrA.length == arrB.length;
        if (result) {
            for (uint i = 0; i < arrA.length; i++) {
                if (arrA[i] != arrB[i]) {
                    result = false;
                    break;
                }
            }
        }
        _report(result, message);
    }

    /*
        Function: notEqual(address[])

        Assert that two 'address[]' are not equal.

        : arrA.length != arrB.length

        or, for some valid index 'i'

        : arrA[i] != arrB[i]

        Params:
            A (address[]) - The first string.
            B (address[]) - The second string.
            message (string) - A message that is sent if the assertion fails.

        Returns:
            result (bool) - The result.
    */
    function notEqual(address[] memory arrA, address[] memory arrB, string memory message) public returns (bool result) {
        result = arrA.length == arrB.length;
        if (result) {
            for (uint i = 0; i < arrA.length; i++) {
                if (arrA[i] != arrB[i]) {
                    result = false;
                    break;
                }
            }
        }
        result = !result;
        _report(result, message);
    }

    /*
        Function: lengthEqual(address[])

        Assert that the length of an 'address[]' is equal to a given value.

        : arr.length == length

        Params:
            arr (address[]) - The array.
            length (uint) - The length.
            message (string) - A message that is sent if the assertion fails.

        Returns:
            result (bool) - The result.
    */
    function lengthEqual(address[] memory arr, uint length, string memory message) public returns (bool result) {
        uint arrLength = arr.length;
        if (arrLength == length)
            _report(result, "");
        else
            _report(result, _appendTagged(_tag(arrLength, "Tested"), _tag(length, "Against"), message));
    }

    /*
        Function: lengthNotEqual(address[])

        Assert that the length of an 'address[]' is not equal to a given value.

        : arr.length != length

        Params:
            arr (address[]) - The array.
            length (uint) - The length.
            message (string) - A message that is sent if the assertion fails.

        Returns:
            result (bool) - The result.
    */
    function lengthNotEqual(address[] memory arr, uint length, string memory message) public returns (bool result) {
        uint arrLength = arr.length;
        if (arrLength != arr.length)
            _report(result, "");
        else
            _report(result, _appendTagged(_tag(arrLength, "Tested"), _tag(length, "Against"), message));
    }

    /******************************** internal ********************************/

        /*
            Function: _report

            Internal function for triggering <TestEvent>.

            Params:
                result (bool) - The test result (true or false).
                message (string) - The message that is sent if the assertion fails.
        */
    function _report(bool result, string memory message) internal {
        if(result)
            emit TestEvent(true, "");
        else
            emit TestEvent(false, message);
    }

    /*
        Function: _utoa(uint)

        Convert an  unsigned integer to a string.

        Params:
            n (uint) - The unsigned integer.
            radix (uint8) - A number between 2 and 16 (inclusive). Characters used are 0-9,a-f

        Returns:
            result (string) - The resulting string.
    */
    function _utoa(uint n, uint8 radix) internal pure returns (string memory) {
        if (n == 0 || radix < 2 || radix > 16)
            return '0';
        bytes memory bts = new bytes(256);
        uint i;
        while (n > 0) {
            bts[i++] = _utoa(uint8(n % radix)); // Turn it to ascii.
            n /= radix;
        }
        // Reverse
        bytes memory rev = new bytes(i);
        for (uint j = 0; j < i; j++)
            rev[j] = bts[i - j - 1];
        return string(rev);
    }

    /*
        Function: _utoa(uint8)

        Convert an unsigned 8-bit integer to its ASCII byte representation. Numbers 0-9 are converted to '0'-'9',
        numbers 10-16 to 'a'-'f'. Numbers larger then 16 return the null byte.

        Params:
            u (uint8) - The unsigned 8-bit integer.

        Returns:
            result (string) - The ASCII byte.
    */
    function _utoa(uint8 u) internal pure returns (byte) {
        if (u < 10)
            return byte(u + ZERO);
        else if (u < 16)
            return byte(u - 10 + A);
        else
            return 0;
    }

    /*
    function htoa(address addr) constant returns (string) {
        bytes memory bts = new bytes(40);
        bytes20 addrBts = bytes20(addr);
        for (uint i = 0; i < 20; i++) {
            bts[2*i] = addrBts[i] % 16;
            bts[2*i + 1] = (addrBts[i] / 16) % 16;
        }
        return string(bts);
    }
    */

    /*
        Function: _tag(string)

        Add a tag to a string. The 'value' and 'tag' strings are returned on the form "tag: value".

        Params:
            value (string) - The value.
            tag (string) - The tag.

        Returns:
            result (string) - "tag: value"
    */
    function _tag(string memory value, string memory tag) internal pure returns (string memory) {

        bytes memory valueB = bytes(value);
        bytes memory tagB = bytes(tag);

        uint vl = valueB.length;
        uint tl = tagB.length;

        bytes memory newB = new bytes(vl + tl + 2);

        uint i;
        uint j;

        for (i = 0; i < tl; i++)
            newB[j++] = tagB[i];
        newB[j++] = ':';
        newB[j++] = ' ';
        for (i = 0; i < vl; i++)
            newB[j++] = valueB[i];

        return string(newB);
    }

    /*
        Function: _tag(uint)

        Add a tag to an uint.

        Params:
            value (uint) - The value.
            tag (string) - The tag.

        Returns:
            result (string) - "tag: _utoa(value)"
    */
    function _tag(uint value, string memory tag) internal pure returns (string memory) {
        string memory nstr = _utoa(value, 10);
        return _tag(nstr, tag);
    }

    /*
        Function: _appendTagged(string, string)

        Append two tagged values to a string.

        Params:
            tagged0 (string) - The first tagged value.
            tagged1 (string) - The second tagged value.
            str (string) - The string.

        Returns:
            result (string) - "str (tagged0, tagged1)"
    */
    function _appendTagged(string memory tagged0, string memory tagged1, string memory str) internal pure returns (string memory) {

        bytes memory tagged0B = bytes(tagged0);
        bytes memory tagged1B = bytes(tagged1);
        bytes memory strB = bytes(str);

        uint sl = strB.length;
        uint t0l = tagged0B.length;
        uint t1l = tagged1B.length;

        bytes memory newB = new bytes(sl + t0l + t1l + 5);

        uint i;
        uint j;

        for (i = 0; i < sl; i++)
            newB[j++] = strB[i];
        newB[j++] = ' ';
        newB[j++] = '(';
        for (i = 0; i < t0l; i++)
            newB[j++] = tagged0B[i];
        newB[j++] = ',';
        newB[j++] = ' ';
        for (i = 0; i < t1l; i++)
            newB[j++] = tagged1B[i];
        newB[j++] = ')';

        return string(newB);
    }
}


adding decimal places argument for qty.

adding decimal places argument for qty.

/*
    Copyright 2017 Phillip A. Elsasser

    Licensed under the Apache License, Version 2.0 (the "License");
    you may not use this file except in compliance with the License.
    You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

    Unless required by applicable law or agreed to in writing, software
    distributed under the License is distributed on an "AS IS" BASIS,
    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    See the License for the specific language governing permissions and
    limitations under the License.
*/

pragma solidity ^0.4.0;

import "./Creatable.sol";
import "./oraclize/oraclizeAPI.sol";
import "./libraries/MathLib.sol";
import "./libraries/HashLib.sol";
import "zeppelin-solidity/contracts/token/ERC20.sol";
import "zeppelin-solidity/contracts/token/SafeERC20.sol";

//TODO: fix style issues
//      add failsafe for pool distribution.
//      push as much into library as possible
//      create mappings for deposit tokens and balance of collateral pool
contract MarketContract is Creatable, usingOraclize  {
    using MathLib for uint256;
    using MathLib for int;
    using HashLib for address;
    using SafeERC20 for ERC20;

    struct UserNetPosition {
        address userAddress;
        Position[] positions;   // all open positions (lifo upon exit - allows us to not reindex array!)
        int netPosition;        // net position across all prices / executions
    }

    struct Position {
        uint price;
        int qty;
    }

    struct Order {
        address maker;
        address taker;
        address feeRecipient;
        uint makerFee;
        uint takerFee;
        uint qty;
        uint price;
        uint8 makerSide;            // 0=Buy 1=Sell
        uint expirationTimeStamp;
        bytes32 orderHash;
    }

    // constants
    string public CONTRACT_NAME;
    address public BASE_TOKEN_ADDRESS;
    ERC20 public BASE_TOKEN;
    uint public PRICE_CAP;
    uint public PRICE_FLOOR;
    uint public PRICE_DECIMAL_PLACES;   // how to convert the pricing from decimal format (if valid) to integer
    uint public QTY_DECIMAL_PLACES;     // how many tradeable units make up a whole pricing increment
    uint public EXPIRATION;
    string public ORACLE_DATA_SOURCE;
    string public ORACLE_QUERY;
    uint public ORACLE_QUERY_REPEAT;
    uint8 constant public BUY_SIDE = 0;
    uint8 constant public SELL_SIDE = 1;
    uint constant public COST_PER_QUERY = 2 finney;    // leave static for now, price of first query from oraclize is 0
    uint constant public QUERY_CALLBACK_GAS = 300000;

    // state variables
    string public lastPriceQueryResult;
    uint public lastPrice;
    bool public isExpired;
    mapping(bytes32 => bool) validQueryIDs;

    // accounting
    mapping(address => UserNetPosition) addressToUserPosition;
    mapping(address => uint) userAddressToAccountBalance;   // stores account balances allowed to be allocated to orders
    uint collateralPoolBalance = 0;                         // current balance of all collateral committed

    // events
    event OracleQuerySuccess();
    event OracleQueryFailed();
    event UpdatedLastPrice(string price);
    event ContractSettled();
    event DepositReceived(address user, uint depositAmount, uint totalBalance);
    event WithdrawCompleted(address user, uint withdrawAmount, uint totalBalance);

    function MarketContract(
        string contractName,
        address baseTokenAddress,
        string oracleDataSource,
        string oracleQuery,
        uint oracleQueryRepeatSeconds,
        uint floorPrice,
        uint capPrice,
        uint priceDecimalPlaces,
        uint qtyDecimalPlaces,
        uint secondsToExpiration
    ) public payable {

        require(capPrice > floorPrice);
        oraclize_setProof(proofType_TLSNotary | proofStorage_IPFS);
        CONTRACT_NAME = contractName;
        BASE_TOKEN_ADDRESS = baseTokenAddress;
        BASE_TOKEN = ERC20(baseTokenAddress);
        PRICE_CAP = capPrice;
        PRICE_FLOOR = floorPrice;
        EXPIRATION = now + secondsToExpiration;
        ORACLE_DATA_SOURCE = oracleDataSource;
        ORACLE_QUERY = oracleQuery;
        ORACLE_QUERY_REPEAT = oracleQueryRepeatSeconds;
        PRICE_DECIMAL_PLACES = priceDecimalPlaces;
        QTY_DECIMAL_PLACES = qtyDecimalPlaces;
        require(checkSufficientStartingBalance(secondsToExpiration));
        queryOracle();  // schedules recursive calls to oracle
    }

    function __callback(bytes32 queryID, string result, bytes proof) public {
        require(validQueryIDs[queryID]);
        require(msg.sender == oraclize_cbAddress());
        lastPriceQueryResult = result;
        lastPrice = parseInt(result, PRICE_DECIMAL_PLACES);
        UpdatedLastPrice(result);
        delete validQueryIDs[queryID];
        checkSettlement();
        if (!isExpired) {
            queryOracle();  // set up our next query
        }
    }

    function getUserPosition(address userAddress) public view returns (int)  {
        return addressToUserPosition[userAddress].netPosition;
    }

    function depositEtherForTrading() public payable {
        // should we allow ether or force users to use WETH?
    }

    // allows for all ERC20 tokens to be used for collateral and trading.
    function depositTokensForTrading(uint256 depositAmount) public {
        // user must call approve!
        BASE_TOKEN.safeTransferFrom(msg.sender, this, depositAmount);
        uint256 balanceAfterDeposit = userAddressToAccountBalance[msg.sender].add(depositAmount);
        userAddressToAccountBalance[msg.sender] = balanceAfterDeposit;
        DepositReceived(msg.sender, depositAmount, balanceAfterDeposit);
    }

    // allows user to remove token from trading account that have not been allocated to open positions
    function withdrawTokens(uint256 withdrawAmount) public {
        require(userAddressToAccountBalance[msg.sender] >= withdrawAmount);   // ensure sufficient balance
        uint256 balanceAfterWithdrawal = userAddressToAccountBalance[msg.sender].subtract(withdrawAmount);
        BASE_TOKEN.safeTransfer(msg.sender, withdrawAmount);
        WithdrawCompleted(msg.sender, withdrawAmount, balanceAfterWithdrawal);
    }

    function trade(address maker, address taker) public {
        require(maker != address(0) && maker != taker);     // do not allow self trade
        // TODO validate orders, etc
    }

    function updatePositions(address maker, address taker, int qty, uint price) private {
        updatePosition(addressToUserPosition[maker], qty, price);
        // continue process for taker, but qty is opposite sign for taker
        updatePosition(addressToUserPosition[taker], qty * -1, price);
    }

    function updatePosition(UserNetPosition storage userNetPosition, int qty, uint price) private {
        if(userNetPosition.netPosition == 0 ||  userNetPosition.netPosition.isSameSign(qty)) {
            // new position or adding to open pos, no collateral returned
            userNetPosition.positions.push(Position(price, newNetPos)); //append array with new position
        }
        else {
            // opposite side from open position, reduce, flattened, or flipped.
            if(userNetPosition.netPosition >= qty * -1) { // pos is reduced of flattened
                reduceUserNetPosition(userNetPosition, qty, price);
            } else {    // pos is flipped, reduce and then create new open pos!
                reduceUserNetPosition(userNetPosition, userNetPosition.netPosition * -1, price); // flatten completely
                int newNetPos = userNetPosition.netPosition + qty;            // the portion remaining after flattening
                userNetPosition.positions.push(Position(price, newNetPos));   // append array with new position
            }
        }
        userNetPosition.netPosition += qty;
    }

    function reduceUserNetPosition(UserNetPosition storage userNetPos, int qty, uint price) private {
        int qtyToReduce = qty;
        assert(userNetPos.positions.length != 0);  // sanity check
        while(qtyToReduce != 0) {
            Position storage position = userNetPos.positions[userNetPos.positions.length - 1];  // get the last pos (LIFO)
            if(position.qty.abs() <= qtyToReduce.abs()) { // this position is completely consumed!
                qtyToReduce = qtyToReduce + position.qty;
                // TODO: work on refunding correct amount of collateral.
                userNetPos.positions.length--;  // remove this position from our array.
            }
            else {  // this position stays, just reduce the qty.
                position.qty += qtyToReduce;
                // TODO: return collateral
                //qtyToReduce = 0; // completely reduced now!
                break;
            }
        }
    }

    function commitCollateralToPool(address fromAddress, uint collateralAmount) private {

    }

    function withdrawCollateralFromPool(address toAddress, uint collateralAmount) private {

    }

    function queryOracle() private {
        if (oraclize_getPrice(ORACLE_DATA_SOURCE) > this.balance) {
            OracleQueryFailed();
            lastPriceQueryResult = "FAILED"; //TODO: failsafe
        } else {
            OracleQuerySuccess();
            bytes32 queryId = oraclize_query(ORACLE_QUERY_REPEAT, ORACLE_DATA_SOURCE, ORACLE_QUERY, QUERY_CALLBACK_GAS);
            validQueryIDs[queryId] = true;
        }
    }

    function checkSettlement() private {
        if(isExpired)   // already expired.
            return;

        if(now > EXPIRATION) {
            isExpired = true;   // time based expiration has occurred.
        } else if(lastPrice >= PRICE_CAP || lastPrice <= PRICE_FLOOR) {
            isExpired = true;   // we have breached/touched our pricing bands
        }

        if(isExpired) {
            settleContract();
        }
    }

    function settleContract() private {
        // TODO: build mechanism for distribution of collateral
        ContractSettled();
    }

    // for now lets require alot of padding for the settlement,
    function checkSufficientStartingBalance(uint secondsToExpiration) private view returns (bool isSufficient) {
        //uint costPerQuery = oraclize_getPrice(ORACLE_DATA_SOURCE); this doesn't work prior to first query(its free)
        uint expectedNoOfQueries = secondsToExpiration / ORACLE_QUERY_REPEAT;
        uint approxGasRequired = COST_PER_QUERY * expectedNoOfQueries;
        return this.balance > (approxGasRequired * 2);
    }
}

/*
    Copyright 2017 Phillip A. Elsasser

    Licensed under the Apache License, Version 2.0 (the "License");
    you may not use this file except in compliance with the License.
    You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

    Unless required by applicable law or agreed to in writing, software
    distributed under the License is distributed on an "AS IS" BASIS,
    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    See the License for the specific language governing permissions and
    limitations under the License.
*/

pragma solidity ^0.4.0;

import "./Creatable.sol";
import "./oraclize/oraclizeAPI.sol";
import "./libraries/MathLib.sol";
import "./libraries/HashLib.sol";
import "zeppelin-solidity/contracts/token/ERC20.sol";
import "zeppelin-solidity/contracts/token/SafeERC20.sol";

//TODO: fix style issues
//      add failsafe for pool distribution.
//      push as much into library as possible
//      create mappings for deposit tokens and balance of collateral pool
contract MarketContract is Creatable, usingOraclize  {
    using MathLib for uint256;
    using MathLib for int;
    using HashLib for address;
    using SafeERC20 for ERC20;

    struct UserNetPosition {
        address userAddress;
        Position[] positions;   // all open positions (lifo upon exit - allows us to not reindex array!)
        int netPosition;        // net position across all prices / executions
    }

    struct Position {
        uint price;
        int qty;
    }

    struct Order {
        address maker;
        address taker;
        address feeRecipient;
        uint makerFee;
        uint takerFee;
        uint qty;
        uint price;
        uint8 makerSide;            // 0=Buy 1=Sell
        uint expirationTimeStamp;
        bytes32 orderHash;
    }

    // constants
    string public CONTRACT_NAME;
    address public BASE_TOKEN_ADDRESS;
    ERC20 public BASE_TOKEN;
    uint public PRICE_CAP;
    uint public PRICE_FLOOR;
    uint public PRICE_DECIMAL_PLACES;   // how to convert the pricing from decimal format (if valid) to integer
    uint public EXPIRATION;
    string public ORACLE_DATA_SOURCE;
    string public ORACLE_QUERY;
    uint public ORACLE_QUERY_REPEAT;
    uint8 constant public BUY_SIDE = 0;
    uint8 constant public SELL_SIDE = 1;
    uint constant public COST_PER_QUERY = 2 finney;    // leave static for now, price of first query from oraclize is 0
    uint constant public QUERY_CALLBACK_GAS = 300000;

    // state variables
    string public lastPriceQueryResult;
    uint public lastPrice;
    bool public isExpired;
    mapping(bytes32 => bool) validQueryIDs;

    // accounting
    mapping(address => UserNetPosition) addressToUserPosition;
    mapping(address => uint) userAddressToAccountBalance;   // stores account balances allowed to be allocated to orders
    uint collateralPoolBalance = 0;                         // current balance of all collateral committed

    // events
    event OracleQuerySuccess();
    event OracleQueryFailed();
    event UpdatedLastPrice(string price);
    event ContractSettled();
    event DepositReceived(address user, uint depositAmount, uint totalBalance);
    event WithdrawCompleted(address user, uint withdrawAmount, uint totalBalance);

    function MarketContract(
        string contractName,
        address baseTokenAddress,
        string oracleDataSource,
        string oracleQuery,
        uint oracleQueryRepeatSeconds,
        uint floorPrice,
        uint capPrice,
        uint priceDecimalPlaces,
        uint secondsToExpiration
    ) public payable {

        require(capPrice > floorPrice);
        oraclize_setProof(proofType_TLSNotary | proofStorage_IPFS);
        CONTRACT_NAME = contractName;
        BASE_TOKEN_ADDRESS = baseTokenAddress;
        BASE_TOKEN = ERC20(baseTokenAddress);
        PRICE_CAP = capPrice;
        PRICE_FLOOR = floorPrice;
        EXPIRATION = now + secondsToExpiration;
        ORACLE_DATA_SOURCE = oracleDataSource;
        ORACLE_QUERY = oracleQuery;
        ORACLE_QUERY_REPEAT = oracleQueryRepeatSeconds;
        PRICE_DECIMAL_PLACES = priceDecimalPlaces;
        require(checkSufficientStartingBalance(secondsToExpiration));
        queryOracle();  // schedules recursive calls to oracle
    }

    function __callback(bytes32 queryID, string result, bytes proof) public {
        require(validQueryIDs[queryID]);
        require(msg.sender == oraclize_cbAddress());
        lastPriceQueryResult = result;
        lastPrice = parseInt(result, PRICE_DECIMAL_PLACES);
        UpdatedLastPrice(result);
        delete validQueryIDs[queryID];
        checkSettlement();
        if (!isExpired) {
            queryOracle();  // set up our next query
        }
    }

    function getUserPosition(address userAddress) public view returns (int)  {
        return addressToUserPosition[userAddress].netPosition;
    }

    function depositEtherForTrading() public payable {
        // should we allow ether or force users to use WETH?
    }

    // allows for all ERC20 tokens to be used for collateral and trading.
    function depositTokensForTrading(uint256 depositAmount) public {
        // user must call approve!
        BASE_TOKEN.safeTransferFrom(msg.sender, this, depositAmount);
        uint256 balanceAfterDeposit = userAddressToAccountBalance[msg.sender].add(depositAmount);
        userAddressToAccountBalance[msg.sender] = balanceAfterDeposit;
        DepositReceived(msg.sender, depositAmount, balanceAfterDeposit);
    }

    // allows user to remove token from trading account that have not been allocated to open positions
    function withdrawTokens(uint256 withdrawAmount) public {
        require(userAddressToAccountBalance[msg.sender] >= withdrawAmount);   // ensure sufficient balance
        uint256 balanceAfterWithdrawal = userAddressToAccountBalance[msg.sender].subtract(withdrawAmount);
        BASE_TOKEN.safeTransfer(msg.sender, withdrawAmount);
        WithdrawCompleted(msg.sender, withdrawAmount, balanceAfterWithdrawal);
    }

    function trade(address maker, address taker) public {
        require(maker != address(0) && maker != taker);     // do not allow self trade
        // TODO validate orders, etc
    }

    function updatePositions(address maker, address taker, int qty, uint price) private {
        updatePosition(addressToUserPosition[maker], qty, price);
        // continue process for taker, but qty is opposite sign for taker
        updatePosition(addressToUserPosition[taker], qty * -1, price);
    }

    function updatePosition(UserNetPosition storage userNetPosition, int qty, uint price) private {
        if(userNetPosition.netPosition == 0 ||  userNetPosition.netPosition.isSameSign(qty)) {
            // new position or adding to open pos, no collateral returned
            userNetPosition.positions.push(Position(price, newNetPos)); //append array with new position
        }
        else {
            // opposite side from open position, reduce, flattened, or flipped.
            if(userNetPosition.netPosition >= qty * -1) { // pos is reduced of flattened
                reduceUserNetPosition(userNetPosition, qty, price);
            } else {    // pos is flipped, reduce and then create new open pos!
                reduceUserNetPosition(userNetPosition, userNetPosition.netPosition * -1, price); // flatten completely
                int newNetPos = userNetPosition.netPosition + qty;            // the portion remaining after flattening
                userNetPosition.positions.push(Position(price, newNetPos));   // append array with new position
            }
        }
        userNetPosition.netPosition += qty;
    }

    function reduceUserNetPosition(UserNetPosition storage userNetPos, int qty, uint price) private {
        int qtyToReduce = qty;
        assert(userNetPos.positions.length != 0);  // sanity check
        while(qtyToReduce != 0) {
            Position storage position = userNetPos.positions[userNetPos.positions.length - 1];  // get the last pos (LIFO)
            if(position.qty.abs() <= qtyToReduce.abs()) { // this position is completely consumed!
                qtyToReduce = qtyToReduce + position.qty;
                // TODO: work on refunding correct amount of collateral.
                userNetPos.positions.length--;  // remove this position from our array.
            }
            else {  // this position stays, just reduce the qty.
                position.qty += qtyToReduce;
                // TODO: return collateral
                //qtyToReduce = 0; // completely reduced now!
                break;
            }
        }
    }

    function commitCollateralToPool(address fromAddress, uint collateralAmount) private {

    }

    function withdrawCollateralFromPool(address toAddress, uint collateralAmount) private {

    }

    function queryOracle() private {
        if (oraclize_getPrice(ORACLE_DATA_SOURCE) > this.balance) {
            OracleQueryFailed();
            lastPriceQueryResult = "FAILED"; //TODO: failsafe
        } else {
            OracleQuerySuccess();
            bytes32 queryId = oraclize_query(ORACLE_QUERY_REPEAT, ORACLE_DATA_SOURCE, ORACLE_QUERY, QUERY_CALLBACK_GAS);
            validQueryIDs[queryId] = true;
        }
    }

    function checkSettlement() private {
        if(isExpired)   // already expired.
            return;

        if(now > EXPIRATION) {
            isExpired = true;   // time based expiration has occurred.
        } else if(lastPrice >= PRICE_CAP || lastPrice <= PRICE_FLOOR) {
            isExpired = true;   // we have breached/touched our pricing bands
        }

        if(isExpired) {
            settleContract();
        }
    }

    function settleContract() private {
        // TODO: build mechanism for distribution of collateral
        ContractSettled();
    }

    // for now lets require alot of padding for the settlement,
    function checkSufficientStartingBalance(uint secondsToExpiration) private view returns (bool isSufficient) {
        //uint costPerQuery = oraclize_getPrice(ORACLE_DATA_SOURCE); this doesn't work prior to first query(its free)
        uint expectedNoOfQueries = secondsToExpiration / ORACLE_QUERY_REPEAT;
        uint approxGasRequired = COST_PER_QUERY * expectedNoOfQueries;
        return this.balance > (approxGasRequired * 2);
    }
}


Added vending machine price calculator

Added vending machine price calculator

pragma solidity ^0.4.4;

// Vending machine to sell X number of tokens for approx Y number of ETH.
// As purchases are made, the owned ERC20 tokens will be sent out to purchaser.
// Purchases will be priced based on the purchase "Generation" the vending machine is in.
// As more purchases are made the Generation gets incremented.
// Each generation will sell the tokens for twice as much as the previous generation.
contract VendingMachine is Ownable {

    // The contract where the tokens are held by this contract until they are sold.
    ERC20 public token;

    // Total Amount of tokens to sell to purchasers
    uint public amountToSell = 21000000;

    // Total amount of tokens that have been sold so far.  Starts at 0.
    uint public amountSold = 0;

    // Initial price that each ETH sent in will get back in tokens.
    uint public initialPricePerEth = 10000;

    // Amount of tokens to sell per generation
    uint public tokensPerGeneration = 120000;

    // Constructor initalized with the token contract that it will be selling.
    function VendingMachine(ERC20 tokenContract){
        token = tokenContract;
    }

    // This function will calculate how many tokens they will get with the amount of ETH they are sending in
    function calculateSaleAmount(uint amountSoldStart, uint ethAmount) uint{
        // Keep track of the amount to sell
        uint amountToSell = 0;

        // First get the amount of tokens sold from the beginning of this generation and the amount left.
        uint currentGeneration = amountSoldStart / tokensPerGeneration;
        uint amountLeftInCurrentGeneration = tokensPerGeneration - (amountSoldStart % tokensPerGeneration);

        // Calculate the price per ETH of the current generation
        uint salePrice = initialPricePerEth;
        for(uint i = 0 ; i < currentGeneration; i ++){
            salePrice = salePrice / 2;
        }

        // Calculate how mant tokens they are trying to buy
        uint amountToSell = salePrice * ethAmount;

        // If they are buying past the current generation, then figure out how much they purchase in the next generation.
        if (amountToSell > amountLeftInCurrentGeneration){
            // Calculate how much ETH would be used from the current generation
            uint ethFromCurrentGen = salePrice * amountLeftInCurrentGeneration;

            // Recursively call this function with the starting amount being the next gen and remaining ETH
            return (ethFromCurrentGen * salePrice) + amountLeftInCurrentGeneration(currentGeneration * tokensPerGeneration, ethAmount - ethFromCurrentGen) ;
        }

        // Return the amount to sell
        return amountToSell;
    }

    // When this function is called, it will send the originator X tokens.
    // X is determined by the price calculated based on the current generation of sales.
    function PurchaseTokens payable(){

        // Figure out how many tokens they are buying
        uint amountPurchased = calculateSaleAmount(amountSold, msg.amount);

        // Updatete the total amount sold
        amountSold += amountPurchased;

        // Send the tokens to the buyers's account
        if(!token.transfer(msg.sender, amountPurchased)){
            throw;
        }
    }

    // This function allows the owner to withdraw any ETH that was sent in via purchases.
    function WithdrawEth(uint amount) onlyOwner {
        // Send out what they are requesting to withdraw and trigger the send
        msg.sender.send(amount);
    }
}

pragma solidity ^0.4.4;

// Vending machine to sell X number of tokens for approx Y number of ETH.
// As purchases are made, the owned ERC20 tokens will be sent out to purchaser.
// Purchases will be priced based on the purchase "Generation" the vending machine is in.
// As more purchases are made the Generation gets incremented.
// Each generation will sell the tokens for twice as much as the previous generation.
contract VendingMachine is Ownable {

    // The contract where the tokens are held by this contract until they are sold.
    ERC20 public token;

    // Total Amount of tokens to sell to purchasers
    uint public amountToSell = 21000000;

    // Total amount of tokens that have been sold so far.  Starts at 0.
    uint public amountSold = 0;

    // Initial price that each ETH sent in will get back in tokens.
    uint public initialPricePerEth = 10000;

    // Constructor initalized with the token contract that it will be selling.
    function VendingMachine(ERC20 tokenContract){
        token = tokenContract;
    }

    function calculateSaleAmount(uint alreadySold, uint ethAmount) uint{
        // First get the amount of tokens sold from the beginning of this generation.
        // Calculate the price per ETH of the current generation
        // Calculate how mant tokens they are trying to buy
        // If they are buying past the current generation, then figure out how much they purchase in the next generation.
    }

    // When this function is called, it will send the originator X tokens.
    // X is determined by the price calculated based on the current generation of sales.
    function PurchaseTokens payable(){

        // Updatete the total amount sold

        // Send the tokens to the sender's account
    }

    // This function allows the owner to withdraw any ETH that was sent in via purchases.
    function WithdrawEth(uint amount) onlyOwner {
        // Send out what they are requesting to withdraw
        msg.sender.send(amount);
    }
}

Example:

I want to sell 10 tokens for 10 ETH, but I want the first token sole to be super cheap

First token sells for 0.1 ETH and last sells for 0.9 ETH

0.1
0.2
0.3
0.4
0.5
0.6
0.7
0.8
0.9
1


catalogo: trocar array por map + adicionar metodos para inspecao

pragma solidity ^0.4.11;

/// @title Catalogo de Ouvidorias para o Barramento de Ouvidorias
contract CatalogoOuvidorias {

    enum TipoEnte { Uniao, Estado, Municipio }

    struct Ente {
        TipoEnte tipo;
        bytes32 nome;   // nome do ente, caso se aplique (Uniao nao eh necessario). Ex.: 'Bahia', 'Salvador-BA'
    }

    struct Ouvidoria {
        address conta; // account Ethereum desta ouvidoria
        bytes32 nome;   // nome do orgao
        Ente ente; // ente a qual a ouvidoria pertence
        bytes32 endpoint;   // URL da aplicacao/web service desta ouvidoria
    }

    address[] enderecosOuvidorias;

    mapping(address => Ouvidoria) private ouvidorias;

    mapping(address => uint8) public candidatas;

    event ouvidoriasAtualizadas(address conta, bytes32 nome, uint8 tipoEnte, bytes32 nomeEnte, bytes32 endpoint);

    /// Cria o catalogo com uma ouvidoria -- nao exigi tres porque seriam tantas variaveis que o solarity nao permite:
    /// Compiler error (...): Stack too deep, try removing local variables.
    function CatalogoOuvidorias(bytes32 nome, uint8 tipoEnte, bytes32 nomeEnte, bytes32 endpoint) {
        ouvidorias[msg.sender] = Ouvidoria({
            conta: msg.sender,
            nome: nome,
            ente: Ente({tipo: toTipoEnte(tipoEnte), nome: nomeEnte}),
            endpoint: endpoint
        });
        enderecosOuvidorias.push(msg.sender);
    }

    function toTipoEnte(uint8 tipo) returns (TipoEnte) {
        if (tipo == 0) return TipoEnte.Uniao;
        if (tipo == 1) return TipoEnte.Estado;
        if (tipo == 2) return TipoEnte.Municipio;
        throw;
    }

    function getNumeroDeOuvidorias() constant returns (uint) {
        return enderecosOuvidorias.length;
    }

    function getEnderecoOuvidoria(uint i) constant returns (address) {
        return enderecosOuvidorias[i];
    }

    function getOuvidoriaNome(address ouvidoria) constant returns (bytes32) {
        return ouvidorias[ouvidoria].nome;
    }

    function getOuvidoriaEndpoint(address ouvidoria) constant returns (bytes32) {
        return ouvidorias[ouvidoria].endpoint;
    }

    function getOuvidoriaEnteTipo(address ouvidoria) constant returns (uint) {
        return uint(ouvidorias[ouvidoria].ente.tipo);
    }

    function getOuvidoriaEnteNome(address ouvidoria) constant returns (string) {
        return toS(ouvidorias[ouvidoria].ente.nome);
    }

    // Uma ouvidoria cadastrada pode votar em outra
    function votar(address ouvidoriaCandidata) {
        log1('votando', '2');
    }

    // converte bytes32 em string
    function toS(bytes32 x) constant returns (string) {
        bytes memory bytesString = new bytes(32);
        uint charCount = 0;
        for (uint j = 0; j < 32; j++) {
            byte char = byte(bytes32(uint(x) * 2 ** (8 * j)));
            if (char != 0) {
                bytesString[charCount] = char;
                charCount++;
            }
        }
        bytes memory bytesStringTrimmed = new bytes(charCount);
        for (j = 0; j < charCount; j++) {
            bytesStringTrimmed[j] = bytesString[j];
        }
        return string(bytesStringTrimmed);
    }

}

pragma solidity ^0.4.11;

/// @title Catalogo de Ouvidorias para o Barramento de Ouvidorias
contract CatalogoOuvidorias {

    enum TipoEnte { Uniao, Estado, Municipio }

    struct Ente {
        TipoEnte tipo;
        bytes32 nome;   // nome do ente, caso se aplique (Uniao nao eh necessario). Ex.: 'Bahia', 'Salvador-BA'
    }

    struct Ouvidoria {
        address conta; // account Ethereum desta ouvidoria
        bytes32 nome;   // nome do orgao
        Ente ente; // ente a qual a ouvidoria pertence
        bytes32 endpoint;   // URL da aplicacao/web service desta ouvidoria
    }

    Ouvidoria[] private ouvidorias;

    /// Cria o catalogo com uma ouvidoria -- nao exigi tres porque seriam tantas variaveis que o solarity nao permite:
    /// Compiler error (...): Stack too deep, try removing local variables.
    function CatalogoOuvidorias(bytes32 nome, uint8 tipoEnte, bytes32 nomeEnte, bytes32 endpoint) {
        ouvidorias.push(Ouvidoria({
            conta: msg.sender,
            nome: nome,
            ente: Ente({tipo: toTipoEnte(tipoEnte), nome: nomeEnte}),
            endpoint: endpoint
        }));
    }

    function toTipoEnte(uint8 tipo) returns (TipoEnte) {
        if (tipo == 0) return TipoEnte.Uniao;
        if (tipo == 1) return TipoEnte.Estado;
        if (tipo == 2) return TipoEnte.Municipio;
        throw;
    }

}


DAOMarketRegulator: contructor name fix

DAOMarketRegulator: contructor name fix

import 'agent_storage.sol';
import 'spec_token.sol';
import 'voting.sol';
import 'market.sol';

/**
 * @title The market rule interface
 */
contract MarketRule {
    /**
     * @dev How amount of token emission needed when given lot is deal
     * @param _deal lot address
     * @return count of emission token value
     */
    function getEmission(Lot _deal) returns (uint);
}

/**
 * @title The market agent interface,
 *        market agent is contract presents a person on the market
 */
contract MarketAgent is Mortal {
    /**
     * @dev Place lot on the market
     * @param _name traded item term name
     * @param _token traded token
     * @param _value how much items traded
     * @param _price one item price
     * @return placed lot address for tracking
     */
    function put(string _name, SpecToken _token,
                 uint _value,  uint _price) onlyOwner returns (Lot);

    /**
     * @dev Get market lot with traded item name
     * @param _index lot position
     * @return traded item description, lot address
     */
    function get(uint _index) constant returns (Knowledge, Lot);

    /**
     * @dev Take a deal by given lot
     * @param _lot target lot address
     * @return `true` when deal is ok
     */
    function deal(Lot _lot) onlyOwner returns (bool);
}

/**
 * @title Market regulator abstract contract,
 *        this contract creates market and `credits` token
 *        for market trade
 */
contract MarketRegulator is Mortal {
    /* The self market */
    Market public market;

    /* The self credits */
    Token  public credits;

    /* The self created market agents */
    address[] public agents;
    using AddressArray for address[];

    /* Only market agents can call modified functions */
    modifier onlyAgents { if (agents.indexOf(msg.sender) < agents.length) _ }

    function MarketRegulator() {
        market  = new Market();
        credits = new Token("Credits", "C");
    }

    /**
     * @dev Sign a contract with sender for trading on market
     * @return `MarketAgent` instance
     */
    function sign() returns (MarketAgent);

    /**
     * @dev Deal done callback, this called by market agent
     *      after call deal of `Lot`
     * @param _lot is deal description
     */
    function dealDone(Lot _lot) onlyAgents;
}

/**
 * @title The DAO market regulator is a market regulator with voting procedure
 */
contract DAOMarketRegulator is MarketRegulator {
    /* The DAO shares token */
    Token public shares;

    /* The DAO thesaurus */
    HumanAgentStorage public thesaurus;

    /* The rule poll by asset address */
    mapping(address => Voting.Poll) ruleOf;
    using Voting for Voting.Poll;

    function DAOMarketRegulator(Token _shares, HumanAgentStorage _thesaurus) {
        shares    = _shares;
        thesaurus = _thesaurus;
    }

    /**
     * @dev Sign a contract with sender for trading on market
     * @return `MarketAgent` instance
     */
    function sign() returns (MarketAgent) {
        // Make a new market agent
        var agent = new DAOMarketAgent(thesaurus);
        // Store agent address for the future usage
        agents.push(agent);
        // Delegate agent to sender
        agent.delegate(msg.sender);
        // Return agent address
        return agent;
    }

    /**
     * @dev Deal done callback, market regulation is maked according
     *      the rules taked from poll stack
     * @param _lot is deal description
     */
    function dealDone(Lot _lot) onlyAgents {
        var assetToken = _lot.buy() == credits ? _lot.sale() : _lot.buy();
        var asset = SpecToken(assetToken).specification();
        var rule = ruleOf[asset].current;
        if (rule != 0) {
            var emission = MarketRule(rule).getEmission(_lot);
            credits.emission(emission);
            credits.transfer(owner, emission);
        }
    }

    /**
     * @dev Increase poll for given asset
     * @param _asset asset for applying the rule
     * @param _rule the rule is maked for given asset
     * @param _count how much shares given for increase
     */
    function pollUp(Knowledge _asset, MarketRule _rule, uint _count)
    { ruleOf[_asset].up(msg.sender, _rule, shares, _count); }

    /**
     * @dev Decrease poll for given asset
     * @param _asset asset for applying the rule
     * @param _count count of refunded shares
     */
    function pollDown(Knowledge _asset, uint _count)
    { ruleOf[_asset].down(msg.sender, shares, _count); }
}

contract DAOMarketAgent is MarketAgent {
    MarketRegulator   regulator;
    HumanAgentStorage thesaurus;

    function DAOMarketAgent(HumanAgentStorage _thesaurus) {
        regulator = MarketRegulator(msg.sender);
        thesaurus = _thesaurus;
    }

    /**
     * @dev Place lot on the market
     * @param _name traded item term name
     * @param _token traded token
     * @param _value how much items traded
     * @param _price one item price
     * @return placed lot address for tracking
     */
    function put(string _name, SpecToken _token,
                 uint _value,  uint _price) onlyOwner returns (Lot) {
        // Check knowledge consistence
        var spec = thesaurus.getKnowledgeByName(_name);
        if (!spec.isEqual(_token.specification()))
            throw;

        // Transfer traded token to self
        if (!_token.transferFrom(msg.sender, this, _value))
            throw;

        // Approve credits that will be given from deal
        regulator.credits().approve(msg.sender, _value * _price);

        // Make lot and place on market
        var lot = new Lot(_token, regulator.credits(), _value, _price);
        regulator.market().append(lot);

        // Approve lot in traded token for deal
        _token.approve(lot, _value);
        return lot;
    }

    /**
     * @dev Get market lot with traded item specification
     * @param _index lot position
     * @return traded item description, lot address
     */
    function get(uint _index) constant returns (Knowledge, Lot) {
        if (_index >= regulator.market().size()) throw;

        var lot = Lot(regulator.market().lots(_index));
        var saleToken = SpecToken(lot.sale());
        var saleSpec = saleToken.specification();

        for (uint i = 0; i < thesaurus.knowledgesLength(); i += 1) {
            var knowledge = thesaurus.getKnowledge(i);
            if (knowledge.isEqual(saleSpec))
                return (knowledge, lot);
        }
        return (Knowledge(0), lot);
    }

    /**
     * @dev Take a deal by given lot
     * @param _lot target lot address
     * @return `true` when deal is ok
     */
    function deal(Lot _lot) onlyOwner returns (bool) {
        var buyValue = _lot.value() * _lot.price();
        // Check balance of sender for the deal

        // Transfer buy value for the lot
        if (!_lot.buy().transferFrom(msg.sender, this, buyValue))
            return false;
        _lot.buy().approve(_lot, buyValue);

        // Try the deal
        if(!_lot.deal()) {
            // Refund when deal isn't ok
            _lot.buy().transfer(msg.sender, buyValue);
            return false;
        }

        // Transfer when deal is success
        _lot.sale().transfer(msg.sender, _lot.value());

        // Notify the regulator
        regulator.dealDone(_lot);
        return true;
    }
}

import 'agent_storage.sol';
import 'spec_token.sol';
import 'voting.sol';
import 'market.sol';

/**
 * @title The market rule interface
 */
contract MarketRule {
    /**
     * @dev How amount of token emission needed when given lot is deal
     * @param _deal lot address
     * @return count of emission token value
     */
    function getEmission(Lot _deal) returns (uint);
}

/**
 * @title The market agent interface,
 *        market agent is contract presents a person on the market
 */
contract MarketAgent is Mortal {
    /**
     * @dev Place lot on the market
     * @param _name traded item term name
     * @param _token traded token
     * @param _value how much items traded
     * @param _price one item price
     * @return placed lot address for tracking
     */
    function put(string _name, SpecToken _token,
                 uint _value,  uint _price) onlyOwner returns (Lot);

    /**
     * @dev Get market lot with traded item name
     * @param _index lot position
     * @return traded item description, lot address
     */
    function get(uint _index) constant returns (Knowledge, Lot);

    /**
     * @dev Take a deal by given lot
     * @param _lot target lot address
     * @return `true` when deal is ok
     */
    function deal(Lot _lot) onlyOwner returns (bool);
}

/**
 * @title Market regulator abstract contract,
 *        this contract creates market and `credits` token
 *        for market trade
 */
contract MarketRegulator is Mortal {
    /* The self market */
    Market public market;

    /* The self credits */
    Token  public credits;

    /* The self created market agents */
    address[] public agents;
    using AddressArray for address[];

    /* Only market agents can call modified functions */
    modifier onlyAgents { if (agents.indexOf(msg.sender) < agents.length) _ }

    function MarketRegulator() {
        market  = new Market();
        credits = new Token("Credits", "C");
    }

    /**
     * @dev Sign a contract with sender for trading on market
     * @return `MarketAgent` instance
     */
    function sign() returns (MarketAgent);

    /**
     * @dev Deal done callback, this called by market agent
     *      after call deal of `Lot`
     * @param _lot is deal description
     */
    function dealDone(Lot _lot) onlyAgents;
}

/**
 * @title The DAO market regulator is a market regulator with voting procedure
 */
contract DAOMarketRegulator is MarketRegulator {
    /* The DAO shares token */
    Token public shares;

    /* The DAO thesaurus */
    HumanAgentStorage public thesaurus;

    /* The rule poll by asset address */
    mapping(address => Voting.Poll) ruleOf;
    using Voting for Voting.Poll;

    function MarketRegulator(Token _shares, HumanAgentStorage _thesaurus) {
        shares    = _shares;
        thesaurus = _thesaurus;
    }

    /**
     * @dev Sign a contract with sender for trading on market
     * @return `MarketAgent` instance
     */
    function sign() returns (MarketAgent) {
        // Make a new market agent
        var agent = new DAOMarketAgent(thesaurus);
        // Store agent address for the future usage
        agents.push(agent);
        // Delegate agent to sender
        agent.delegate(msg.sender);
        // Return agent address
        return agent;
    }

    /**
     * @dev Deal done callback, market regulation is maked according
     *      the rules taked from poll stack
     * @param _lot is deal description
     */
    function dealDone(Lot _lot) onlyAgents {
        var assetToken = _lot.buy() == credits ? _lot.sale() : _lot.buy();
        var asset = SpecToken(assetToken).specification();
        var rule = ruleOf[asset].current;
        if (rule != 0) {
            var emission = MarketRule(rule).getEmission(_lot);
            credits.emission(emission);
            credits.transfer(owner, emission);
        }
    }

    /**
     * @dev Increase poll for given asset
     * @param _asset asset for applying the rule
     * @param _rule the rule is maked for given asset
     * @param _count how much shares given for increase
     */
    function pollUp(Knowledge _asset, MarketRule _rule, uint _count)
    { ruleOf[_asset].up(msg.sender, _rule, shares, _count); }

    /**
     * @dev Decrease poll for given asset
     * @param _asset asset for applying the rule
     * @param _count count of refunded shares
     */
    function pollDown(Knowledge _asset, uint _count)
    { ruleOf[_asset].down(msg.sender, shares, _count); }
}

contract DAOMarketAgent is MarketAgent {
    MarketRegulator   regulator;
    HumanAgentStorage thesaurus;

    function DAOMarketAgent(HumanAgentStorage _thesaurus) {
        regulator = MarketRegulator(msg.sender);
        thesaurus = _thesaurus;
    }

    /**
     * @dev Place lot on the market
     * @param _name traded item term name
     * @param _token traded token
     * @param _value how much items traded
     * @param _price one item price
     * @return placed lot address for tracking
     */
    function put(string _name, SpecToken _token,
                 uint _value,  uint _price) onlyOwner returns (Lot) {
        // Check knowledge consistence
        var spec = thesaurus.getKnowledgeByName(_name);
        if (!spec.isEqual(_token.specification()))
            throw;

        // Transfer traded token to self
        if (!_token.transferFrom(msg.sender, this, _value))
            throw;

        // Approve credits that will be given from deal
        regulator.credits().approve(msg.sender, _value * _price);

        // Make lot and place on market
        var lot = new Lot(_token, regulator.credits(), _value, _price);
        regulator.market().append(lot);

        // Approve lot in traded token for deal
        _token.approve(lot, _value);
        return lot;
    }

    /**
     * @dev Get market lot with traded item specification
     * @param _index lot position
     * @return traded item description, lot address
     */
    function get(uint _index) constant returns (Knowledge, Lot) {
        if (_index >= regulator.market().size()) throw;

        var lot = Lot(regulator.market().lots(_index));
        var saleToken = SpecToken(lot.sale());
        var saleSpec = saleToken.specification();

        for (uint i = 0; i < thesaurus.knowledgesLength(); i += 1) {
            var knowledge = thesaurus.getKnowledge(i);
            if (knowledge.isEqual(saleSpec))
                return (knowledge, lot);
        }
        return (Knowledge(0), lot);
    }

    /**
     * @dev Take a deal by given lot
     * @param _lot target lot address
     * @return `true` when deal is ok
     */
    function deal(Lot _lot) onlyOwner returns (bool) {
        var buyValue = _lot.value() * _lot.price();
        // Check balance of sender for the deal

        // Transfer buy value for the lot
        if (!_lot.buy().transferFrom(msg.sender, this, buyValue))
            return false;
        _lot.buy().approve(_lot, buyValue);

        // Try the deal
        if(!_lot.deal()) {
            // Refund when deal isn't ok
            _lot.buy().transfer(msg.sender, buyValue);
            return false;
        }

        // Transfer when deal is success
        _lot.sale().transfer(msg.sender, _lot.value());

        // Notify the regulator
        regulator.dealDone(_lot);
        return true;
    }
}


Scaffolding

Scaffolding

//Quadractic voting
contract Quadractic{
	struct votingRules {
		bool ethCurrency;
		uint voteCost;
	}
	struct proposal {
		bytes32 name;
		uint voteCount;
		uint startDate;
		unit endDate;
	}

	function voteBuyer{
	}
}