Cosmetic

Cosmetic

Variable 'baseN' should be named 'baseD'.

pragma solidity ^0.4.11;
import './SafeMath.sol';
import './IBancorFormula.sol';

/*
    Open issues:
    - The formula is not yet super accurate, especially for very small/very high ratios
    - Possibly support dynamic precision in the future
*/

contract BancorFormula is IBancorFormula, SafeMath {

    uint8 constant PRECISION   = 32;  // fractional bits
    uint256 constant FIXED_ONE = uint256(1) << PRECISION; // 0x100000000
    uint256 constant FIXED_TWO = uint256(2) << PRECISION; // 0x200000000
    uint256 constant MAX_VAL   = uint256(1) << (256 - PRECISION); // 0x0000000100000000000000000000000000000000000000000000000000000000
    string public version = '0.1';

    function BancorFormula() {
    }

    /**
        @dev given a token supply, reserve, CRR and a deposit amount (in the reserve token), calculates the return for a given change (in the main token)

        Formula:
        Return = _supply * ((1 + _depositAmount / _reserveBalance) ^ (_reserveRatio / 100) - 1)

        @param _supply             token total supply
        @param _reserveBalance     total reserve
        @param _reserveRatio       constant reserve ratio, 1-100
        @param _depositAmount      deposit amount, in reserve token

        @return purchase return amount
    */
    function calculatePurchaseReturn(uint256 _supply, uint256 _reserveBalance, uint16 _reserveRatio, uint256 _depositAmount) public constant returns (uint256) {
        // validate input
        require(_supply != 0 && _reserveBalance != 0 && _reserveRatio > 0 && _reserveRatio <= 100);

        // special case for 0 deposit amount
        if (_depositAmount == 0)
            return 0;

        uint256 baseN = safeAdd(_depositAmount, _reserveBalance);
        uint256 temp;

        // special case if the CRR = 100
        if (_reserveRatio == 100) {
            temp = safeMul(_supply, baseN) / _reserveBalance;
            return safeSub(temp, _supply);
        }

        uint256 resN = power(baseN, _reserveBalance, _reserveRatio, 100);

        temp = safeMul(_supply, resN) / FIXED_ONE;

        return safeSub(temp, _supply);
     }

    /**
        @dev given a token supply, reserve, CRR and a sell amount (in the main token), calculates the return for a given change (in the reserve token)

        Formula:
        Return = _reserveBalance * (1 - (1 - _sellAmount / _supply) ^ (1 / (_reserveRatio / 100)))

        @param _supply             token total supply
        @param _reserveBalance     total reserve
        @param _reserveRatio       constant reserve ratio, 1-100
        @param _sellAmount         sell amount, in the token itself

        @return sale return amount
    */
    function calculateSaleReturn(uint256 _supply, uint256 _reserveBalance, uint16 _reserveRatio, uint256 _sellAmount) public constant returns (uint256) {
        // validate input
        require(_supply != 0 && _reserveBalance != 0 && _reserveRatio > 0 && _reserveRatio <= 100 && _sellAmount <= _supply);

        // special case for 0 sell amount
        if (_sellAmount == 0)
            return 0;

        uint256 baseD = safeSub(_supply, _sellAmount);
        uint256 temp1;
        uint256 temp2;

        // special case if the CRR = 100
        if (_reserveRatio == 100) {
            temp1 = safeMul(_reserveBalance, _supply);
            temp2 = safeMul(_reserveBalance, baseD);
            return safeSub(temp1, temp2) / _supply;
        }

        // special case for selling the entire supply
        if (_sellAmount == _supply)
            return _reserveBalance;

        uint256 resN = power(_supply, baseD, 100, _reserveRatio);

        temp1 = safeMul(_reserveBalance, resN);
        temp2 = safeMul(_reserveBalance, FIXED_ONE);

        return safeSub(temp1, temp2) / resN;
    }

    /**
        @dev Calculate (_baseN / _baseD) ^ (_expN / _expD)
        Returns result upshifted by PRECISION

        This method is overflow-safe
    */
    function power(uint256 _baseN, uint256 _baseD, uint32 _expN, uint32 _expD) constant returns (uint256 resN) {
        uint256 logbase = ln(_baseN, _baseD);
        // Not using safeDiv here, since safeDiv protects against
        // precision loss. It's unavoidable, however
        // Both `ln` and `fixedExp` are overflow-safe.
        resN = fixedExp(safeMul(logbase, _expN) / _expD);
        return resN;
	}

    /**
        input range:
            - numerator: [1, uint256_max >> PRECISION]
            - denominator: [1, uint256_max >> PRECISION]
        output range:
            [0, 0x9b43d4f8d6]

        This method asserts outside of bounds

    */
    function ln(uint256 _numerator, uint256 _denominator) public constant returns (uint256) {
        // denominator > numerator: less than one yields negative values. Unsupported
        assert(_denominator <= _numerator);

        // log(1) is the lowest we can go
        assert(_denominator != 0 && _numerator != 0);

        // Upper 32 bits are scaled off by PRECISION
        assert(_numerator < MAX_VAL);
        assert(_denominator < MAX_VAL);

        return fixedLoge( (_numerator * FIXED_ONE) / _denominator);
    }

    /**
        input range:
            [0x100000000,uint256_max]
        output range:
            [0, 0x9b43d4f8d6]

        This method asserts outside of bounds

    */
    function fixedLoge(uint256 _x) constant returns (uint256 logE) {
        /*
        Since `fixedLog2_min` output range is max `0xdfffffffff`
        (40 bits, or 5 bytes), we can use a very large approximation
        for `ln(2)`. This one is used since it's the max accuracy
        of Python `ln(2)`

        0xb17217f7d1cf78 = ln(2) * (1 << 56)

        */
        //Cannot represent negative numbers (below 1)
        assert(_x >= FIXED_ONE);

        uint256 log2 = fixedLog2(_x);
        logE = (log2 * 0xb17217f7d1cf78) >> 56;
    }

    /**
        Returns log2(x >> 32) << 32 [1]
        So x is assumed to be already upshifted 32 bits, and
        the result is also upshifted 32 bits.

        [1] The function returns a number which is lower than the
        actual value

        input-range :
            [0x100000000,uint256_max]
        output-range:
            [0,0xdfffffffff]

        This method asserts outside of bounds

    */
    function fixedLog2(uint256 _x) constant returns (uint256) {
        // Numbers below 1 are negative.
        assert( _x >= FIXED_ONE);

        uint256 hi = 0;
        while (_x >= FIXED_TWO) {
            _x >>= 1;
            hi += FIXED_ONE;
        }

        for (uint8 i = 0; i < PRECISION; ++i) {
            _x = (_x * _x) / FIXED_ONE;
            if (_x >= FIXED_TWO) {
                _x >>= 1;
                hi += uint256(1) << (PRECISION - 1 - i);
            }
        }

        return hi;
    }

    /**
        fixedExp is a 'protected' version of `fixedExpUnsafe`, which
        asserts instead of overflows
    */
    function fixedExp(uint256 _x) constant returns (uint256) {
        assert(_x <= 0x386bfdba29);
        return fixedExpUnsafe(_x);
    }

    /**
        fixedExp
        Calculates e^x according to maclauren summation:

        e^x = 1+x+x^2/2!...+x^n/n!

        and returns e^(x>>32) << 32, that is, upshifted for accuracy

        Input range:
            - Function ok at    <= 242329958953
            - Function fails at >= 242329958954

        This method is is visible for testcases, but not meant for direct use.

        The values in this method been generated via the following python snippet:

        def calculateFactorials():
            """Method to print out the factorials for fixedExp"""

            ni = []
            ni.append( 295232799039604140847618609643520000000) # 34!
            ITERATIONS = 34
            for n in range( 1,  ITERATIONS,1 ) :
                ni.append(math.floor(ni[n - 1] / n))
            print( "\n        ".join(["xi = (xi * _x) >> PRECISION;\n        res += xi * %s;" % hex(int(x)) for x in ni]))

    */
    function fixedExpUnsafe(uint256 _x) constant returns (uint256) {

        uint256 xi = FIXED_ONE;
        uint256 res = 0xde1bc4d19efcac82445da75b00000000 * xi;

        xi = (xi * _x) >> PRECISION;
        res += xi * 0xde1bc4d19efcb0000000000000000000;
        xi = (xi * _x) >> PRECISION;
        res += xi * 0x6f0de268cf7e58000000000000000000;
        xi = (xi * _x) >> PRECISION;
        res += xi * 0x2504a0cd9a7f72000000000000000000;
        xi = (xi * _x) >> PRECISION;
        res += xi * 0x9412833669fdc800000000000000000;
        xi = (xi * _x) >> PRECISION;
        res += xi * 0x1d9d4d714865f500000000000000000;
        xi = (xi * _x) >> PRECISION;
        res += xi * 0x4ef8ce836bba8c0000000000000000;
        xi = (xi * _x) >> PRECISION;
        res += xi * 0xb481d807d1aa68000000000000000;
        xi = (xi * _x) >> PRECISION;
        res += xi * 0x16903b00fa354d000000000000000;
        xi = (xi * _x) >> PRECISION;
        res += xi * 0x281cdaac677b3400000000000000;
        xi = (xi * _x) >> PRECISION;
        res += xi * 0x402e2aad725eb80000000000000;
        xi = (xi * _x) >> PRECISION;
        res += xi * 0x5d5a6c9f31fe24000000000000;
        xi = (xi * _x) >> PRECISION;
        res += xi * 0x7c7890d442a83000000000000;
        xi = (xi * _x) >> PRECISION;
        res += xi * 0x9931ed540345280000000000;
        xi = (xi * _x) >> PRECISION;
        res += xi * 0xaf147cf24ce150000000000;
        xi = (xi * _x) >> PRECISION;
        res += xi * 0xbac08546b867d000000000;
        xi = (xi * _x) >> PRECISION;
        res += xi * 0xbac08546b867d00000000;
        xi = (xi * _x) >> PRECISION;
        res += xi * 0xafc441338061b8000000;
        xi = (xi * _x) >> PRECISION;
        res += xi * 0x9c3cabbc0056e000000;
        xi = (xi * _x) >> PRECISION;
        res += xi * 0x839168328705c80000;
        xi = (xi * _x) >> PRECISION;
        res += xi * 0x694120286c04a0000;
        xi = (xi * _x) >> PRECISION;
        res += xi * 0x50319e98b3d2c400;
        xi = (xi * _x) >> PRECISION;
        res += xi * 0x3a52a1e36b82020;
        xi = (xi * _x) >> PRECISION;
        res += xi * 0x289286e0fce002;
        xi = (xi * _x) >> PRECISION;
        res += xi * 0x1b0c59eb53400;
        xi = (xi * _x) >> PRECISION;
        res += xi * 0x114f95b55400;
        xi = (xi * _x) >> PRECISION;
        res += xi * 0xaa7210d200;
        xi = (xi * _x) >> PRECISION;
        res += xi * 0x650139600;
        xi = (xi * _x) >> PRECISION;
        res += xi * 0x39b78e80;
        xi = (xi * _x) >> PRECISION;
        res += xi * 0x1fd8080;
        xi = (xi * _x) >> PRECISION;
        res += xi * 0x10fbc0;
        xi = (xi * _x) >> PRECISION;
        res += xi * 0x8c40;
        xi = (xi * _x) >> PRECISION;
        res += xi * 0x462;
        xi = (xi * _x) >> PRECISION;
        res += xi * 0x22;

        return res / 0xde1bc4d19efcac82445da75b00000000;
    }
}

pragma solidity ^0.4.11;
import './SafeMath.sol';
import './IBancorFormula.sol';

/*
    Open issues:
    - The formula is not yet super accurate, especially for very small/very high ratios
    - Possibly support dynamic precision in the future
*/

contract BancorFormula is IBancorFormula, SafeMath {

    uint8 constant PRECISION   = 32;  // fractional bits
    uint256 constant FIXED_ONE = uint256(1) << PRECISION; // 0x100000000
    uint256 constant FIXED_TWO = uint256(2) << PRECISION; // 0x200000000
    uint256 constant MAX_VAL   = uint256(1) << (256 - PRECISION); // 0x0000000100000000000000000000000000000000000000000000000000000000
    string public version = '0.1';

    function BancorFormula() {
    }

    /**
        @dev given a token supply, reserve, CRR and a deposit amount (in the reserve token), calculates the return for a given change (in the main token)

        Formula:
        Return = _supply * ((1 + _depositAmount / _reserveBalance) ^ (_reserveRatio / 100) - 1)

        @param _supply             token total supply
        @param _reserveBalance     total reserve
        @param _reserveRatio       constant reserve ratio, 1-100
        @param _depositAmount      deposit amount, in reserve token

        @return purchase return amount
    */
    function calculatePurchaseReturn(uint256 _supply, uint256 _reserveBalance, uint16 _reserveRatio, uint256 _depositAmount) public constant returns (uint256) {
        // validate input
        require(_supply != 0 && _reserveBalance != 0 && _reserveRatio > 0 && _reserveRatio <= 100);

        // special case for 0 deposit amount
        if (_depositAmount == 0)
            return 0;

        uint256 baseN = safeAdd(_depositAmount, _reserveBalance);
        uint256 temp;

        // special case if the CRR = 100
        if (_reserveRatio == 100) {
            temp = safeMul(_supply, baseN) / _reserveBalance;
            return safeSub(temp, _supply);
        }

        uint256 resN = power(baseN, _reserveBalance, _reserveRatio, 100);

        temp = safeMul(_supply, resN) / FIXED_ONE;

        return safeSub(temp, _supply);
     }

    /**
        @dev given a token supply, reserve, CRR and a sell amount (in the main token), calculates the return for a given change (in the reserve token)

        Formula:
        Return = _reserveBalance * (1 - (1 - _sellAmount / _supply) ^ (1 / (_reserveRatio / 100)))

        @param _supply             token total supply
        @param _reserveBalance     total reserve
        @param _reserveRatio       constant reserve ratio, 1-100
        @param _sellAmount         sell amount, in the token itself

        @return sale return amount
    */
    function calculateSaleReturn(uint256 _supply, uint256 _reserveBalance, uint16 _reserveRatio, uint256 _sellAmount) public constant returns (uint256) {
        // validate input
        require(_supply != 0 && _reserveBalance != 0 && _reserveRatio > 0 && _reserveRatio <= 100 && _sellAmount <= _supply);

        // special case for 0 sell amount
        if (_sellAmount == 0)
            return 0;

        uint256 baseN = safeSub(_supply, _sellAmount);
        uint256 temp1;
        uint256 temp2;

        // special case if the CRR = 100
        if (_reserveRatio == 100) {
            temp1 = safeMul(_reserveBalance, _supply);
            temp2 = safeMul(_reserveBalance, baseN);
            return safeSub(temp1, temp2) / _supply;
        }

        // special case for selling the entire supply
        if (_sellAmount == _supply)
            return _reserveBalance;

        uint256 resN = power(_supply, baseN, 100, _reserveRatio);

        temp1 = safeMul(_reserveBalance, resN);
        temp2 = safeMul(_reserveBalance, FIXED_ONE);

        return safeSub(temp1, temp2) / resN;
    }

    /**
        @dev Calculate (_baseN / _baseD) ^ (_expN / _expD)
        Returns result upshifted by PRECISION

        This method is overflow-safe
    */
    function power(uint256 _baseN, uint256 _baseD, uint32 _expN, uint32 _expD) constant returns (uint256 resN) {
        uint256 logbase = ln(_baseN, _baseD);
        // Not using safeDiv here, since safeDiv protects against
        // precision loss. It's unavoidable, however
        // Both `ln` and `fixedExp` are overflow-safe.
        resN = fixedExp(safeMul(logbase, _expN) / _expD);
        return resN;
	}

    /**
        input range:
            - numerator: [1, uint256_max >> PRECISION]
            - denominator: [1, uint256_max >> PRECISION]
        output range:
            [0, 0x9b43d4f8d6]

        This method asserts outside of bounds

    */
    function ln(uint256 _numerator, uint256 _denominator) public constant returns (uint256) {
        // denominator > numerator: less than one yields negative values. Unsupported
        assert(_denominator <= _numerator);

        // log(1) is the lowest we can go
        assert(_denominator != 0 && _numerator != 0);

        // Upper 32 bits are scaled off by PRECISION
        assert(_numerator < MAX_VAL);
        assert(_denominator < MAX_VAL);

        return fixedLoge( (_numerator * FIXED_ONE) / _denominator);
    }

    /**
        input range:
            [0x100000000,uint256_max]
        output range:
            [0, 0x9b43d4f8d6]

        This method asserts outside of bounds

    */
    function fixedLoge(uint256 _x) constant returns (uint256 logE) {
        /*
        Since `fixedLog2_min` output range is max `0xdfffffffff`
        (40 bits, or 5 bytes), we can use a very large approximation
        for `ln(2)`. This one is used since it's the max accuracy
        of Python `ln(2)`

        0xb17217f7d1cf78 = ln(2) * (1 << 56)

        */
        //Cannot represent negative numbers (below 1)
        assert(_x >= FIXED_ONE);

        uint256 log2 = fixedLog2(_x);
        logE = (log2 * 0xb17217f7d1cf78) >> 56;
    }

    /**
        Returns log2(x >> 32) << 32 [1]
        So x is assumed to be already upshifted 32 bits, and
        the result is also upshifted 32 bits.

        [1] The function returns a number which is lower than the
        actual value

        input-range :
            [0x100000000,uint256_max]
        output-range:
            [0,0xdfffffffff]

        This method asserts outside of bounds

    */
    function fixedLog2(uint256 _x) constant returns (uint256) {
        // Numbers below 1 are negative.
        assert( _x >= FIXED_ONE);

        uint256 hi = 0;
        while (_x >= FIXED_TWO) {
            _x >>= 1;
            hi += FIXED_ONE;
        }

        for (uint8 i = 0; i < PRECISION; ++i) {
            _x = (_x * _x) / FIXED_ONE;
            if (_x >= FIXED_TWO) {
                _x >>= 1;
                hi += uint256(1) << (PRECISION - 1 - i);
            }
        }

        return hi;
    }

    /**
        fixedExp is a 'protected' version of `fixedExpUnsafe`, which
        asserts instead of overflows
    */
    function fixedExp(uint256 _x) constant returns (uint256) {
        assert(_x <= 0x386bfdba29);
        return fixedExpUnsafe(_x);
    }

    /**
        fixedExp
        Calculates e^x according to maclauren summation:

        e^x = 1+x+x^2/2!...+x^n/n!

        and returns e^(x>>32) << 32, that is, upshifted for accuracy

        Input range:
            - Function ok at    <= 242329958953
            - Function fails at >= 242329958954

        This method is is visible for testcases, but not meant for direct use.

        The values in this method been generated via the following python snippet:

        def calculateFactorials():
            """Method to print out the factorials for fixedExp"""

            ni = []
            ni.append( 295232799039604140847618609643520000000) # 34!
            ITERATIONS = 34
            for n in range( 1,  ITERATIONS,1 ) :
                ni.append(math.floor(ni[n - 1] / n))
            print( "\n        ".join(["xi = (xi * _x) >> PRECISION;\n        res += xi * %s;" % hex(int(x)) for x in ni]))

    */
    function fixedExpUnsafe(uint256 _x) constant returns (uint256) {

        uint256 xi = FIXED_ONE;
        uint256 res = 0xde1bc4d19efcac82445da75b00000000 * xi;

        xi = (xi * _x) >> PRECISION;
        res += xi * 0xde1bc4d19efcb0000000000000000000;
        xi = (xi * _x) >> PRECISION;
        res += xi * 0x6f0de268cf7e58000000000000000000;
        xi = (xi * _x) >> PRECISION;
        res += xi * 0x2504a0cd9a7f72000000000000000000;
        xi = (xi * _x) >> PRECISION;
        res += xi * 0x9412833669fdc800000000000000000;
        xi = (xi * _x) >> PRECISION;
        res += xi * 0x1d9d4d714865f500000000000000000;
        xi = (xi * _x) >> PRECISION;
        res += xi * 0x4ef8ce836bba8c0000000000000000;
        xi = (xi * _x) >> PRECISION;
        res += xi * 0xb481d807d1aa68000000000000000;
        xi = (xi * _x) >> PRECISION;
        res += xi * 0x16903b00fa354d000000000000000;
        xi = (xi * _x) >> PRECISION;
        res += xi * 0x281cdaac677b3400000000000000;
        xi = (xi * _x) >> PRECISION;
        res += xi * 0x402e2aad725eb80000000000000;
        xi = (xi * _x) >> PRECISION;
        res += xi * 0x5d5a6c9f31fe24000000000000;
        xi = (xi * _x) >> PRECISION;
        res += xi * 0x7c7890d442a83000000000000;
        xi = (xi * _x) >> PRECISION;
        res += xi * 0x9931ed540345280000000000;
        xi = (xi * _x) >> PRECISION;
        res += xi * 0xaf147cf24ce150000000000;
        xi = (xi * _x) >> PRECISION;
        res += xi * 0xbac08546b867d000000000;
        xi = (xi * _x) >> PRECISION;
        res += xi * 0xbac08546b867d00000000;
        xi = (xi * _x) >> PRECISION;
        res += xi * 0xafc441338061b8000000;
        xi = (xi * _x) >> PRECISION;
        res += xi * 0x9c3cabbc0056e000000;
        xi = (xi * _x) >> PRECISION;
        res += xi * 0x839168328705c80000;
        xi = (xi * _x) >> PRECISION;
        res += xi * 0x694120286c04a0000;
        xi = (xi * _x) >> PRECISION;
        res += xi * 0x50319e98b3d2c400;
        xi = (xi * _x) >> PRECISION;
        res += xi * 0x3a52a1e36b82020;
        xi = (xi * _x) >> PRECISION;
        res += xi * 0x289286e0fce002;
        xi = (xi * _x) >> PRECISION;
        res += xi * 0x1b0c59eb53400;
        xi = (xi * _x) >> PRECISION;
        res += xi * 0x114f95b55400;
        xi = (xi * _x) >> PRECISION;
        res += xi * 0xaa7210d200;
        xi = (xi * _x) >> PRECISION;
        res += xi * 0x650139600;
        xi = (xi * _x) >> PRECISION;
        res += xi * 0x39b78e80;
        xi = (xi * _x) >> PRECISION;
        res += xi * 0x1fd8080;
        xi = (xi * _x) >> PRECISION;
        res += xi * 0x10fbc0;
        xi = (xi * _x) >> PRECISION;
        res += xi * 0x8c40;
        xi = (xi * _x) >> PRECISION;
        res += xi * 0x462;
        xi = (xi * _x) >> PRECISION;
        res += xi * 0x22;

        return res / 0xde1bc4d19efcac82445da75b00000000;
    }
}


Added a temporary check about winning faction while the battle is in progress;

/*******************************************************************************
**************************     BATTLE CONTRACT v1    ***************************
********************************************************************************

Battle smart contract is a platform/ecosystem for gaming built on top of a
decentralized smart contract, allowing anyone to use a Warrior tokens: entities
which exists on the Ethereum Network, which can be traded or used to enter the
battle with other Warrior tokens holders, for profit or just for fun!

********************************************************************************
**************************           RULES           ***************************
********************************************************************************

- This first battle contract accepts Persians, Spartans (300 Tokens), Immortals
  and Athenians as warriors.
- Every warrior token has a proper value in **Battle Point (BP)** that represent
  his strength on the battle contract.
- Persians and Immortals represent the Persian faction, Spartans and Athenians
  the Greek one.
- During the first phase players send tokens to the battle contract
  (NOTE: before calling the proper contract's function that assigning warriors
  to the battlefiled, players NEED TO CALL APPROVE on their token contract to
  allow Battle contract to move their tokens.
- Once sent, troops can't be retired form the battlefield
- The battle will last for several days
- When the battle period is over, following results can happpen:
    -- When the battle ends in a draw:
        (*) 10% of main troops of both sides lie on the ground
        (*) 90% of them can be retrieved by each former owner
        (*) No slaves are assigned
    -- When the battle ends with a winning factions:
        (*) 10% of main troops of both sides lie on the ground
        (*) 90% of them can be retrieved by each former owner
        (*) Surviving warriors of the loosing faction are assigned as slaves
            to winners
        (*) Slaves are computed based on the BP contributed by each sender
- Persians and Spartans are main troops.
- Immortals and Athenians are support troops: there will be no casualties in
  their row, and they will be retrieved without losses by original senders.
- Only Persians and Spartans can be slaves. Immortals and Athenians WILL NOT
  be sent back as slaves to winners.

********************************************************************************
**************************      TOKEN ADDRESSES      ***************************
********************************************************************************

        0xaEc98A708810414878c3BCDF46Aad31dEd4a4557      Persians
        0x22E5F62D0FA19974749faa194e3d3eF6d89c08d7      Immortals
        0x163733bcc28dbf26B41a8CfA83e369b5B3af741b      Spartans
        0x17052d51E954592C1046320c2371AbaB6C73Ef10      Athenians

*******************************************************************************/
pragma solidity ^0.4.15;

import "./TokenERC20.sol";
import "./Timed.sol";
import "./SafeMathLib.sol";
import "./Upgradable.sol";

contract Battle is Timed, Upgradable {
    using SafeMathLib for uint;

    uint    public constant MAX_PERSIANS            = 300000 * 10**18;  // 300.000
    uint    public constant MAX_SPARTANS            = 300 * 10**18;     // 300
    uint    public constant MAX_IMMORTALS           = 100;              // 100
    uint    public constant MAX_ATHENIANS           = 100 * 10**18;     // 100

    uint    public constant WAD                     = 10**18;           // Common decimal positions
    uint8   public constant BP_PERSIAN              = 1;                // Each Persian worths 1 Battle Point
    uint8   public constant BP_IMMORTAL             = 100;              // Each Immortal worths 100 Battle Points
    uint16  public constant BP_SPARTAN              = 1000;             // Each Spartan worths 1000 Battle Points
    uint8   public constant BP_ATHENIAN             = 100;              // Each Athenians worths 100 Battle Points

    uint8   public constant BATTLE_POINT_DECIMALS   = 18;
    uint8   public constant BATTLE_CASUALTIES       = 10;               // Percentage of Persian and Spartan casualties

    address public persians;                                            // Address of the Persian Tokens
    address public immortals;                                           // Address of the Immortal Tokens
    address public spartans;                                            // Address of the 300 Tokens
    address public athenians;                                           // Address of the Athenian Tokens

    mapping (address => mapping (address => uint))   public  warriorsByPlayer;               // Troops currently allocated by each player
    mapping (address => uint)                        public  warriorsOnTheBattlefield;       // Total troops fighting in the battle

    event WarriorsAssignedToBattlefield (address indexed _from, address _faction, uint _battlePointsIncrementForecast);
    event WarriorsBackToHome            (address indexed _to, address _faction, uint _survivedWarriors);

    function Battle(uint _startTime, uint _life, uint8 _avarageBlockTime, address _persians, address _immortals, address _spartans, address _athenians) Timed(_startTime, _life, _avarageBlockTime) Upgradable("1.0.0") {
        persians = _persians;
        immortals = _immortals;
        spartans = _spartans;
        athenians = _athenians;
    }

    /**** PHASE #1 ******/

    function assignPersiansToBattle(uint _warriors) onlyIfInTime external returns (bool success) {
        assignWarriorsToBattle(msg.sender, persians, _warriors, MAX_PERSIANS);
        // Persians are divisible with 18 decimals and their value is 1 BP
        WarriorsAssignedToBattlefield(msg.sender, persians, _warriors / WAD);
        return true;
    }

    function assignSpartansToBattle(uint _warriors) onlyIfInTime external returns (bool success) {
        assignWarriorsToBattle(msg.sender, spartans, _warriors, MAX_SPARTANS);
        // Spartans are divisible with 18 decimals and their value is 1.000 BP
        WarriorsAssignedToBattlefield(msg.sender, spartans, (_warriors / WAD).mul(BP_SPARTAN));
        return true;
    }

    function assignImmortalsToBattle(uint _warriors) onlyIfInTime external returns (bool success) {
        assignWarriorsToBattle(msg.sender, immortals, _warriors, MAX_IMMORTALS);
        // Immortals are not divisible and their value is 100 BP
        WarriorsAssignedToBattlefield(msg.sender, immortals, _warriors.mul(BP_IMMORTAL));
        return true;
    }

    function assignAtheniansToBattle(uint _warriors) onlyIfInTime external returns (bool success) {
        assignWarriorsToBattle(msg.sender, athenians, _warriors, MAX_ATHENIANS);
        // Athenians are divisible with 18 decimals and their value is 100 BP
        WarriorsAssignedToBattlefield(msg.sender, athenians, (_warriors / WAD).mul(BP_ATHENIAN));
        return true;
    }

    /**** PHASE #2 ******/

    function redeemWarriors() onlyIfTimePassed external returns (bool success) {
        if (getPersiansBattlePoints() > getGreeksBattlePoints()) {
            // Persians won, compute slaves
            uint spartanSlaves = computeSlaves(msg.sender, spartans);
            if (spartanSlaves > 0) {
                // Send back Spartan slaves to winner
                sendWarriors(msg.sender, spartans, spartanSlaves);
            }
            // Send back Persians but casualties
            retrieveWarriors(msg.sender, persians, BATTLE_CASUALTIES);
        } else if (getPersiansBattlePoints() < getGreeksBattlePoints()) {
            //Greeks won, send back Persian slaves
            uint persianSlaves = computeSlaves(msg.sender, persians);
            if (persianSlaves > 0) {
                // Send back Persians slaves to winner
                sendWarriors(msg.sender, persians, persianSlaves);
            }
            // Send back Spartans but casualties
            retrieveWarriors(msg.sender, spartans, BATTLE_CASUALTIES);
        } else {
            // It's a draw, send back Persians and Spartans but casualties
            retrieveWarriors(msg.sender, persians, BATTLE_CASUALTIES);
            retrieveWarriors(msg.sender, spartans, BATTLE_CASUALTIES);
        }
        // Send back Immortals untouched
        retrieveWarriors(msg.sender, immortals, 0);
        // Send back Athenians untouched
        retrieveWarriors(msg.sender, athenians, 0);
        return true;
    }

    /*** PRIVATE FUNCTIONS ***/

    function assignWarriorsToBattle(address _player, address _faction, uint _warriors, uint _maxWarriors) private {
        require(warriorsOnTheBattlefield[_faction].add(_warriors) <= _maxWarriors);
        assert(TokenERC20(_faction).transferFrom(_player, address(this), _warriors));
        warriorsByPlayer[_player][_faction] = warriorsByPlayer[_player][_faction].add(_warriors);
        warriorsOnTheBattlefield[_faction] = warriorsOnTheBattlefield[_faction].add(_warriors);
    }

    function retrieveWarriors(address _player, address _faction, uint8 _deadPercentage) private {
        if (warriorsByPlayer[_player][_faction] > 0) {
            uint _warriors = warriorsByPlayer[_player][_faction];
            if (_deadPercentage > 0) {
                _warriors = _warriors.sub(_warriors.wper(_deadPercentage));
            }
            warriorsByPlayer[_player][_faction] = 0;
            sendWarriors(_player, _faction, _warriors);
            WarriorsBackToHome(_player, _faction, _warriors);
        }
    }

    function sendWarriors(address _player, address _faction, uint _warriors) private {
        assert(TokenERC20(_faction).transfer(_player, _warriors));
    }

    /*** CONSTANT FUNCTIONS AND DAPP HELPERS ***/

    function getPersiansOnTheBattlefield(address _player) constant returns (uint persiansOnTheBattlefield) {
        return warriorsByPlayer[_player][persians];
    }

    function getImmortalsOnTheBattlefield(address _player) constant returns (uint immortalsOnTheBattlefield) {
        return warriorsByPlayer[_player][immortals];
    }

    function getSpartansOnTheBattlefield(address _player) constant returns (uint spartansOnTheBattlefield) {
        return warriorsByPlayer[_player][spartans];
    }

    function getAtheniansOnTheBattlefield(address _player) constant returns (uint atheniansOnTheBattlefield) {
        return warriorsByPlayer[_player][athenians];
    }

    function getPersiansBattlePoints() constant returns (uint persiansBattlePoints) {
        return (warriorsOnTheBattlefield[persians].mul(BP_PERSIAN) + warriorsOnTheBattlefield[immortals].mul(WAD).mul(BP_IMMORTAL));
    }

    function getGreeksBattlePoints() constant returns (uint greeksBattlePoints) {
        return (warriorsOnTheBattlefield[spartans].mul(BP_SPARTAN) + warriorsOnTheBattlefield[athenians].mul(BP_ATHENIAN));
    }

    function getPersiansBattlePointsBy(address _player) constant returns (uint playerBattlePoints) {
        return (getPersiansOnTheBattlefield(_player).mul(BP_PERSIAN) + getImmortalsOnTheBattlefield(_player).mul(WAD).mul(BP_IMMORTAL));
    }

    function getGreeksBattlePointsBy(address _player) constant returns (uint playerBattlePoints) {
        return (getSpartansOnTheBattlefield(_player).mul(BP_SPARTAN) + getAtheniansOnTheBattlefield(_player).mul(BP_ATHENIAN));
    }

    function computeSlaves(address _player, address _loosingMainTroops) constant returns (uint slaves) {
        if (_loosingMainTroops == spartans) {
            return getPersiansBattlePointsBy(_player).wdiv(getPersiansBattlePoints()).wmul(getTotalSlaves(spartans));
        } else {
            return getGreeksBattlePointsBy(_player).wdiv(getGreeksBattlePoints()).wmul(getTotalSlaves(persians));
        }
    }

    function getTotalSlaves(address _faction) constant returns (uint slaves) {
        return warriorsOnTheBattlefield[_faction].sub(warriorsOnTheBattlefield[_faction].wper(BATTLE_CASUALTIES));
    }

    function isInProgress() constant returns (bool inProgress) {
        return !isTimeExpired();
    }

    function isEnded() constant returns (bool ended) {
        return isTimeExpired();
    }

    function isDraw() constant returns (bool draw) {
        return (getPersiansBattlePoints() == getGreeksBattlePoints());
    }

    function getTemporaryWinningFaction() constant returns (string temporaryWinningFaction) {
        if (isDraw()) {
            return "It's currently a draw, but the battle is still in progress!";
        }
        return getPersiansBattlePoints() > getGreeksBattlePoints() ?
            "Persians are winning, but the battle is still in progress!" : "Greeks are winning, but the battle is still in progress!";
    }

    function getWinningFaction() constant returns (string winningFaction) {
        if (isInProgress()) {
            return "The battle is still in progress";
        }
        if (isDraw()) {
            return "The battle ended in a draw!";
        }
        return getPersiansBattlePoints() > getGreeksBattlePoints() ? "Persians" : "Greeks";
    }

    /****           DEV FUNCTIONS                   *******/
    /**** REMOVE FOLLOWING FUNCTIONS BEFORE DEPLOY  *******/
    /**** REMOVE FOLLOWING FUNCTIONS BEFORE DEPLOY  *******/
    /**** REMOVE FOLLOWING FUNCTIONS BEFORE DEPLOY  *******/
    /**** REMOVE FOLLOWING FUNCTIONS BEFORE DEPLOY  *******/
    /****             REALLY!                       *******/

    function setTime(uint _startTime, uint life, uint8 _avarageBlockTime) {
        startTime = _startTime;
        endTime = _startTime + life;
        avarageBlockTime = _avarageBlockTime;
    }

    event Debug (uint value);
}

/*******************************************************************************
**************************     BATTLE CONTRACT v1    ***************************
********************************************************************************

Battle smart contract is a platform/ecosystem for gaming built on top of a
decentralized smart contract, allowing anyone to use a Warrior tokens: entities
which exists on the Ethereum Network, which can be traded or used to enter the
battle with other Warrior tokens holders, for profit or just for fun!

********************************************************************************
**************************           RULES           ***************************
********************************************************************************

- This first battle contract accepts Persians, Spartans (300 Tokens), Immortals
  and Athenians as warriors.
- Every warrior token has a proper value in **Battle Point (BP)** that represent
  his strength on the battle contract.
- Persians and Immortals represent the Persian faction, Spartans and Athenians
  the Greek one.
- During the first phase players send tokens to the battle contract
  (NOTE: before calling the proper contract's function that assigning warriors
  to the battlefiled, players NEED TO CALL APPROVE on their token contract to
  allow Battle contract to move their tokens.
- Once sent, troops can't be retired form the battlefield
- The battle will last for several days
- When the battle period is over, following results can happpen:
    -- When the battle ends in a draw:
        (*) 10% of main troops of both sides lie on the ground
        (*) 90% of them can be retrieved by each former owner
        (*) No slaves are assigned
    -- When the battle ends with a winning factions:
        (*) 10% of main troops of both sides lie on the ground
        (*) 90% of them can be retrieved by each former owner
        (*) Surviving warriors of the loosing faction are assigned as slaves
            to winners
        (*) Slaves are computed based on the BP contributed by each sender
- Persians and Spartans are main troops.
- Immortals and Athenians are support troops: there will be no casualties in
  their row, and they will be retrieved without losses by original senders.
- Only Persians and Spartans can be slaves. Immortals and Athenians WILL NOT
  be sent back as slaves to winners.

********************************************************************************
**************************      TOKEN ADDRESSES      ***************************
********************************************************************************

        0xaEc98A708810414878c3BCDF46Aad31dEd4a4557      Persians
        0x22E5F62D0FA19974749faa194e3d3eF6d89c08d7      Immortals
        0x163733bcc28dbf26B41a8CfA83e369b5B3af741b      Spartans
        0x17052d51E954592C1046320c2371AbaB6C73Ef10      Athenians

*******************************************************************************/
pragma solidity ^0.4.15;

import "./TokenERC20.sol";
import "./Timed.sol";
import "./SafeMathLib.sol";
import "./Upgradable.sol";

contract Battle is Timed, Upgradable {
    using SafeMathLib for uint;

    uint    public constant MAX_PERSIANS            = 300000 * 10**18;  // 300.000
    uint    public constant MAX_SPARTANS            = 300 * 10**18;     // 300
    uint    public constant MAX_IMMORTALS           = 100;              // 100
    uint    public constant MAX_ATHENIANS           = 100 * 10**18;     // 100

    uint    public constant WAD                     = 10**18;           // Common decimal positions
    uint8   public constant BP_PERSIAN              = 1;                // Each Persian worths 1 Battle Point
    uint8   public constant BP_IMMORTAL             = 100;              // Each Immortal worths 100 Battle Points
    uint16  public constant BP_SPARTAN              = 1000;             // Each Spartan worths 1000 Battle Points
    uint8   public constant BP_ATHENIAN             = 100;              // Each Athenians worths 100 Battle Points

    uint8   public constant BATTLE_POINT_DECIMALS   = 18;
    uint8   public constant BATTLE_CASUALTIES       = 10;               // Percentage of Persian and Spartan casualties

    address public persians;                                            // Address of the Persian Tokens
    address public immortals;                                           // Address of the Immortal Tokens
    address public spartans;                                            // Address of the 300 Tokens
    address public athenians;                                           // Address of the Athenian Tokens

    mapping (address => mapping (address => uint))   public  warriorsByPlayer;               // Troops currently allocated by each player
    mapping (address => uint)                        public  warriorsOnTheBattlefield;       // Total troops fighting in the battle

    event WarriorsAssignedToBattlefield (address indexed _from, address _faction, uint _battlePointsIncrementForecast);
    event WarriorsBackToHome            (address indexed _to, address _faction, uint _survivedWarriors);

    function Battle(uint _startTime, uint _life, uint8 _avarageBlockTime, address _persians, address _immortals, address _spartans, address _athenians) Timed(_startTime, _life, _avarageBlockTime) Upgradable("1.0.0") {
        persians = _persians;
        immortals = _immortals;
        spartans = _spartans;
        athenians = _athenians;
    }

    /**** PHASE #1 ******/

    function assignPersiansToBattle(uint _warriors) onlyIfInTime external returns (bool success) {
        assignWarriorsToBattle(msg.sender, persians, _warriors, MAX_PERSIANS);
        // Persians are divisible with 18 decimals and their value is 1 BP
        WarriorsAssignedToBattlefield(msg.sender, persians, _warriors / WAD);
        return true;
    }

    function assignSpartansToBattle(uint _warriors) onlyIfInTime external returns (bool success) {
        assignWarriorsToBattle(msg.sender, spartans, _warriors, MAX_SPARTANS);
        // Spartans are divisible with 18 decimals and their value is 1.000 BP
        WarriorsAssignedToBattlefield(msg.sender, spartans, (_warriors / WAD).mul(BP_SPARTAN));
        return true;
    }

    function assignImmortalsToBattle(uint _warriors) onlyIfInTime external returns (bool success) {
        assignWarriorsToBattle(msg.sender, immortals, _warriors, MAX_IMMORTALS);
        // Immortals are not divisible and their value is 100 BP
        WarriorsAssignedToBattlefield(msg.sender, immortals, _warriors.mul(BP_IMMORTAL));
        return true;
    }

    function assignAtheniansToBattle(uint _warriors) onlyIfInTime external returns (bool success) {
        assignWarriorsToBattle(msg.sender, athenians, _warriors, MAX_ATHENIANS);
        // Athenians are divisible with 18 decimals and their value is 100 BP
        WarriorsAssignedToBattlefield(msg.sender, athenians, (_warriors / WAD).mul(BP_ATHENIAN));
        return true;
    }

    /**** PHASE #2 ******/

    function redeemWarriors() onlyIfTimePassed external returns (bool success) {
        if (getPersiansBattlePoints() > getGreeksBattlePoints()) {
            // Persians won, compute slaves
            uint spartanSlaves = computeSlaves(msg.sender, spartans);
            if (spartanSlaves > 0) {
                // Send back Spartan slaves to winner
                sendWarriors(msg.sender, spartans, spartanSlaves);
            }
            // Send back Persians but casualties
            retrieveWarriors(msg.sender, persians, BATTLE_CASUALTIES);
        } else if (getPersiansBattlePoints() < getGreeksBattlePoints()) {
            //Greeks won, send back Persian slaves
            uint persianSlaves = computeSlaves(msg.sender, persians);
            if (persianSlaves > 0) {
                // Send back Persians slaves to winner
                sendWarriors(msg.sender, persians, persianSlaves);
            }
            // Send back Spartans but casualties
            retrieveWarriors(msg.sender, spartans, BATTLE_CASUALTIES);
        } else {
            // It's a draw, send back Persians and Spartans but casualties
            retrieveWarriors(msg.sender, persians, BATTLE_CASUALTIES);
            retrieveWarriors(msg.sender, spartans, BATTLE_CASUALTIES);
        }
        // Send back Immortals untouched
        retrieveWarriors(msg.sender, immortals, 0);
        // Send back Athenians untouched
        retrieveWarriors(msg.sender, athenians, 0);
        return true;
    }

    /*** PRIVATE FUNCTIONS ***/

    function assignWarriorsToBattle(address _player, address _faction, uint _warriors, uint _maxWarriors) private {
        require(warriorsOnTheBattlefield[_faction].add(_warriors) <= _maxWarriors);
        assert(TokenERC20(_faction).transferFrom(_player, address(this), _warriors));
        warriorsByPlayer[_player][_faction] = warriorsByPlayer[_player][_faction].add(_warriors);
        warriorsOnTheBattlefield[_faction] = warriorsOnTheBattlefield[_faction].add(_warriors);
    }

    function retrieveWarriors(address _player, address _faction, uint8 _deadPercentage) private {
        if (warriorsByPlayer[_player][_faction] > 0) {
            uint _warriors = warriorsByPlayer[_player][_faction];
            if (_deadPercentage > 0) {
                _warriors = _warriors.sub(_warriors.wper(_deadPercentage));
            }
            warriorsByPlayer[_player][_faction] = 0;
            sendWarriors(_player, _faction, _warriors);
            WarriorsBackToHome(_player, _faction, _warriors);
        }
    }

    function sendWarriors(address _player, address _faction, uint _warriors) private {
        assert(TokenERC20(_faction).transfer(_player, _warriors));
    }

    /*** CONSTANT FUNCTIONS AND DAPP HELPERS ***/

    function getPersiansOnTheBattlefield(address _player) constant returns (uint persiansOnTheBattlefield) {
        return warriorsByPlayer[_player][persians];
    }

    function getImmortalsOnTheBattlefield(address _player) constant returns (uint immortalsOnTheBattlefield) {
        return warriorsByPlayer[_player][immortals];
    }

    function getSpartansOnTheBattlefield(address _player) constant returns (uint spartansOnTheBattlefield) {
        return warriorsByPlayer[_player][spartans];
    }

    function getAtheniansOnTheBattlefield(address _player) constant returns (uint atheniansOnTheBattlefield) {
        return warriorsByPlayer[_player][athenians];
    }

    function getPersiansBattlePoints() constant returns (uint persiansBattlePoints) {
        return (warriorsOnTheBattlefield[persians].mul(BP_PERSIAN) + warriorsOnTheBattlefield[immortals].mul(WAD).mul(BP_IMMORTAL));
    }

    function getGreeksBattlePoints() constant returns (uint greeksBattlePoints) {
        return (warriorsOnTheBattlefield[spartans].mul(BP_SPARTAN) + warriorsOnTheBattlefield[athenians].mul(BP_ATHENIAN));
    }

    function getPersiansBattlePointsBy(address _player) constant returns (uint playerBattlePoints) {
        return (getPersiansOnTheBattlefield(_player).mul(BP_PERSIAN) + getImmortalsOnTheBattlefield(_player).mul(WAD).mul(BP_IMMORTAL));
    }

    function getGreeksBattlePointsBy(address _player) constant returns (uint playerBattlePoints) {
        return (getSpartansOnTheBattlefield(_player).mul(BP_SPARTAN) + getAtheniansOnTheBattlefield(_player).mul(BP_ATHENIAN));
    }

    function computeSlaves(address _player, address _loosingMainTroops) constant returns (uint slaves) {
        if (_loosingMainTroops == spartans) {
            return getPersiansBattlePointsBy(_player).wdiv(getPersiansBattlePoints()).wmul(getTotalSlaves(spartans));
        } else {
            return getGreeksBattlePointsBy(_player).wdiv(getGreeksBattlePoints()).wmul(getTotalSlaves(persians));
        }
    }

    function getTotalSlaves(address _faction) constant returns (uint slaves) {
        return warriorsOnTheBattlefield[_faction].sub(warriorsOnTheBattlefield[_faction].wper(BATTLE_CASUALTIES));
    }

    function isInProgress() constant returns (bool inProgress) {
        return !isTimeExpired();
    }

    function isEnded() constant returns (bool ended) {
        return isTimeExpired();
    }

    function isDraw() constant returns (bool draw) {
        return (getPersiansBattlePoints() == getGreeksBattlePoints());
    }

    function getWinningFaction() constant returns (string winningFaction) {
        if (isInProgress()) {
            return "The battle is still in progress";
        }
        if (isDraw()) {
            return "The battle ended in a draw!";
        }
        return getPersiansBattlePoints() > getGreeksBattlePoints() ? "Persians" : "Greeks";
    }

    /****           DEV FUNCTIONS                   *******/
    /**** REMOVE FOLLOWING FUNCTIONS BEFORE DEPLOY  *******/
    /**** REMOVE FOLLOWING FUNCTIONS BEFORE DEPLOY  *******/
    /**** REMOVE FOLLOWING FUNCTIONS BEFORE DEPLOY  *******/
    /**** REMOVE FOLLOWING FUNCTIONS BEFORE DEPLOY  *******/
    /****             REALLY!                       *******/

    function setTime(uint _startTime, uint life, uint8 _avarageBlockTime) {
        startTime = _startTime;
        endTime = _startTime + life;
        avarageBlockTime = _avarageBlockTime;
    }

    event Debug (uint value);
}


add rule contract

add rule contract

contract token {
    string public assetName;
    address public daoAddr;
    address public owner;
    mapping (address => uint) public tokenBalanceOf;
    DAO daoToken;

    /*Initial */
    function token(string _assetName) {
        assetName = _assetName;
        owner = msg.sender;
    }

    /* DAO functions */
    function emission(address _agentContrAddr, uint _amount) returns(bool result) {
        if(msg.sender==daoAddr || msg.sender==owner)
        {
            tokenBalanceOf[_agentContrAddr] += _amount;
            return true;
        }
        return false;
    }

    function burn(address _agentContrAddr, uint _amount) returns(bool result) {
        if(msg.sender==daoAddr && tokenBalanceOf[_agentContrAddr]>=_amount)
        {
            tokenBalanceOf[_agentContrAddr] -= _amount;
            return true;
        }
        return false;
    }

    function setDaoAddr(address _daoAddr) {
        DAO dao = DAO(_daoAddr);
        address agentContrAddr = dao.agentContractOf(msg.sender);
        if(dao.agentActiveOf(agentContrAddr) || dao.daoFounder() == msg.sender) {
            daoAddr = _daoAddr;
        }
    }

    /* Agent function */
    function sendToken(address receiver, uint amount) returns(bool result) {
        if (tokenBalanceOf[msg.sender] < amount) {return false;}
        tokenBalanceOf[msg.sender] -= amount;
        tokenBalanceOf[receiver] += amount;
        return true;
    }
}

contract DAO {
    address public daoFounder;
    address public daoFounderContr;
    address public daoMarketContr;
    address public daoGovermentContr;
    bool public initialization;
    uint public creditAmount;
    uint public sharesAmount;
    uint public creditTurn;
    uint public numAgents;

    token public daoShares;
    token public daoCredits;

    /* Assets data */
    Asset[] public assetsList;
    mapping (address => uint) public assetDataOf;
    mapping (address => bool) public assetExistOf;
    struct Asset {
        address assetAddr;
    }

    /* Agents data */
    Agent[] public agentsList;
    mapping (address => uint) public agentDataOf;
    mapping (address => bool) public agentActiveOf;
    mapping (address => address) public agentContractOf;
    struct Agent {
        address agentContrAddr;
        uint joinData;
    }

    function DAO(token _shares, token _credits, agent _daoFounderContr, market _daoMarketContr, goverment _daoGovermentContr) {
        daoFounder = msg.sender;
        daoShares = token(_shares);
        daoCredits = token(_credits);
        daoFounderContr = _daoFounderContr;
        daoMarketContr = _daoMarketContr;
        daoGovermentContr = _daoGovermentContr;
    }

    function setMarket(address _daoMarketContr) {
        if(msg.sender == daoFounder) {
        	daoMarketContr = _daoMarketContr;
        }
    }

    function initializationDaoBalances(uint _founderSharesAmount, uint _founderCreditsAmount) returns (bool result) {
        if(!initialization) {
			daoShares.emission(daoFounderContr, _founderSharesAmount);
			sharesAmount = _founderSharesAmount;
			daoCredits.emission(daoFounderContr, _founderCreditsAmount);
			creditAmount = _founderCreditsAmount;
			initialization = true;
			return true;
        }
    }

    function daoEfficiency() returns (uint daoEfficiency) {
        daoEfficiency = creditTurn*100/creditAmount;
    }

    function daoShareCost() returns (uint shareCost) {
        shareCost = creditTurn/sharesAmount;
    }

    function daoCreditPower() returns (uint creditPower) {
        creditPower = sharesAmount*100/creditTurn;
    }

    function daoShareSale(uint _shareAmount) returns (uint creditReward) {
        if(daoShares.tokenBalanceOf(msg.sender)>=_shareAmount) {
            creditReward = daoShareCost()*_shareAmount;
            daoCredits.emission(msg.sender, creditReward);
            daoShares.burn(msg.sender, _shareAmount);
        }
    }

    function daoShareBuy(uint _creditAmount) returns (uint shares) {
        if(daoCredits.tokenBalanceOf(msg.sender)>=_creditAmount) {
            shares = daoCreditPower()*_creditAmount;
            daoShares.emission(msg.sender, shares);
            daoCredits.burn(msg.sender, _creditAmount);
        }
    }

    function daoSharesEmission(address _agentContrAddr, uint _sharesAmount) {
        daoShares.emission(_agentContrAddr, _sharesAmount);
    }

    function daoCreditEmission(address _agentContrAddr, uint _creditsAmount) {
        daoCredits.emission(_agentContrAddr, _creditsAmount);
    }

    function setAgent(address _agentContAddr) returns(uint agentID) {
        if(daoShares.tokenBalanceOf(msg.sender)>0) {
            agentID = agentsList.length++;
            Agent a = agentsList[agentID];
            a.agentContrAddr = _agentContAddr;
            a.joinData = now;
            uint newAgentSharesAmount;
            numAgents = agentID + 1;
            newAgentSharesAmount = sharesAmount/numAgents*daoEfficiency();
            daoShares.emission(_agentContAddr, newAgentSharesAmount);
            agentDataOf[_agentContAddr] = agentID;
            agentActiveOf[_agentContAddr] = true;
            agent Agn = agent(_agentContAddr);
            agentContractOf[Agn.agentAddr()] = _agentContAddr;
            return agentID;
        }
    }

    function setAssets(address _assetAddr) returns(uint assetID) {
        if (agentActiveOf[msg.sender] == true) {
            assetID = assetsList.length++;
            Asset a = assetsList[assetID];
            a.assetAddr = _assetAddr;
            assetDataOf[_assetAddr] = assetID;
            assetExistOf[_assetAddr] = true;
            return assetID;
        }
    }
}

contract agent {
    address public agentAddr;
    address controlAddr;
    address daoAddr;
    DAO public dao;

    /* Agents contract list*/

    AgentContract[] public agentContractList;
    struct AgentContract {
        address agentContractAddr;
        string abi;
        string desc;
        bool active;
    }

    modifier controlCheck { if (msg.sender == controlAddr) _ }

    function agent() {
        agentAddr = msg.sender;
        controlAddr = msg.sender;
    }

    function addAsset(address _tokenAddr) {
        if (msg.sender == agentAddr) {
			dao.setAssets(_tokenAddr);
		}
    }

    function sendToken(address assetAddr, address receiver, uint amount) {
        if (msg.sender == agentAddr || msg.sender == dao.daoMarketContr()) {
			token asset = token(assetAddr);
			asset.sendToken(receiver, amount);
		}
    }

    function setDao(address _daoAddr) {
        if(msg.sender == agentAddr) {
        	daoAddr = _daoAddr;
			dao = DAO(daoAddr);
        }
    }

    function setControlAddr(address _controlAddr) returns(bool result) {
        if(msg.sender == agentAddr) {
            controlAddr = _controlAddr;
        }
    }

    function setNewAgent(address _agentAddr) controlCheck returns(bool result) {
        dao.setAgent(_agentAddr);
        return true;
    }

    function setAgentContract(address _agentContractAddr, string _abi, string _desc) controlCheck returns(uint contractID) {
        contractID = agentContractList.length++;
        AgentContract a = agentContractList[contractID];
        a.agentContractAddr = _agentContractAddr;
        a.abi = _abi;
        a.desc = _desc;
        a.active = true;
        return contractID;
    }

    function inactiveAgentContract(address _agentContractAddr) controlCheck returns(bool result) {

    }
}

contract market {
    address daoAddr;
    DAO public dao;

    struct Order {
        uint orderID;
        address owner;
        uint total;
        uint unitPrice;
        uint min;
        uint step;
        bool active;
    }

    struct SaleAssetList {
        address assetAddr;
        Order[] sellOrderList;
    }

    struct BuyAssetList {
        address assetAddr;
        Order[] buyOrderList;
    }

    SaleAssetList[] public sellAssetList;
    Order[] public sellOrderList;
    mapping (address => bool) public sellExistOf;
    mapping (address => uint) public sellDataOf;

    BuyAssetList[] public buyAssetList;
    Order[] public buyOrderList;
    mapping (address => bool) public buyExistOf;
    mapping (address => uint) public buyDataOf;

    function setDao(address _daoAddr) {
		daoAddr = _daoAddr;
		dao = DAO(daoAddr);
    }

    function addSell(address _assetAddr, uint _total, uint _unitPrice, uint _min, uint _step) returns(uint sellID) {
    	address agentContrAddr = dao.agentContractOf(msg.sender);
        if (dao.agentActiveOf(agentContrAddr) && dao.assetExistOf(_assetAddr)) {
        	uint assetID;
            if (sellExistOf[_assetAddr]) {
                assetID = sellDataOf[_assetAddr];
                SaleAssetList sellAssetOrders = sellAssetList[assetID];
            } else {
            	assetID = sellAssetList.length++;
				sellExistOf[_assetAddr] = true;
                sellAssetOrders = sellAssetList[assetID];
                sellAssetOrders.assetAddr = _assetAddr;
            }
			sellID = sellAssetOrders.sellOrderList.length++;

			Order order = sellAssetOrders.sellOrderList[sellID];
			order.orderID = sellID;
			order.owner = agentContrAddr;
			order.total = _total;
			order.unitPrice = _unitPrice;
			order.min = _min;
			order.step = _step;
			order.active = true;

			return sellID;
        }
    }

    function addBuy(address _assetAddr, uint _total, uint _unitPrice, uint _min, uint _step) returns(uint buyID) {
    	address agentContrAddr = dao.agentContractOf(msg.sender);
        if (dao.agentActiveOf(agentContrAddr) && dao.assetExistOf(_assetAddr)) {
        	uint assetID;
            if (buyExistOf[_assetAddr]) {
                assetID = buyDataOf[_assetAddr];
                BuyAssetList buyAssetOrders = buyAssetList[assetID];
            } else {
            	assetID = buyAssetList.length++;
				buyExistOf[_assetAddr] = true;
                buyAssetOrders = buyAssetList[assetID];
                buyAssetOrders.assetAddr = _assetAddr;
            }
			buyID = buyAssetOrders.buyOrderList.length++;

			Order order = buyAssetOrders.buyOrderList[buyID];
			order.orderID = buyID;
			order.owner = agentContrAddr;
			order.total = _total;
			order.unitPrice = _unitPrice;
			order.min = _min;
			order.step = _step;
			order.active = true;

			return buyID;
        }
    }

    function removeSell(address _assetAddr, uint _orderID) returns(bool result) {
    	if (sellExistOf[_assetAddr]) {
    		address agentContrAddr = dao.agentContractOf(msg.sender);
			uint assetID = sellDataOf[_assetAddr];
			Order order = sellAssetList[assetID].sellOrderList[_orderID];
			if (order.owner == agentContrAddr) {
				order.active = false;
				return true;
			}
		}
		return false;
    }

    function removeBuy(address _assetAddr, uint _orderID) returns(bool result) {
    	if (buyExistOf[_assetAddr]) {
    		address agentContrAddr = dao.agentContractOf(msg.sender);
			uint assetID = buyDataOf[_assetAddr];
			Order order = buyAssetList[assetID].buyOrderList[_orderID];
			if (order.owner == agentContrAddr) {
				order.active = false;
				return true;
			}
		}
		return false;
    }

    function getSell(address _assetAddr, uint _orderID) returns(address owner, uint total, uint unitPrice, uint min, uint step, bool active) {
		if (sellExistOf[_assetAddr]) {
			uint assetID = sellDataOf[_assetAddr];
			Order order = sellAssetList[assetID].sellOrderList[_orderID];
			return (order.owner, order.total, order.unitPrice, order.min, order.step, order.active);
		}
    }

    function getBuy(address _assetAddr, uint _orderID) returns(address owner, uint total, uint unitPrice, uint min, uint step, bool active) {
		if (buyExistOf[_assetAddr]) {
			uint assetID = buyDataOf[_assetAddr];
			Order order = buyAssetList[assetID].buyOrderList[_orderID];
			return (order.owner, order.total, order.unitPrice, order.min, order.step, order.active);
		}
    }

    function BuyDeal(address _assetAddr, uint _amount, uint _orderID) returns(bool result) {
		if (sellExistOf[_assetAddr]) {
            uint assetID = sellDataOf[_assetAddr];
			Order order = sellAssetList[assetID].sellOrderList[_orderID];
			if (order.total > 0 && order.active == true && _amount >= order.min && _amount <= order.total && ((_amount / order.step) * order.step) == _amount) {
				address agent_buy_addr = dao.agentContractOf(msg.sender);
				agent agent_buy = agent(agent_buy_addr);
				agent agent_sell = agent(order.owner);

				token credit = token(dao.daoCredits());
				if (credit.tokenBalanceOf(agent_buy_addr) < (order.unitPrice * _amount)) {
					return false;
				}
				token asset = token(sellAssetList[assetID].assetAddr);
				if (asset.tokenBalanceOf(order.owner) < _amount) {
					return false;
				}

				agent_buy.sendToken(dao.daoCredits(), order.owner, (order.unitPrice * _amount));
				agent_sell.sendToken(sellAssetList[assetID].assetAddr, agent_buy_addr, _amount);

				order.total = order.total - _amount;
				if (order.total == 0) {
					order.active = false;
				}
				return true;
			}
		}
        return false;
    }

    function SellDeal(address _assetAddr, uint _amount, uint _orderID) returns(bool result) {
        if (buyExistOf[_assetAddr]) {
			uint assetID = buyDataOf[_assetAddr];
			Order order = buyAssetList[assetID].buyOrderList[_orderID];
			if (order.total > 0 && order.active == true && _amount >= order.min && _amount <= order.total && ((_amount / order.step) * order.step) == _amount) {
				address agent_sell_addr = dao.agentContractOf(msg.sender);
				agent agent_sell = agent(agent_sell_addr);
				agent agent_buy = agent(order.owner);

				token credit = token(dao.daoCredits());
				if (credit.tokenBalanceOf(order.owner) < (order.unitPrice * _amount)) {
					return false;
				}
				token asset = token(buyAssetList[assetID].assetAddr);
				if (asset.tokenBalanceOf(agent_sell_addr) < _amount) {
					return false;
				}

				agent_sell.sendToken(buyAssetList[assetID].assetAddr, order.owner, _amount);
				agent_buy.sendToken(dao.daoCredits(), agent_sell_addr, (order.unitPrice * _amount));

				order.total = order.total - _amount;
				if (order.total == 0) {
					order.active = false;
				}
				return true;
			}
		}
		return false;
    }
}

contract rule {
    address seller;
    address buyer;
    address asset;
    uint qty;
    uint fullCost;
    uint dealTimestamp;

    function execute(address _seller , address _buyer, address  _asset,  uint _qty, uint _fullCost) returns(address seller, address buyer, address asset, address qty, uint fullCost) {
    }
}

contract goverment {
    address daoAddr;

    function goverment(address _daoAddr) {
        daoAddr = _daoAddr;
    }

    /* market data */

    struct MarketDeal {
        address seller;
        address buyer;
        address asset;
        uint qty;
        uint fullCost;
        uint dealTimestamp;
    }

    MarketDeal[] public marketDeals;

    /* proposal data */

    mapping (address => uint) public sellerRulesFilterExistOf;
    mapping (address => uint) public buyerRulesFilterExistOf;
    mapping (address => uint) public assetRulesFilterExistOf;
    mapping (address => uint) public sellerRulesFilterOf;
    mapping (address => uint) public buyerRulesFilterOf;
    mapping (address => uint) public assetRulesFilterOf;

    /* proposal data */
    function setMarketDeal(address _seller , address _buyer, address  _asset,  uint _qty, uint _fullCost) returns(bool result) {
        marketDeals[marketDeals.length++] = MarketDeal({seller: _seller, buyer: _buyer, asset: _asset, qty: _qty, fullCost: _fullCost, dealTimestamp: now});
    }

    function executeRule(address _ruleAddr, uint _marketDealID) {
        rule executingRule;
        executingRule = rule(_ruleAddr);
        address seller = marketDeals[_marketDealID].seller;
        address buyer = marketDeals[_marketDealID].buyer;
        address asset = marketDeals[_marketDealID].asset;
        uint qty = marketDeals[_marketDealID].qty;
        uint fullCost = marketDeals[_marketDealID].fullCost;

        executingRule.execute(seller,buyer,asset,qty,fullCost);

    }

}

contract token {
    string public assetName;
    address public daoAddr;
    address public owner;
    mapping (address => uint) public tokenBalanceOf;
    DAO daoToken;

    /*Initial */
    function token(string _assetName) {
        assetName = _assetName;
        owner = msg.sender;
    }

    /* DAO functions */
    function emission(address _agentContrAddr, uint _amount) returns(bool result) {
        if(msg.sender==daoAddr || msg.sender==owner)
        {
            tokenBalanceOf[_agentContrAddr] += _amount;
            return true;
        }
        return false;
    }

    function burn(address _agentContrAddr, uint _amount) returns(bool result) {
        if(msg.sender==daoAddr && tokenBalanceOf[_agentContrAddr]>=_amount)
        {
            tokenBalanceOf[_agentContrAddr] -= _amount;
            return true;
        }
        return false;
    }

    function setDaoAddr(address _daoAddr) {
        DAO dao = DAO(_daoAddr);
        address agentContrAddr = dao.agentContractOf(msg.sender);
        if(dao.agentActiveOf(agentContrAddr) || dao.daoFounder() == msg.sender) {
            daoAddr = _daoAddr;
        }
    }

    /* Agent function */
    function sendToken(address receiver, uint amount) returns(bool result) {
        if (tokenBalanceOf[msg.sender] < amount) {return false;}
        tokenBalanceOf[msg.sender] -= amount;
        tokenBalanceOf[receiver] += amount;
        return true;
    }
}

contract DAO {
    address public daoFounder;
    address public daoFounderContr;
    address public daoMarketContr;
    address public daoGovermentContr;
    bool public initialization;
    uint public creditAmount;
    uint public sharesAmount;
    uint public creditTurn;
    uint public numAgents;

    token public daoShares;
    token public daoCredits;

    /* Assets data */
    Asset[] public assetsList;
    mapping (address => uint) public assetDataOf;
    mapping (address => bool) public assetExistOf;
    struct Asset {
        address assetAddr;
    }

    /* Agents data */
    Agent[] public agentsList;
    mapping (address => uint) public agentDataOf;
    mapping (address => bool) public agentActiveOf;
    mapping (address => address) public agentContractOf;
    struct Agent {
        address agentContrAddr;
        uint joinData;
    }

    function DAO(token _shares, token _credits, agent _daoFounderContr, market _daoMarketContr, goverment _daoGovermentContr) {
        daoFounder = msg.sender;
        daoShares = token(_shares);
        daoCredits = token(_credits);
        daoFounderContr = _daoFounderContr;
        daoMarketContr = _daoMarketContr;
        daoGovermentContr = _daoGovermentContr;
    }

    function setMarket(address _daoMarketContr) {
        if(msg.sender == daoFounder) {
        	daoMarketContr = _daoMarketContr;
        }
    }

    function initializationDaoBalances(uint _founderSharesAmount, uint _founderCreditsAmount) returns (bool result) {
        if(!initialization) {
			daoShares.emission(daoFounderContr, _founderSharesAmount);
			sharesAmount = _founderSharesAmount;
			daoCredits.emission(daoFounderContr, _founderCreditsAmount);
			creditAmount = _founderCreditsAmount;
			initialization = true;
			return true;
        }
    }

    function daoEfficiency() returns (uint daoEfficiency) {
        daoEfficiency = creditTurn*100/creditAmount;
    }

    function daoShareCost() returns (uint shareCost) {
        shareCost = creditTurn/sharesAmount;
    }

    function daoCreditPower() returns (uint creditPower) {
        creditPower = sharesAmount*100/creditTurn;
    }

    function daoShareSale(uint _shareAmount) returns (uint creditReward) {
        if(daoShares.tokenBalanceOf(msg.sender)>=_shareAmount) {
            creditReward = daoShareCost()*_shareAmount;
            daoCredits.emission(msg.sender, creditReward);
            daoShares.burn(msg.sender, _shareAmount);
        }
    }

    function daoShareBuy(uint _creditAmount) returns (uint shares) {
        if(daoCredits.tokenBalanceOf(msg.sender)>=_creditAmount) {
            shares = daoCreditPower()*_creditAmount;
            daoShares.emission(msg.sender, shares);
            daoCredits.burn(msg.sender, _creditAmount);
        }
    }

    function daoSharesEmission(address _agentContrAddr, uint _sharesAmount) {
        daoShares.emission(_agentContrAddr, _sharesAmount);
    }

    function daoCreditEmission(address _agentContrAddr, uint _creditsAmount) {
        daoCredits.emission(_agentContrAddr, _creditsAmount);
    }

    function setAgent(address _agentContAddr) returns(uint agentID) {
        if(daoShares.tokenBalanceOf(msg.sender)>0) {
            agentID = agentsList.length++;
            Agent a = agentsList[agentID];
            a.agentContrAddr = _agentContAddr;
            a.joinData = now;
            uint newAgentSharesAmount;
            numAgents = agentID + 1;
            newAgentSharesAmount = sharesAmount/numAgents*daoEfficiency();
            daoShares.emission(_agentContAddr, newAgentSharesAmount);
            agentDataOf[_agentContAddr] = agentID;
            agentActiveOf[_agentContAddr] = true;
            agent Agn = agent(_agentContAddr);
            agentContractOf[Agn.agentAddr()] = _agentContAddr;
            return agentID;
        }
    }

    function setAssets(address _assetAddr) returns(uint assetID) {
        if (agentActiveOf[msg.sender] == true) {
            assetID = assetsList.length++;
            Asset a = assetsList[assetID];
            a.assetAddr = _assetAddr;
            assetDataOf[_assetAddr] = assetID;
            assetExistOf[_assetAddr] = true;
            return assetID;
        }
    }
}

contract agent {
    address public agentAddr;
    address controlAddr;
    address daoAddr;
    DAO public dao;

    /* Agents contract list*/

    AgentContract[] public agentContractList;
    struct AgentContract {
        address agentContractAddr;
        string abi;
        string desc;
        bool active;
    }

    modifier controlCheck { if (msg.sender == controlAddr) _ }

    function agent() {
        agentAddr = msg.sender;
        controlAddr = msg.sender;
    }

    function addAsset(address _tokenAddr) {
        if (msg.sender == agentAddr) {
			dao.setAssets(_tokenAddr);
		}
    }

    function sendToken(address assetAddr, address receiver, uint amount) {
        if (msg.sender == agentAddr || msg.sender == dao.daoMarketContr()) {
			token asset = token(assetAddr);
			asset.sendToken(receiver, amount);
		}
    }

    function setDao(address _daoAddr) {
        if(msg.sender == agentAddr) {
        	daoAddr = _daoAddr;
			dao = DAO(daoAddr);
        }
    }

    function setControlAddr(address _controlAddr) returns(bool result) {
        if(msg.sender == agentAddr) {
            controlAddr = _controlAddr;
        }
    }

    function setNewAgent(address _agentAddr) controlCheck returns(bool result) {
        dao.setAgent(_agentAddr);
        return true;
    }

    function setAgentContract(address _agentContractAddr, string _abi, string _desc) controlCheck returns(uint contractID) {
        contractID = agentContractList.length++;
        AgentContract a = agentContractList[contractID];
        a.agentContractAddr = _agentContractAddr;
        a.abi = _abi;
        a.desc = _desc;
        a.active = true;
        return contractID;
    }

    function inactiveAgentContract(address _agentContractAddr) controlCheck returns(bool result) {

    }
}

contract market {
    address daoAddr;
    DAO public dao;

    struct Order {
        uint orderID;
        address owner;
        uint total;
        uint unitPrice;
        uint min;
        uint step;
        bool active;
    }

    struct SaleAssetList {
        address assetAddr;
        Order[] sellOrderList;
    }

    struct BuyAssetList {
        address assetAddr;
        Order[] buyOrderList;
    }

    SaleAssetList[] public sellAssetList;
    Order[] public sellOrderList;
    mapping (address => bool) public sellExistOf;
    mapping (address => uint) public sellDataOf;

    BuyAssetList[] public buyAssetList;
    Order[] public buyOrderList;
    mapping (address => bool) public buyExistOf;
    mapping (address => uint) public buyDataOf;

    function setDao(address _daoAddr) {
		daoAddr = _daoAddr;
		dao = DAO(daoAddr);
    }

    function addSell(address _assetAddr, uint _total, uint _unitPrice, uint _min, uint _step) returns(uint sellID) {
    	address agentContrAddr = dao.agentContractOf(msg.sender);
        if (dao.agentActiveOf(agentContrAddr) && dao.assetExistOf(_assetAddr)) {
        	uint assetID;
            if (sellExistOf[_assetAddr]) {
                assetID = sellDataOf[_assetAddr];
                SaleAssetList sellAssetOrders = sellAssetList[assetID];
            } else {
            	assetID = sellAssetList.length++;
				sellExistOf[_assetAddr] = true;
                sellAssetOrders = sellAssetList[assetID];
                sellAssetOrders.assetAddr = _assetAddr;
            }
			sellID = sellAssetOrders.sellOrderList.length++;

			Order order = sellAssetOrders.sellOrderList[sellID];
			order.orderID = sellID;
			order.owner = agentContrAddr;
			order.total = _total;
			order.unitPrice = _unitPrice;
			order.min = _min;
			order.step = _step;
			order.active = true;

			return sellID;
        }
    }

    function addBuy(address _assetAddr, uint _total, uint _unitPrice, uint _min, uint _step) returns(uint buyID) {
    	address agentContrAddr = dao.agentContractOf(msg.sender);
        if (dao.agentActiveOf(agentContrAddr) && dao.assetExistOf(_assetAddr)) {
        	uint assetID;
            if (buyExistOf[_assetAddr]) {
                assetID = buyDataOf[_assetAddr];
                BuyAssetList buyAssetOrders = buyAssetList[assetID];
            } else {
            	assetID = buyAssetList.length++;
				buyExistOf[_assetAddr] = true;
                buyAssetOrders = buyAssetList[assetID];
                buyAssetOrders.assetAddr = _assetAddr;
            }
			buyID = buyAssetOrders.buyOrderList.length++;

			Order order = buyAssetOrders.buyOrderList[buyID];
			order.orderID = buyID;
			order.owner = agentContrAddr;
			order.total = _total;
			order.unitPrice = _unitPrice;
			order.min = _min;
			order.step = _step;
			order.active = true;

			return buyID;
        }
    }

    function removeSell(address _assetAddr, uint _orderID) returns(bool result) {
    	if (sellExistOf[_assetAddr]) {
    		address agentContrAddr = dao.agentContractOf(msg.sender);
			uint assetID = sellDataOf[_assetAddr];
			Order order = sellAssetList[assetID].sellOrderList[_orderID];
			if (order.owner == agentContrAddr) {
				order.active = false;
				return true;
			}
		}
		return false;
    }

    function removeBuy(address _assetAddr, uint _orderID) returns(bool result) {
    	if (buyExistOf[_assetAddr]) {
    		address agentContrAddr = dao.agentContractOf(msg.sender);
			uint assetID = buyDataOf[_assetAddr];
			Order order = buyAssetList[assetID].buyOrderList[_orderID];
			if (order.owner == agentContrAddr) {
				order.active = false;
				return true;
			}
		}
		return false;
    }

    function getSell(address _assetAddr, uint _orderID) returns(address owner, uint total, uint unitPrice, uint min, uint step, bool active) {
		if (sellExistOf[_assetAddr]) {
			uint assetID = sellDataOf[_assetAddr];
			Order order = sellAssetList[assetID].sellOrderList[_orderID];
			return (order.owner, order.total, order.unitPrice, order.min, order.step, order.active);
		}
    }

    function getBuy(address _assetAddr, uint _orderID) returns(address owner, uint total, uint unitPrice, uint min, uint step, bool active) {
		if (buyExistOf[_assetAddr]) {
			uint assetID = buyDataOf[_assetAddr];
			Order order = buyAssetList[assetID].buyOrderList[_orderID];
			return (order.owner, order.total, order.unitPrice, order.min, order.step, order.active);
		}
    }

    function BuyDeal(address _assetAddr, uint _amount, uint _orderID) returns(bool result) {
		if (sellExistOf[_assetAddr]) {
            uint assetID = sellDataOf[_assetAddr];
			Order order = sellAssetList[assetID].sellOrderList[_orderID];
			if (order.total > 0 && order.active == true && _amount >= order.min && _amount <= order.total && ((_amount / order.step) * order.step) == _amount) {
				address agent_buy_addr = dao.agentContractOf(msg.sender);
				agent agent_buy = agent(agent_buy_addr);
				agent agent_sell = agent(order.owner);

				token credit = token(dao.daoCredits());
				if (credit.tokenBalanceOf(agent_buy_addr) < (order.unitPrice * _amount)) {
					return false;
				}
				token asset = token(sellAssetList[assetID].assetAddr);
				if (asset.tokenBalanceOf(order.owner) < _amount) {
					return false;
				}

				agent_buy.sendToken(dao.daoCredits(), order.owner, (order.unitPrice * _amount));
				agent_sell.sendToken(sellAssetList[assetID].assetAddr, agent_buy_addr, _amount);

				order.total = order.total - _amount;
				if (order.total == 0) {
					order.active = false;
				}
				return true;
			}
		}
        return false;
    }

    function SellDeal(address _assetAddr, uint _amount, uint _orderID) returns(bool result) {
        if (buyExistOf[_assetAddr]) {
			uint assetID = buyDataOf[_assetAddr];
			Order order = buyAssetList[assetID].buyOrderList[_orderID];
			if (order.total > 0 && order.active == true && _amount >= order.min && _amount <= order.total && ((_amount / order.step) * order.step) == _amount) {
				address agent_sell_addr = dao.agentContractOf(msg.sender);
				agent agent_sell = agent(agent_sell_addr);
				agent agent_buy = agent(order.owner);

				token credit = token(dao.daoCredits());
				if (credit.tokenBalanceOf(order.owner) < (order.unitPrice * _amount)) {
					return false;
				}
				token asset = token(buyAssetList[assetID].assetAddr);
				if (asset.tokenBalanceOf(agent_sell_addr) < _amount) {
					return false;
				}

				agent_sell.sendToken(buyAssetList[assetID].assetAddr, order.owner, _amount);
				agent_buy.sendToken(dao.daoCredits(), agent_sell_addr, (order.unitPrice * _amount));

				order.total = order.total - _amount;
				if (order.total == 0) {
					order.active = false;
				}
				return true;
			}
		}
		return false;
    }
}

contract goverment {
    address daoAddr;
    DAO public dao;
}


Update market.sol

Update market.sol

contract market {
    address creator;
    token Token;
    etherToken EtherToken;

    struct Order {
        uint orderID;
        address owner;
        uint total;
        uint unitPrice;
        uint min;
        uint step;
        bool active;
    }

    struct SaleAssetList {
        address assetAddr;
        Order[] sellOrderList;
    }

    struct BuyAssetList {
        address assetAddr;
        Order[] buyOrderList;
    }

    SaleAssetList[] public sellAssetList;
    mapping (address => bool) public sellExistOf;
    mapping (address => uint) public sellDataOf;
    mapping (address => uint) public sellCountAsset;

    BuyAssetList[] public buyAssetList;
    mapping (address => bool) public buyExistOf;
    mapping (address => uint) public buyDataOf;
    mapping (address => uint) public buyCountAsset;

    function market(address _etherTokenAddr) {
        creator = msg.sender;
        EtherToken = etherToken(_etherTokenAddr);
    }

    function addSell(address _assetAddr, uint _total, uint _unitPrice, uint _min, uint _step) returns(uint sellID) {
        uint assetID;
        if (sellExistOf[_assetAddr]) {
            assetID = sellDataOf[_assetAddr];
            SaleAssetList sellAssetOrders = sellAssetList[assetID];
        } else {
            assetID = sellAssetList.length++;
			sellDataOf[_assetAddr] = assetID;
            sellExistOf[_assetAddr] = true;
            sellAssetOrders = sellAssetList[assetID];
            sellAssetOrders.assetAddr = _assetAddr;
        }
        sellID = sellAssetOrders.sellOrderList.length++;

        Order order = sellAssetOrders.sellOrderList[sellID];
        order.orderID = sellID;
        order.owner = msg.sender;
        order.total = _total;
        order.unitPrice = _unitPrice;
        order.min = _min;
        order.step = _step;
        order.active = true;

        sellCountAsset[_assetAddr] = sellID;

        return sellID;
    }

    function addBuy(address _assetAddr, uint _total, uint _unitPrice, uint _min, uint _step) returns(uint buyID) {
        uint assetID;
        if (buyExistOf[_assetAddr]) {
            assetID = buyDataOf[_assetAddr];
            BuyAssetList buyAssetOrders = buyAssetList[assetID];
        } else {
            assetID = buyAssetList.length++;
			buyDataOf[_assetAddr] = assetID;
            buyExistOf[_assetAddr] = true;
            buyAssetOrders = buyAssetList[assetID];
            buyAssetOrders.assetAddr = _assetAddr;
        }
        buyID = buyAssetOrders.buyOrderList.length++;

        Order order = buyAssetOrders.buyOrderList[buyID];
        order.orderID = buyID;
        order.owner = msg.sender;
        order.total = _total;
        order.unitPrice = _unitPrice;
        order.min = _min;
        order.step = _step;
        order.active = true;

        buyCountAsset[_assetAddr] = buyID;

        return buyID;
    }

    function removeSell(address _assetAddr, uint _orderID) returns(bool) {
        if (sellExistOf[_assetAddr]) {
            uint assetID = sellDataOf[_assetAddr];
            Order order = sellAssetList[assetID].sellOrderList[_orderID];
            if (order.owner == msg.sender) {
                order.active = false;
                return true;
            }
        }
        return false;
    }

    function removeBuy(address _assetAddr, uint _orderID) returns(bool) {
        if (buyExistOf[_assetAddr]) {
            uint assetID = buyDataOf[_assetAddr];
            Order order = buyAssetList[assetID].buyOrderList[_orderID];
            if (order.owner == msg.sender) {
                order.active = false;
                return true;
            }
        }
        return false;
    }

    function downSell(address _assetAddr, uint _orderID, uint _total) {
        if (sellExistOf[_assetAddr]) {
            uint assetID = sellDataOf[_assetAddr];
            Order order = sellAssetList[assetID].sellOrderList[_orderID];
            order.total = order.total - _total;
            if (order.total == 0) {
                order.active = false;
            }
        }
    }

    function downBuy(address _assetAddr, uint _orderID, uint _total) {
        if (sellExistOf[_assetAddr]) {
            uint assetID = buyDataOf[_assetAddr];
            Order order = buyAssetList[assetID].buyOrderList[_orderID];
            order.total = order.total - _total;
            if (order.total == 0) {
                order.active = false;
            }
        }
    }

    function getSell(address _assetAddr, uint _orderID) returns(address owner, uint total, uint unitPrice, uint min, uint step, bool active) {
        if (sellExistOf[_assetAddr]) {
            uint assetID = sellDataOf[_assetAddr];
            Order order = sellAssetList[assetID].sellOrderList[_orderID];
            return (order.owner, order.total, order.unitPrice, order.min, order.step, order.active);
        }
    }

    function getBuy(address _assetAddr, uint _orderID) returns(address owner, uint total, uint unitPrice, uint min, uint step, bool active) {
        if (buyExistOf[_assetAddr]) {
            uint assetID = buyDataOf[_assetAddr];
            Order order = buyAssetList[assetID].buyOrderList[_orderID];
            return (order.owner, order.total, order.unitPrice, order.min, order.step, order.active);
        }
    }

    function getSellOwner(address _assetAddr, uint _orderID) returns(address) {
        if (sellExistOf[_assetAddr]) {
            uint assetID = sellDataOf[_assetAddr];
            Order order = sellAssetList[assetID].sellOrderList[_orderID];
            return order.owner;
        }
    }

    function getBuyOwner(address _assetAddr, uint _orderID) returns(address) {
        if (buyExistOf[_assetAddr]) {
            uint assetID = buyDataOf[_assetAddr];
            Order order = buyAssetList[assetID].buyOrderList[_orderID];
            return order.owner;
        }
    }

    function getSellPrice(address _assetAddr, uint _orderID) returns(uint) {
        if (sellExistOf[_assetAddr]) {
            uint assetID = sellDataOf[_assetAddr];
            Order order = sellAssetList[assetID].sellOrderList[_orderID];
            return order.unitPrice;
        }
    }

    function getBuyPrice(address _assetAddr, uint _orderID) returns(uint) {
        if (buyExistOf[_assetAddr]) {
            uint assetID = buyDataOf[_assetAddr];
            Order order = buyAssetList[assetID].buyOrderList[_orderID];
            return order.unitPrice;
        }
    }

    function dealSell(address _assetAddr, uint _orderID, uint count) returns(bool) {
       if (sellExistOf[_assetAddr]) {
           uint assetID = sellDataOf[_assetAddr];
           Order order = sellAssetList[assetID].sellOrderList[_orderID];
           Token = token(_assetAddr);

           if (count <= order.total
               && Token.balanceOf(order.owner) >= count
               && EtherToken.balanceOf(msg.sender) >= count * order.unitPrice) {
               Token.transferFrom(order.owner,msg.sender, count);
               EtherToken.transferFrom(msg.sender,order.owner,count * order.unitPrice);
               order.total -= count;
               order.active = order.total > 0;
               return true;
           }
       }
       return false;

   }

    function dealBuy(address _assetAddr, uint _orderID) returns(bool) {
        if (buyExistOf[_assetAddr]) {
            uint assetID = buyDataOf[_assetAddr];
            Order order = buyAssetList[assetID].buyOrderList[_orderID];
            Token = token(_assetAddr);
            if (EtherToken.balanceOf(order.owner) >= order.total * order.unitPrice && Token.balanceOf(msg.sender) >= order.total) {
                order.active = false;
                Token.transferFrom(msg.sender,order.owner,order.total);
                EtherToken.transferFrom(order.owner,msg.sender,order.total * order.unitPrice);
                return true;
            }
        }
        return false;
    }

}

contract market {
    address creator;
    token Token;
    etherToken EtherToken;

    struct Order {
        uint orderID;
        address owner;
        uint total;
        uint unitPrice;
        uint min;
        uint step;
        bool active;
    }

    struct SaleAssetList {
        address assetAddr;
        Order[] sellOrderList;
    }

    struct BuyAssetList {
        address assetAddr;
        Order[] buyOrderList;
    }

    SaleAssetList[] public sellAssetList;
    mapping (address => bool) public sellExistOf;
    mapping (address => uint) public sellDataOf;
    mapping (address => uint) public sellCountAsset;

    BuyAssetList[] public buyAssetList;
    mapping (address => bool) public buyExistOf;
    mapping (address => uint) public buyDataOf;
    mapping (address => uint) public buyCountAsset;

    function market(address _etherTokenAddr) {
        creator = msg.sender;
        EtherToken = etherToken(_etherTokenAddr);
    }

    function addSell(address _assetAddr, uint _total, uint _unitPrice, uint _min, uint _step) returns(uint sellID) {
        uint assetID;
        if (sellExistOf[_assetAddr]) {
            assetID = sellDataOf[_assetAddr];
            SaleAssetList sellAssetOrders = sellAssetList[assetID];
        } else {
            assetID = sellAssetList.length++;
			sellDataOf[_assetAddr] = assetID;
            sellExistOf[_assetAddr] = true;
            sellAssetOrders = sellAssetList[assetID];
            sellAssetOrders.assetAddr = _assetAddr;
        }
        sellID = sellAssetOrders.sellOrderList.length++;

        Order order = sellAssetOrders.sellOrderList[sellID];
        order.orderID = sellID;
        order.owner = msg.sender;
        order.total = _total;
        order.unitPrice = _unitPrice;
        order.min = _min;
        order.step = _step;
        order.active = true;

        sellCountAsset[_assetAddr] = sellID;

        return sellID;
    }

    function addBuy(address _assetAddr, uint _total, uint _unitPrice, uint _min, uint _step) returns(uint buyID) {
        uint assetID;
        if (buyExistOf[_assetAddr]) {
            assetID = buyDataOf[_assetAddr];
            BuyAssetList buyAssetOrders = buyAssetList[assetID];
        } else {
            assetID = buyAssetList.length++;
			buyDataOf[_assetAddr] = assetID;
            buyExistOf[_assetAddr] = true;
            buyAssetOrders = buyAssetList[assetID];
            buyAssetOrders.assetAddr = _assetAddr;
        }
        buyID = buyAssetOrders.buyOrderList.length++;

        Order order = buyAssetOrders.buyOrderList[buyID];
        order.orderID = buyID;
        order.owner = msg.sender;
        order.total = _total;
        order.unitPrice = _unitPrice;
        order.min = _min;
        order.step = _step;
        order.active = true;

        buyCountAsset[_assetAddr] = buyID;

        return buyID;
    }

    function removeSell(address _assetAddr, uint _orderID) returns(bool) {
        if (sellExistOf[_assetAddr]) {
            uint assetID = sellDataOf[_assetAddr];
            Order order = sellAssetList[assetID].sellOrderList[_orderID];
            if (order.owner == msg.sender) {
                order.active = false;
                return true;
            }
        }
        return false;
    }

    function removeBuy(address _assetAddr, uint _orderID) returns(bool) {
        if (buyExistOf[_assetAddr]) {
            uint assetID = buyDataOf[_assetAddr];
            Order order = buyAssetList[assetID].buyOrderList[_orderID];
            if (order.owner == msg.sender) {
                order.active = false;
                return true;
            }
        }
        return false;
    }

    function downSell(address _assetAddr, uint _orderID, uint _total) {
        if (sellExistOf[_assetAddr]) {
            uint assetID = sellDataOf[_assetAddr];
            Order order = sellAssetList[assetID].sellOrderList[_orderID];
            order.total = order.total - _total;
            if (order.total == 0) {
                order.active = false;
            }
        }
    }

    function downBuy(address _assetAddr, uint _orderID, uint _total) {
        if (sellExistOf[_assetAddr]) {
            uint assetID = buyDataOf[_assetAddr];
            Order order = buyAssetList[assetID].buyOrderList[_orderID];
            order.total = order.total - _total;
            if (order.total == 0) {
                order.active = false;
            }
        }
    }

    function getSell(address _assetAddr, uint _orderID) returns(address owner, uint total, uint unitPrice, uint min, uint step, bool active) {
        if (sellExistOf[_assetAddr]) {
            uint assetID = sellDataOf[_assetAddr];
            Order order = sellAssetList[assetID].sellOrderList[_orderID];
            return (order.owner, order.total, order.unitPrice, order.min, order.step, order.active);
        }
    }

    function getBuy(address _assetAddr, uint _orderID) returns(address owner, uint total, uint unitPrice, uint min, uint step, bool active) {
        if (buyExistOf[_assetAddr]) {
            uint assetID = buyDataOf[_assetAddr];
            Order order = buyAssetList[assetID].buyOrderList[_orderID];
            return (order.owner, order.total, order.unitPrice, order.min, order.step, order.active);
        }
    }

    function getSellOwner(address _assetAddr, uint _orderID) returns(address) {
        if (sellExistOf[_assetAddr]) {
            uint assetID = sellDataOf[_assetAddr];
            Order order = sellAssetList[assetID].sellOrderList[_orderID];
            return order.owner;
        }
    }

    function getBuyOwner(address _assetAddr, uint _orderID) returns(address) {
        if (buyExistOf[_assetAddr]) {
            uint assetID = buyDataOf[_assetAddr];
            Order order = buyAssetList[assetID].buyOrderList[_orderID];
            return order.owner;
        }
    }

    function getSellPrice(address _assetAddr, uint _orderID) returns(uint) {
        if (sellExistOf[_assetAddr]) {
            uint assetID = sellDataOf[_assetAddr];
            Order order = sellAssetList[assetID].sellOrderList[_orderID];
            return order.unitPrice;
        }
    }

    function getBuyPrice(address _assetAddr, uint _orderID) returns(uint) {
        if (buyExistOf[_assetAddr]) {
            uint assetID = buyDataOf[_assetAddr];
            Order order = buyAssetList[assetID].buyOrderList[_orderID];
            return order.unitPrice;
        }
    }

    function dealSell(address _assetAddr, uint _orderID) returns(bool) {
        if (sellExistOf[_assetAddr]) {
            uint assetID = sellDataOf[_assetAddr];
            Order order = sellAssetList[assetID].sellOrderList[_orderID];
            Token = token(_assetAddr);
            if (Token.balanceOf(order.owner) >= order.total && EtherToken.balanceOf(msg.sender) >= order.total * order.unitPrice) {
                order.active = false;
                Token.transferFrom(order.owner,msg.sender,order.total);
                EtherToken.transferFrom(msg.sender,order.owner,order.total * order.unitPrice);
                return true;
            }
        }
        return false;

    }

    function dealBuy(address _assetAddr, uint _orderID) returns(bool) {
        if (buyExistOf[_assetAddr]) {
            uint assetID = buyDataOf[_assetAddr];
            Order order = buyAssetList[assetID].buyOrderList[_orderID];
            Token = token(_assetAddr);
            if (EtherToken.balanceOf(order.owner) >= order.total * order.unitPrice && Token.balanceOf(msg.sender) >= order.total) {
                order.active = false;
                Token.transferFrom(msg.sender,order.owner,order.total);
                EtherToken.transferFrom(order.owner,msg.sender,order.total * order.unitPrice);
                return true;
            }
        }
        return false;
    }

}


Make state variables private (#1426)

Make state variables private (#1426)

* added function to renounce ownership

* Make state variables private (#1411)

pragma solidity ^0.4.24;

import "./ERC721.sol";
import "./IERC721Metadata.sol";
import "../../introspection/ERC165.sol";

contract ERC721Metadata is ERC165, ERC721, IERC721Metadata {
  // Token name
  string private _name;

  // Token symbol
  string private _symbol;

  // Optional mapping for token URIs
  mapping(uint256 => string) private _tokenURIs;

  bytes4 private constant InterfaceId_ERC721Metadata = 0x5b5e139f;
  /**
   * 0x5b5e139f ===
   *   bytes4(keccak256('name()')) ^
   *   bytes4(keccak256('symbol()')) ^
   *   bytes4(keccak256('tokenURI(uint256)'))
   */

  /**
   * @dev Constructor function
   */
  constructor(string name, string symbol) public {
    _name = name;
    _symbol = symbol;

    // register the supported interfaces to conform to ERC721 via ERC165
    _registerInterface(InterfaceId_ERC721Metadata);
  }

  /**
   * @dev Gets the token name
   * @return string representing the token name
   */
  function name() external view returns (string) {
    return _name;
  }

  /**
   * @dev Gets the token symbol
   * @return string representing the token symbol
   */
  function symbol() external view returns (string) {
    return _symbol;
  }

  /**
   * @dev Returns an URI for a given token ID
   * Throws if the token ID does not exist. May return an empty string.
   * @param tokenId uint256 ID of the token to query
   */
  function tokenURI(uint256 tokenId) public view returns (string) {
    require(_exists(tokenId));
    return _tokenURIs[tokenId];
  }

  /**
   * @dev Internal function to set the token URI for a given token
   * Reverts if the token ID does not exist
   * @param tokenId uint256 ID of the token to set its URI
   * @param uri string URI to assign
   */
  function _setTokenURI(uint256 tokenId, string uri) internal {
    require(_exists(tokenId));
    _tokenURIs[tokenId] = uri;
  }

  /**
   * @dev Internal function to burn a specific token
   * Reverts if the token does not exist
   * @param owner owner of the token to burn
   * @param tokenId uint256 ID of the token being burned by the msg.sender
   */
  function _burn(address owner, uint256 tokenId) internal {
    super._burn(owner, tokenId);

    // Clear metadata (if any)
    if (bytes(_tokenURIs[tokenId]).length != 0) {
      delete _tokenURIs[tokenId];
    }
  }
}

pragma solidity ^0.4.24;

import "./ERC721.sol";
import "./IERC721Metadata.sol";
import "../../introspection/ERC165.sol";

contract ERC721Metadata is ERC165, ERC721, IERC721Metadata {
  // Token name
  string internal _name;

  // Token symbol
  string internal _symbol;

  // Optional mapping for token URIs
  mapping(uint256 => string) private _tokenURIs;

  bytes4 private constant InterfaceId_ERC721Metadata = 0x5b5e139f;
  /**
   * 0x5b5e139f ===
   *   bytes4(keccak256('name()')) ^
   *   bytes4(keccak256('symbol()')) ^
   *   bytes4(keccak256('tokenURI(uint256)'))
   */

  /**
   * @dev Constructor function
   */
  constructor(string name, string symbol) public {
    _name = name;
    _symbol = symbol;

    // register the supported interfaces to conform to ERC721 via ERC165
    _registerInterface(InterfaceId_ERC721Metadata);
  }

  /**
   * @dev Gets the token name
   * @return string representing the token name
   */
  function name() external view returns (string) {
    return _name;
  }

  /**
   * @dev Gets the token symbol
   * @return string representing the token symbol
   */
  function symbol() external view returns (string) {
    return _symbol;
  }

  /**
   * @dev Returns an URI for a given token ID
   * Throws if the token ID does not exist. May return an empty string.
   * @param tokenId uint256 ID of the token to query
   */
  function tokenURI(uint256 tokenId) public view returns (string) {
    require(_exists(tokenId));
    return _tokenURIs[tokenId];
  }

  /**
   * @dev Internal function to set the token URI for a given token
   * Reverts if the token ID does not exist
   * @param tokenId uint256 ID of the token to set its URI
   * @param uri string URI to assign
   */
  function _setTokenURI(uint256 tokenId, string uri) internal {
    require(_exists(tokenId));
    _tokenURIs[tokenId] = uri;
  }

  /**
   * @dev Internal function to burn a specific token
   * Reverts if the token does not exist
   * @param owner owner of the token to burn
   * @param tokenId uint256 ID of the token being burned by the msg.sender
   */
  function _burn(address owner, uint256 tokenId) internal {
    super._burn(owner, tokenId);

    // Clear metadata (if any)
    if (bytes(_tokenURIs[tokenId]).length != 0) {
      delete _tokenURIs[tokenId];
    }
  }
}