Latest 25 txns From a total of 1889 Transactions

TxHash Age From To Value [TxFee]
0x630e222655d7cf5ae875d6a49f48cc00ed46cfc80d0d9ad3fc3197de27e34a9c224 days 2 hrs ago0xc3982f1dbab6da9d95f579b9a5f9c5cab13f8cfc  IN   0xe801403a9b8dae494f9088a4687c1c139fae2fe40.000002 Ether0.001588395
0x190235cbdddb652041875a15458adc6a7b9d88cf2c0bb7740686b3ed77864ca4224 days 2 hrs ago0xc3982f1dbab6da9d95f579b9a5f9c5cab13f8cfc  IN   0xe801403a9b8dae494f9088a4687c1c139fae2fe40.000002 Ether0.001572075
0x9e1980a7685ce23700123784b1cbdb86f0ab84400dd6cfc7d224175c4104bc6a224 days 3 hrs ago0xc3982f1dbab6da9d95f579b9a5f9c5cab13f8cfc  IN   0xe801403a9b8dae494f9088a4687c1c139fae2fe40.000002 Ether0.001572075
0x8173120b0f991331f8c2b318321a6bd7adbf13a9afe7c240d3e9ab9352a0bdfd224 days 5 hrs ago0x00450992bc72ab99ae55bccdce68e160412fdac0  IN   0xe801403a9b8dae494f9088a4687c1c139fae2fe40 Ether0.001004369
0x38f348e98da4e6848ab6c4a6c0167eec2b0bf2d044ad075272bf73f0fbcbc281224 days 6 hrs ago0xc3982f1dbab6da9d95f579b9a5f9c5cab13f8cfc  IN   0xe801403a9b8dae494f9088a4687c1c139fae2fe40.000002 Ether0.001586661
0x2dc9172077470337db0ab25f6cadad68537e418a8339ba66b84043e6a190b437224 days 6 hrs ago0xc3982f1dbab6da9d95f579b9a5f9c5cab13f8cfc  IN   0xe801403a9b8dae494f9088a4687c1c139fae2fe42 Ether0.001593189
0xd4ca0b0fa74984397b1fcb2a61f0e77110f447b029415bb7f392d24cf07e25c2224 days 6 hrs ago0xc3982f1dbab6da9d95f579b9a5f9c5cab13f8cfc  IN   0xe801403a9b8dae494f9088a4687c1c139fae2fe41 Ether0.001593189
0x2af7e336f05d42a05e1ef17903ab6d5f371f7d07bbe6f2174beb5eb11aa4f896224 days 7 hrs ago0xc3982f1dbab6da9d95f579b9a5f9c5cab13f8cfc  IN   0xe801403a9b8dae494f9088a4687c1c139fae2fe41 Ether0.001562283
0x5568ad7accf5ec7073ccef5d64cd71b3d20dec3554943f2c912ae9ceb7884adc230 days 7 hrs ago0xc3982f1dbab6da9d95f579b9a5f9c5cab13f8cfc  IN   0xe801403a9b8dae494f9088a4687c1c139fae2fe40.1 Ether0.001304743
0x364211df204edd55465a2b0aed7f9631814012d8aa6f8e80dcc5316389281c08230 days 9 hrs ago0xc3982f1dbab6da9d95f579b9a5f9c5cab13f8cfc  IN   0xe801403a9b8dae494f9088a4687c1c139fae2fe40 Ether0.001302119
0x1a3c6c4b2d51df6c8f4ebde19e74123a9d001fc56745da6190da717693df2fa0230 days 9 hrs ago0xc3982f1dbab6da9d95f579b9a5f9c5cab13f8cfc  IN   0xe801403a9b8dae494f9088a4687c1c139fae2fe40 Ether0.001323111
0x51365d8d259d8dc2b7a560d61ab81a27f39e866a107863b24af147ea449e26f3230 days 9 hrs ago0xc3982f1dbab6da9d95f579b9a5f9c5cab13f8cfc  IN   0xe801403a9b8dae494f9088a4687c1c139fae2fe40 Ether0.001323111
0x127b71aeafd017983026d6b8df63aa63e0c77f620c6853b9ad599418b827c559230 days 10 hrs ago0xc3982f1dbab6da9d95f579b9a5f9c5cab13f8cfc  IN   0xe801403a9b8dae494f9088a4687c1c139fae2fe40 Ether0.001323111
0xb4c5740d9178e4aa262e1e7791318e5bf93ccfe613e364a77f35f739f850578f230 days 10 hrs ago0xc3982f1dbab6da9d95f579b9a5f9c5cab13f8cfc  IN   0xe801403a9b8dae494f9088a4687c1c139fae2fe40 Ether0.001559019
0x8fec180a85ddbec62d0e6bcab389155407caf071eb23187c0c771399775e4c65230 days 10 hrs ago0xc3982f1dbab6da9d95f579b9a5f9c5cab13f8cfc  IN   0xe801403a9b8dae494f9088a4687c1c139fae2fe40 Ether0.001624299
0x9b58ef8aa746caa033543cdc2c33300c8a3baddf50fb80c79b41c7797dc6b572230 days 23 hrs ago0xc3982f1dbab6da9d95f579b9a5f9c5cab13f8cfc  IN   0xe801403a9b8dae494f9088a4687c1c139fae2fe45 Ether0.001338855
0x63c56e17e7df92068e3e9c0ff1885ec3198427fea78b8d4f0f711d73bba412de230 days 23 hrs ago0xc3982f1dbab6da9d95f579b9a5f9c5cab13f8cfc  IN   0xe801403a9b8dae494f9088a4687c1c139fae2fe42 Ether0.001333607
0x42fc20593a9a6e940408288e01185790d8018c77e257ce449c3fce46d82062bc276 days 1 hr ago0xf61807b9488374c44a8fe022273855b5fa7e61f3  IN   0xe801403a9b8dae494f9088a4687c1c139fae2fe40 Ether0.000028668
0xfe3f5209ac8253985be9bafd3e4ea8bb22258ba405fad50660e9dba582ec31ac276 days 1 hr ago0xf61807b9488374c44a8fe022273855b5fa7e61f3  IN   0xe801403a9b8dae494f9088a4687c1c139fae2fe40 Ether0.004465034
0xe13b791d35983af72d6325dbcb2a4a9efa45f16df530217d5a502f76c1797a6a276 days 4 hrs ago0xf61807b9488374c44a8fe022273855b5fa7e61f3  IN   0xe801403a9b8dae494f9088a4687c1c139fae2fe40 Ether0.004465034
0xb364ebc3152ae067338c571877fe25b11abfbae9efd90962d1e9236f0475c27c276 days 4 hrs ago0xf61807b9488374c44a8fe022273855b5fa7e61f3  IN   0xe801403a9b8dae494f9088a4687c1c139fae2fe40 Ether0.004465034
0x5a1743f218b8ff08e0171cfaf9f40bf0bf98177e7040c438c13bf471f8132622278 days 23 hrs ago0x4ca3432d898ab1bc0763a44b086579cc4a5ff780  IN   0xe801403a9b8dae494f9088a4687c1c139fae2fe41 Ether0.004465034
0x2aee62cba6b25a13a183f3e2fd7a0e5210e3b441c0654e841d6f7dcc721a14fe279 days 12 hrs ago0x20d7114a144e8e5890dd2de22d56c665d2a14719  IN   0xe801403a9b8dae494f9088a4687c1c139fae2fe40.01 Ether0.004469392
0x572fac98175fd47bb76dcf8d12d9d0bd7d42a8b78b3d952bf661ef4be0c85784279 days 12 hrs ago0x20d7114a144e8e5890dd2de22d56c665d2a14719  IN   0xe801403a9b8dae494f9088a4687c1c139fae2fe40.01 Ether0.0004473756
0x66fd9b01f3f71a440ac1844cccfd5223a1c67445b28ec02838771fb999d45e3c280 days 2 hrs ago0xe47494379c1d48ee73454c251a6395fdd4f9eb43  IN   0xe801403a9b8dae494f9088a4687c1c139fae2fe40.001 Ether0.05
[ Download CSV Export  ] 
 Internal Transactions as a result of Contract Execution
 Latest 25 Internal Txns, Click Here To View More View All
ParentTxHash Block Age From To Value
0x2f01a583b19ca3bf2d29d36880107aa77a2cd8add41a65a9c84983153cae5e943208623192 days 23 hrs ago0x14c7e3b3d5d6dae6c088b04e2ea9c14e4ddc2d970xe801403a9b8dae494f9088a4687c1c139fae2fe40.00000000000004 Ether
0xf2126a95b1701c53cc836a817d01398b7b73e1dac873ce6d005c6a4aad4ac6a02612231284 days 21 hrs ago0xe801403a9b8dae494f9088a4687c1c139fae2fe40x488b362e51a53e969cb28f42eadc41411f20a8350.1 Ether
0x38d1ccd5f219efc301f48ca53c7d8fc2ab54cd82d8717fabc1e5ed36c3d0050f2611952284 days 22 hrs ago0xe801403a9b8dae494f9088a4687c1c139fae2fe40x488b362e51a53e969cb28f42eadc41411f20a8351 Ether
0xdedb34c6620b5df581cdaf3be0b3dac0aa051134d9284b2ce08e5e998c3aa2ea2611780284 days 22 hrs ago0xe801403a9b8dae494f9088a4687c1c139fae2fe40x488b362e51a53e969cb28f42eadc41411f20a8350.04 Ether
0xd7d0959fb290b81161c170b5abc2b87a0601f0cfc55dacfb7e383278f0502b332611302285 days 40 mins ago0xe801403a9b8dae494f9088a4687c1c139fae2fe40x488b362e51a53e969cb28f42eadc41411f20a8351 Ether
0x4222b71126f9c324b2465b1aaaac32ae51a048f82ae006dd54b97888198478ed2610971285 days 1 hr ago0xe801403a9b8dae494f9088a4687c1c139fae2fe40x488b362e51a53e969cb28f42eadc41411f20a8350.79958 Ether
0x5773b661393fb55122e2db9df85fd8150881a2ecd5e1f0b7469103f810f6e7d92610840285 days 2 hrs ago0xe801403a9b8dae494f9088a4687c1c139fae2fe40x374c8afb8e7d75c71d880862dec75ec2dc5ea3800.360928083253912125 Ether
0x5773b661393fb55122e2db9df85fd8150881a2ecd5e1f0b7469103f810f6e7d92610840285 days 2 hrs ago0x488b362e51a53e969cb28f42eadc41411f20a8350xe801403a9b8dae494f9088a4687c1c139fae2fe40.360928083253912125 Ether
0xd1773b7ffe974d7c59e8a97f3930a770990bfe938bfe93a99dbd4916313a71732610823285 days 2 hrs ago0xe801403a9b8dae494f9088a4687c1c139fae2fe40x488b362e51a53e969cb28f42eadc41411f20a8350.37 Ether
0xfea1629037b4e20373834c35f2ef9e6f27fea4b22fbe23a76eb2b68206f3b4072610810285 days 2 hrs ago0xe801403a9b8dae494f9088a4687c1c139fae2fe40x374c8afb8e7d75c71d880862dec75ec2dc5ea3800.392375028637187034 Ether
0xfea1629037b4e20373834c35f2ef9e6f27fea4b22fbe23a76eb2b68206f3b4072610810285 days 2 hrs ago0x488b362e51a53e969cb28f42eadc41411f20a8350xe801403a9b8dae494f9088a4687c1c139fae2fe40.392375028637187034 Ether
0x3ce103c2c6147cf07c3b55e6d91f275d8a7bf1a6ac65ef38c250b0cfe47962f72610804285 days 2 hrs ago0xe801403a9b8dae494f9088a4687c1c139fae2fe40x374c8afb8e7d75c71d880862dec75ec2dc5ea3800.192096662860611176 Ether
0x3ce103c2c6147cf07c3b55e6d91f275d8a7bf1a6ac65ef38c250b0cfe47962f72610804285 days 2 hrs ago0x488b362e51a53e969cb28f42eadc41411f20a8350xe801403a9b8dae494f9088a4687c1c139fae2fe40.192096662860611176 Ether
0x71e0a4c76d0413ca16416cf456cc81a0f76d4da1a83a76f5bb839f5990b07d0b2610796285 days 2 hrs ago0xe801403a9b8dae494f9088a4687c1c139fae2fe40xb03c4e48bfaa8b2ecc1c9037b1610e56114f81e73.89917175 Ether
0x71e0a4c76d0413ca16416cf456cc81a0f76d4da1a83a76f5bb839f5990b07d0b2610796285 days 2 hrs ago0x488b362e51a53e969cb28f42eadc41411f20a8350xe801403a9b8dae494f9088a4687c1c139fae2fe43.89917175 Ether
0x2a4fcfee48d22fcecf09da67cd95cb609b62b7232b5a60106bdc12cd692572d92610794285 days 2 hrs ago0xe801403a9b8dae494f9088a4687c1c139fae2fe40x488b362e51a53e969cb28f42eadc41411f20a8359 Ether
0x3ee3f2c0854c7a618fb7efa17f37fa8ca3a1f5ffb273df73a1f824d06a127ca92610788285 days 2 hrs ago0xe801403a9b8dae494f9088a4687c1c139fae2fe40x488b362e51a53e969cb28f42eadc41411f20a83510 Ether
0x434bee6a6d1b3d89986400e00ad90597a746f21b82bc717f0cd16b9e488ddae12610616285 days 3 hrs ago0xe801403a9b8dae494f9088a4687c1c139fae2fe40x488b362e51a53e969cb28f42eadc41411f20a8351 Ether
0x9f3e30d34854964ba926459c75e1a7d84f82bb4667d23df6dd5874acdc0064672610203285 days 4 hrs ago0xe801403a9b8dae494f9088a4687c1c139fae2fe40x93e96382437672907898c57a6d2c012b3cdab91b2.010535899326813173 Ether
0x9f3e30d34854964ba926459c75e1a7d84f82bb4667d23df6dd5874acdc0064672610203285 days 4 hrs ago0x488b362e51a53e969cb28f42eadc41411f20a8350xe801403a9b8dae494f9088a4687c1c139fae2fe42.010535899326813173 Ether
0x54097fecebe8fd4468b9344b32b6b54b290f205003fc0b6a0191353816c10b922610174285 days 4 hrs ago0xe801403a9b8dae494f9088a4687c1c139fae2fe40x488b362e51a53e969cb28f42eadc41411f20a8350.09 Ether
0x7ba2b569c9c11f67a4b53f883c272154cfed47c57f146dd469c9c63218ce4db72609188285 days 7 hrs ago0xe801403a9b8dae494f9088a4687c1c139fae2fe40x488b362e51a53e969cb28f42eadc41411f20a8350.23 Ether
0x896ce06b7815d52157d24bb455924c05669e2e84ae344da35035b983267cdc132609182285 days 7 hrs ago0xe801403a9b8dae494f9088a4687c1c139fae2fe40x488b362e51a53e969cb28f42eadc41411f20a8350.23 Ether
0x2e75e72c817bb3b73a251eef1c7ad8b98da0876defd493c2e113cbcb6233189e2609178285 days 7 hrs ago0xe801403a9b8dae494f9088a4687c1c139fae2fe40x488b362e51a53e969cb28f42eadc41411f20a8350.2 Ether
0x1a55eda037ca74ceb4f3c5b7fc41f88f4b460caa888ef79a10485509fc76bd232609164285 days 8 hrs ago0xe801403a9b8dae494f9088a4687c1c139fae2fe40x488b362e51a53e969cb28f42eadc41411f20a8351.888124 Ether
[ Download CSV Export  ] 
Warning: The Compiled Contract might be susceptible to ExpExponentCleanup (medium/high-severity), EventStructWrongData (very low-severity), NestedArrayFunctionCallDecoder (medium-severity) SolidityCompiler Bugs.

Contract Source Code Verified (Exact Match)
Contract Name: KyberNetwork
Compiler Text: v0.4.18+commit.9cf6e910
Optimization Enabled: No
Runs (Optimiser):  200



  Contract Source Code   Find Similiar Contracts

pragma solidity ^0.4.18;

interface SanityPricingInterface {
    function getSanityPrice(ERC20 src, ERC20 dest) view public returns(uint);
}

interface ERC20 {
    function totalSupply() public view returns (uint supply);
    function balanceOf(address _owner) public view returns (uint balance);
    function transfer(address _to, uint _value) public returns (bool success);
    function transferFrom(address _from, address _to, uint _value) public returns (bool success);
    function approve(address _spender, uint _value) public returns (bool success);
    function allowance(address _owner, address _spender) public view returns (uint remaining);
    function decimals() public view returns(uint digits);
    event Transfer(address indexed _from, address indexed _to, uint _value);
    event Approval(address indexed _owner, address indexed _spender, uint _value);
}

contract KyberConstants {

    ERC20 constant ETH_TOKEN_ADDRESS = ERC20(0x00eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee);
    uint  constant PRECISION = (10**18);
    uint  constant MAX_QTY   = (10**28); // 1B tokens
    uint  constant MAX_RATE  = (PRECISION * 10**6); // up to 1M tokens per ETH
    uint  constant MAX_DECIMALS = 18;

    function calcDstQty(uint srcQty, uint srcDecimals, uint dstDecimals, uint rate) internal pure returns(uint) {
        if( dstDecimals >= srcDecimals ) {
            require((dstDecimals-srcDecimals) <= MAX_DECIMALS);
            return (srcQty * rate * (10**(dstDecimals-srcDecimals))) / PRECISION;
        } else {
            require((srcDecimals-dstDecimals) <= MAX_DECIMALS);
            return (srcQty * rate) / (PRECISION * (10**(srcDecimals-dstDecimals)));
        }
    }

    function calcSrcQty(uint dstQty, uint srcDecimals, uint dstDecimals, uint rate) internal pure returns(uint) {
        if( srcDecimals >= dstDecimals ) {
            require((srcDecimals-dstDecimals) <= MAX_DECIMALS);
            return (PRECISION * dstQty * (10**(srcDecimals - dstDecimals))) / rate;
        } else {
            require((dstDecimals-srcDecimals) <= MAX_DECIMALS);
            return (PRECISION * dstQty) / (rate * (10**(dstDecimals - srcDecimals)));
        }
    }
}

interface ExpectedRateInterface {
    function getExpectedRate(ERC20 source, ERC20 dest, uint srcQty) public view
        returns (uint expectedPrice, uint slippagePrice);
}

interface BurnableToken {
    function transferFrom(address _from, address _to, uint _value) public returns (bool);
    function burnFrom(address _from, uint256 _value) public returns (bool);
}

interface FeeBurnerInterface {
    function handleFees (uint tradeWeiAmount, address reserve, address wallet) public returns(bool);
}

contract PermissionGroups {

    address public admin;
    address public pendingAdmin;
    mapping(address=>bool) operators;
    mapping(address=>bool) alerters;
    address[] operatorsGroup;
    address[] alertersGroup;

    function PermissionGroups() public {
        admin = msg.sender;
    }

    modifier onlyAdmin() {
        require (msg.sender == admin);
        _;
    }

    modifier onlyOperator() {
        require (operators[msg.sender]);
        _;
    }

    modifier onlyAlerter() {
        require (alerters[msg.sender]);
        _;
    }

    event TransferAdmin(address pendingAdmin);

    /**
     * @dev Allows the current admin to set the pendingAdmin address.
     * @param newAdmin The address to transfer ownership to.
     */
    function transferAdmin(address newAdmin) public onlyAdmin {
        require(newAdmin !=  address(0));
        TransferAdmin(pendingAdmin);
        pendingAdmin = newAdmin;
    }

    event ClaimAdmin( address newAdmin, address previousAdmin);

    /**
     * @dev Allows the pendingAdmin address to finalize the change admin process.
     */
    function claimAdmin() public {
        require(pendingAdmin == msg.sender);
        ClaimAdmin(pendingAdmin, admin);
        admin = pendingAdmin;
        pendingAdmin = address(0);
    }

    event AddAlerter (address newAlerter, bool isAdd);

    function addAlerter(address newAlerter) public onlyAdmin {
        require(!alerters[newAlerter]); // prevent duplicates.
        AddAlerter(newAlerter, true);
        alerters[newAlerter] = true;
        alertersGroup.push(newAlerter);
    }

    function removeAlerter (address alerter) public onlyAdmin {

        require(alerters[alerter]);
        alerters[alerter] = false;

        for (uint i = 0; i < alertersGroup.length; ++i)
        {
            if (alertersGroup[i] == alerter)
            {
                alertersGroup[i] = alertersGroup[alertersGroup.length - 1];
                alertersGroup.length--;
                AddAlerter(alerter, false);
                break;
            }
        }
    }

    event AddOperator(address newOperator, bool isAdd);

    function addOperator(address newOperator) public onlyAdmin {
        require(!operators[newOperator]); // prevent duplicates.
        AddOperator(newOperator, true);
        operators[newOperator] = true;
        operatorsGroup.push(newOperator);
    }

    function removeOperator (address operator) public onlyAdmin {

        require (operators[operator]);
        operators[operator] = false;

        for (uint i = 0; i < operatorsGroup.length; ++i)
        {
            if (operatorsGroup[i] == operator)
            {
                operatorsGroup[i] = operatorsGroup[operatorsGroup.length - 1];
                operatorsGroup.length -= 1;
                AddOperator(operator, false);
                break;
            }
        }
    }

    function getOperators () external view returns(address []) {
        return operatorsGroup;
    }

    function getAlerters () external view returns(address []) {
        return alertersGroup;
    }
}

contract Withdrawable is PermissionGroups {

    event WithdrawToken(ERC20 token, uint amount, address sendTo);
    /**
     * @dev Withdraw all ERC20 compatible tokens
     * @param token ERC20 The address of the token contract
     */
    function withdrawToken(ERC20 token, uint amount, address sendTo) external onlyAdmin {
        assert(token.transfer(sendTo, amount));
        WithdrawToken(token, amount, sendTo);
    }

    event WithdrawEther(uint amount, address sendTo);
    /**
     * @dev Withdraw Ethers
     */
    function withdrawEther(uint amount, address sendTo) external onlyAdmin {
        sendTo.transfer(amount);
        WithdrawEther(amount, sendTo);
    }
}

contract KyberWhiteList is Withdrawable {

    uint public weiPerSgd; // amount of weis in 1 singapore dollar
    mapping (address=>uint) public userCategory; // each user has a category that defines cap on trade amount. 0 will be standard
    mapping (uint=>uint)    public categoryCap;  // will define cap on trade amount per category in singapore Dollar.

    function KyberWhiteList(address _admin) public {
        admin = _admin;
    }

    event SetUserCategory(address user, uint category);

    function setUserCategory(address user, uint category) public onlyOperator {
        userCategory[user] = category;
        SetUserCategory(user, category);
    }

    event SetCategoryCap (uint category, uint sgdCap);

    function setCategoryCap(uint category, uint sgdCap) public onlyOperator {
        categoryCap[category] = sgdCap;
        SetCategoryCap (category, sgdCap);
    }

    event SetSgdToWeiRate (uint rate);

    function setSgdToEthRate(uint _sgdToWeiRate) public onlyOperator {
        weiPerSgd = _sgdToWeiRate;
        SetSgdToWeiRate(_sgdToWeiRate);
    }

    function getUserCapInWei(address user) external view returns (uint userCapWei) {
        uint category = userCategory[user];
        return (categoryCap[category] * weiPerSgd);
    }
}

contract KyberReserve is Withdrawable, KyberConstants {

    address public kyberNetwork;
    bool public tradeEnabled;
    Pricing public pricingContract;
    SanityPricingInterface public sanityPricingContract;
    mapping(bytes32=>bool) public approvedWithdrawAddresses; // sha3(token,address)=>bool

    function KyberReserve(address _kyberNetwork, Pricing _pricingContract, address _admin) public {
        kyberNetwork = _kyberNetwork;
        pricingContract = _pricingContract;
        admin = _admin;
        tradeEnabled = true;
    }

    event DepositToken(ERC20 token, uint amount);

    function() payable public {
        DepositToken(ETH_TOKEN_ADDRESS, msg.value);
    }

    event DoTrade(
        address indexed origin,
        address source,
        uint sourceAmount,
        address destToken,
        uint destAmount,
        address destAddress
    );

    function trade(
        ERC20 sourceToken,
        uint sourceAmount,
        ERC20 destToken,
        address destAddress,
        uint conversionRate,
        bool validate
    )
        public
        payable
        returns(bool)
    {
        require(tradeEnabled);
        require(msg.sender == kyberNetwork);

        assert(doTrade(sourceToken, sourceAmount, destToken, destAddress, conversionRate, validate));

        return true;
    }

    event EnableTrade(bool enable);

    function enableTrade() public onlyAdmin returns(bool) {
        tradeEnabled = true;
        EnableTrade(true);

        return true;
    }

    function disableTrade() public onlyAlerter returns(bool) {
        tradeEnabled = false;
        EnableTrade(false);

        return true;
    }

    event ApproveWithdrawAddress(ERC20 token, address addr, bool approve);

    function approveWithdrawAddress(ERC20 token, address addr, bool approve) public onlyAdmin {
        approvedWithdrawAddresses[keccak256(token, addr)] = approve;
        ApproveWithdrawAddress(token, addr, approve);
    }

    event Withdraw(ERC20 token, uint amount, address destination);

    function withdraw(ERC20 token, uint amount, address destination) public onlyOperator returns(bool) {
        require(approvedWithdrawAddresses[keccak256(token, destination)]);

        if(token == ETH_TOKEN_ADDRESS) {
            destination.transfer(amount);
        } else {
            assert(token.transfer(destination, amount));
        }

        Withdraw(token, amount, destination);

        return true;
    }

    function setContracts(address _kyberNetwork, Pricing _pricing, SanityPricingInterface _sanityPricing)
        public
        onlyAdmin
    {
        require(_kyberNetwork != address(0));
        require(_pricing != address(0));

        kyberNetwork = _kyberNetwork;
        pricingContract = _pricing;
        sanityPricingContract = _sanityPricing;
    }

    ////////////////////////////////////////////////////////////////////////////
    /// status functions ///////////////////////////////////////////////////////
    ////////////////////////////////////////////////////////////////////////////

    function getBalance(ERC20 token) public view returns(uint) {
        if(token == ETH_TOKEN_ADDRESS) return this.balance;
        else return token.balanceOf(this);
    }

    function getDecimals(ERC20 token) public view returns(uint) {
        if(token == ETH_TOKEN_ADDRESS) return 18;
        return token.decimals();
    }

    function getDestQty(ERC20 source, ERC20 dest, uint srcQty, uint rate) public view returns(uint) {
        uint dstDecimals = getDecimals(dest);
        uint srcDecimals = getDecimals(source);

        return calcDstQty(srcQty, srcDecimals, dstDecimals, rate);
    }

    function getSrcQty(ERC20 source, ERC20 dest, uint dstQty, uint rate) public view returns(uint) {
        uint dstDecimals = getDecimals(dest);
        uint srcDecimals = getDecimals(source);

        if( srcDecimals >= dstDecimals ) {
            require((srcDecimals-dstDecimals) <= MAX_DECIMALS);
            return (PRECISION * dstQty * (10**(srcDecimals - dstDecimals))) / rate;
        } else {
            require((dstDecimals-srcDecimals) <= MAX_DECIMALS);
            return (PRECISION * dstQty) / (rate * (10**(dstDecimals - srcDecimals)));
        }
    }

    function getConversionRate(ERC20 source, ERC20 dest, uint srcQty, uint blockNumber) public view returns(uint) {
        ERC20 token;
        bool  buy;

        if(ETH_TOKEN_ADDRESS == source) {
            buy = true;
            token = dest;
        } else if(ETH_TOKEN_ADDRESS == dest) {
            buy = false;
            token = source;
        } else {
            return 0; // pair is not listed
        }

        uint price = pricingContract.getPrice(token, blockNumber, buy, srcQty);
        uint destQty = getDestQty(source, dest, srcQty, price);

        if(getBalance(dest) < destQty) return 0;

        if(sanityPricingContract != address(0)) {
            uint sanityPrice = sanityPricingContract.getSanityPrice(source, dest);
            if(price > sanityPrice) return 0;
        }

        return price;
    }

    /// @dev do a trade
    /// @param sourceToken Source token
    /// @param sourceAmount Amount of source token
    /// @param destToken Destination token
    /// @param destAddress Destination address to send tokens to
    /// @param validate If true, additional validations are applicable
    /// @return true iff trade is successful
    function doTrade(
        ERC20 sourceToken,
        uint sourceAmount,
        ERC20 destToken,
        address destAddress,
        uint conversionRate,
        bool validate
    )
        internal
        returns(bool)
    {
        // can skip validation if done at kyber network level
        if(validate) {
            require(conversionRate > 0);
            if(sourceToken == ETH_TOKEN_ADDRESS) require(msg.value == sourceAmount);
            else require(msg.value == 0);
        }

        uint destAmount = getDestQty(sourceToken, destToken, sourceAmount, conversionRate);
        // sanity check
        require(destAmount > 0);

        // add to imbalance
        ERC20 token;
        int buy;
        if(sourceToken == ETH_TOKEN_ADDRESS) {
            buy = int(destAmount);
            token = destToken;
        } else {
            buy = -1 * int(sourceAmount);
            token = sourceToken;
        }

        pricingContract.recordImbalance(
            token,
            buy,
            pricingContract.getPriceUpdateBlock(token),
            block.number
        );

        // collect source tokens
        if(sourceToken != ETH_TOKEN_ADDRESS) {
            assert(sourceToken.transferFrom(msg.sender, this, sourceAmount));
        }

        // send dest tokens
        if(destToken == ETH_TOKEN_ADDRESS) {
            destAddress.transfer(destAmount);
        } else {
            assert(destToken.transfer(destAddress, destAmount));
        }

        DoTrade(tx.origin, sourceToken, sourceAmount, destToken, destAmount, destAddress);

        return true;
    }
}

contract KyberNetwork is Withdrawable, KyberConstants {

    uint public negligiblePriceDiff = 10; // basic price steps will be in 0.01%
    KyberReserve[] public reserves;
    mapping(address=>bool) public isReserve;
    KyberWhiteList public kyberWhiteList;
    ExpectedRateInterface public expectedRateContract;
    FeeBurnerInterface    public feeBurnerContract;
    uint                  public maxGasPrice = 50 * 1000 * 1000 * 1000; // 50 gwei
    bool                  public enable = true; // network is enabled
    mapping(address=>mapping(bytes32=>bool)) perReserveListedPairs;

    function KyberNetwork(address _admin) public {
        admin = _admin;
    }

    event Trade(address indexed sender, ERC20 source, ERC20 dest, uint actualSrcAmount, uint actualDestAmount);

    /// @notice use token address ETH_TOKEN_ADDRESS for ether
    /// @dev makes a trade between source and dest token and send dest token to
    /// destAddress and record wallet id for later payment
    /// @param source Source token
    /// @param srcAmount amount of source tokens
    /// @param dest   Destination token
    /// @param destAddress Address to send tokens to
    /// @param maxDestAmount A limit on the amount of dest tokens
    /// @param minConversionRate The minimal conversion rate. If actual rate is lower, trade is canceled.
    /// @return amount of actual dest tokens
    function walletTrade(
        ERC20 source,
        uint srcAmount,
        ERC20 dest,
        address destAddress,
        uint maxDestAmount,
        uint minConversionRate,
        address walletId
    )
        public
        payable
        returns(uint)
    {
       return trade(source, srcAmount, dest, destAddress, maxDestAmount, minConversionRate, walletId);
    }

    /// @notice use token address ETH_TOKEN_ADDRESS for ether
    /// @dev makes a trade between source and dest token and send dest token to destAddress
    /// @param source Source token
    /// @param srcAmount amount of source tokens
    /// @param dest   Destination token
    /// @param destAddress Address to send tokens to
    /// @param maxDestAmount A limit on the amount of dest tokens
    /// @param minConversionRate The minimal conversion rate. If actual rate is lower, trade is canceled.
    /// @return amount of actual dest tokens
    function trade(
        ERC20 source,
        uint srcAmount,
        ERC20 dest,
        address destAddress,
        uint maxDestAmount,
        uint minConversionRate,
        address walletId
    )
        public
        payable
        returns(uint)
    {
        require(enable);

        uint userSrcBalanceBefore;
        uint userSrcBalanceAfter;
        uint userDestBalanceBefore;
        uint userDestBalanceAfter;

        userSrcBalanceBefore = getBalance(source, msg.sender);
        userDestBalanceBefore = getBalance(dest,destAddress);

        assert(doTrade(source,srcAmount,dest,destAddress,maxDestAmount,minConversionRate,walletId) > 0);

        userSrcBalanceAfter = getBalance(source, msg.sender);
        userDestBalanceAfter = getBalance(dest,destAddress);

        require(userSrcBalanceAfter <= userSrcBalanceBefore);
        require(userDestBalanceAfter >= userDestBalanceBefore);

        uint srcDecimals;
        uint destDecimals;

        if(source == ETH_TOKEN_ADDRESS) {
            srcDecimals = 18;
        } else {
            srcDecimals = source.decimals();
        }

        if(dest == ETH_TOKEN_ADDRESS) {
            destDecimals = 18;
        } else {
            destDecimals = dest.decimals();
        }

        // TODO - mitigate potential overflow
        require(((userSrcBalanceBefore - userSrcBalanceAfter) * minConversionRate) * (10 ** destDecimals) <=
                (userDestBalanceAfter - userDestBalanceBefore) * (10 ** srcDecimals) * PRECISION );
    }

    function getDecimals(ERC20 token) internal view returns(uint) {
        if(token == ETH_TOKEN_ADDRESS) return 18;
        return token.decimals();
    }

    function calcDestAmount(ERC20 source, ERC20 dest, uint srcAmount, uint rate) internal view returns(uint) {
        return calcDstQty(srcAmount, getDecimals(source), getDecimals(dest),rate);
    }

    function calcSrcAmount(ERC20 source, ERC20 dest, uint destAmount, uint rate) internal view returns(uint) {
        return calcSrcQty(destAmount,getDecimals(source), getDecimals(dest),rate);
    }

    function doTrade(
        ERC20 source,
        uint srcAmount,
        ERC20 dest,
        address destAddress,
        uint maxDestAmount,
        uint minConversionRate,
        address walletId
    )
        internal
        returns(uint)
    {
        require(tx.gasprice <= maxGasPrice);
        require(kyberWhiteList != address(0));
        require(feeBurnerContract != address(0));
        require(validateTradeInput(source, srcAmount));

        uint reserveInd;
        uint rate;
        (reserveInd,rate) = findBestRate(source, dest, srcAmount);
        KyberReserve theReserve = reserves[reserveInd];
        assert(rate > 0);
        assert(rate < MAX_RATE);
        assert(rate >= minConversionRate);

        uint actualSourceAmount = srcAmount;
        uint actualDestAmount = calcDestAmount(source,dest,actualSourceAmount,rate);

        if(actualDestAmount > maxDestAmount) {
            actualDestAmount = maxDestAmount;
            actualSourceAmount = calcSrcAmount(source,dest,actualDestAmount,rate);
        }

        // do the trade
        // verify trade size is smaller then user cap
        uint ethAmount;
        if (source == ETH_TOKEN_ADDRESS) {
            ethAmount = actualSourceAmount;
        }
        else {
            ethAmount = actualDestAmount;
        }

        require(ethAmount <= getUserCapInWei(msg.sender));

        assert(doReserveTrade(
            source,
            actualSourceAmount,
            dest,
            destAddress,
            actualDestAmount,
            theReserve,
            rate,
            true)
        );

        assert(feeBurnerContract.handleFees(ethAmount,theReserve,walletId));

        Trade(msg.sender, source, dest, actualSourceAmount, actualDestAmount);
        return actualDestAmount;
    }

    event AddReserve(KyberReserve reserve, bool add);

    /// @notice can be called only by admin
    /// @dev add or deletes a reserve to/from the network.
    /// @param reserve The reserve address.
    /// @param add If true, the add reserve. Otherwise delete reserve.
    function addReserve(KyberReserve reserve, bool add) public onlyAdmin {

        if(add) {
            reserves.push(reserve);
            isReserve[reserve] = true;
            AddReserve(reserve, true);
        } else {
            isReserve[reserve] = false;
            // will have trouble if more than 50k reserves...
            for(uint i = 0; i < reserves.length; i++) {
                if(reserves[i] == reserve) {
                    if(reserves.length == 0) return;
                    reserves[i] = reserves[--reserves.length];
                    AddReserve(reserve, false);
                    break;
                }
            }
        }
    }

    event ListPairsForReserve(address reserve, ERC20 source, ERC20 dest, bool add);

    /// @notice can be called only by admin
    /// @dev allow or prevent a specific reserve to trade a pair of tokens
    /// @param reserve The reserve address.
    /// @param source Source token
    /// @param dest Destination token
    /// @param add If true then enable trade, otherwise delist pair.
    function listPairForReserve(address reserve, ERC20 source, ERC20 dest, bool add) public onlyAdmin {
        (perReserveListedPairs[reserve])[keccak256(source, dest)] = add;

        if(source != ETH_TOKEN_ADDRESS) {
            if(add) {
                source.approve(reserve, 2**255); // approve infinity
            } else {
                source.approve(reserve, 0);
            }
        }

        ListPairsForReserve(reserve, source, dest, add);
    }

    function setParams(
        KyberWhiteList        _whiteList,
        ExpectedRateInterface _expectedRate,
        FeeBurnerInterface    _feeBurner,
        uint                  _maxGasPrice,
        uint                  _negligibleDiff
    )
        public
        onlyAdmin
    {
        kyberWhiteList = _whiteList;
        expectedRateContract = _expectedRate;
        feeBurnerContract = _feeBurner;
        maxGasPrice = _maxGasPrice;
        negligiblePriceDiff = _negligibleDiff;

    }

    function setEnable(bool _enable) public onlyAdmin {
        enable = _enable;
    }

    event EtherReceival(address indexed sender, uint amount);
    function() payable public {
        require(isReserve[msg.sender]);
        EtherReceival(msg.sender,msg.value);
    }

    /// @dev returns number of reserves
    /// @return number of reserves
    function getNumReserves() public view returns(uint) {
        return reserves.length;
    }

    /// @notice should be called off chain with as much gas as needed
    /// @dev get an array of all reserves
    /// @return An array of all reserves
    function getReserves() public view returns(KyberReserve[]) {
        return reserves;
    }

    /// @dev get the balance of a user.
    /// @param token The token type
    /// @return The balance
    function getBalance(ERC20 token, address user) public view returns(uint){
        if(token == ETH_TOKEN_ADDRESS) return user.balance;
        else return token.balanceOf(user);
    }

    /// @notice use token address ETH_TOKEN_ADDRESS for ether
    /// @dev best conversion rate for a pair of tokens, if number of reserves have small differences. randomize
    /// @param source Source token
    /// @param dest Destination token
    function findBestRate(ERC20 source, ERC20 dest, uint srcQty) public view returns(uint, uint) {
        uint bestRate = 0;
        uint bestReserve = 0;
        uint numRelevantReserves = 0;
        uint numReserves = reserves.length;
        uint[] memory rates = new uint[](numReserves);
        uint[] memory reserveCandidates = new uint[](numReserves);

        for(uint i = 0; i < numReserves; i++) {
            //list all reserves that have this token.
            if(!(perReserveListedPairs[reserves[i]])[keccak256(source, dest)]) continue;

            rates[i] = reserves[i].getConversionRate(source, dest, srcQty, block.number);

            if(rates[i] > bestRate) {
                //best rate is highest rate
                bestRate = rates[i];
            }
        }

        if (bestRate > 0) {
            uint random = 0;
            uint smallestRelevantRate = (bestRate * 10000) / (10000 + negligiblePriceDiff);

            for (i = 0; i < numReserves; i++) {
                if (rates[i] >= smallestRelevantRate) {
                    reserveCandidates[numRelevantReserves++] = i;
                }
            }

            if (numRelevantReserves > 1) {
                //when encountering small price diff from bestRate. draw from relevant reserves
                random = uint(block.blockhash(block.number-1)) % numRelevantReserves;
            }

            bestReserve = reserveCandidates[random];
            bestRate = rates[bestReserve];
        }

        return (bestReserve, bestRate);
    }

    function getExpectedRate(ERC20 source, ERC20 dest, uint srcQuantity)
        public view
        returns (uint expectedPrice, uint slippagePrice)
    {
        require(expectedRateContract != address(0));
        return expectedRateContract.getExpectedRate(source, dest, srcQuantity);
    }

    function getUserCapInWei(address user) public view returns(uint) {
        return kyberWhiteList.getUserCapInWei(user);
    }

    /// @notice use token address ETH_TOKEN_ADDRESS for ether
    /// @dev do one trade with a reserve
    /// @param source Source token
    /// @param amount amount of source tokens
    /// @param dest   Destination token
    /// @param destAddress Address to send tokens to
    /// @param reserve Reserve to use
    /// @param validate If true, additional validations are applicable
    /// @return true if trade is successful
    function doReserveTrade(
        ERC20 source,
        uint amount,
        ERC20 dest,
        address destAddress,
        uint expectedDestAmount,
        KyberReserve reserve,
        uint conversionRate,
        bool validate
    )
        internal
        returns(bool)
    {
        uint callValue = 0;

        if(source == ETH_TOKEN_ADDRESS) {
            callValue = amount;
        } else {
            // take source tokens to this contract
            source.transferFrom(msg.sender, this, amount);
        }

        // reserve send tokens/eth to network. network sends it to destination
        assert(reserve.trade.value(callValue)(source, amount, dest, this, conversionRate, validate));

        if(dest == ETH_TOKEN_ADDRESS) {
            destAddress.transfer(expectedDestAmount);
        } else {
            assert(dest.transfer(destAddress,expectedDestAmount));
        }

        return true;
    }

    /// @notice use token address ETH_TOKEN_ADDRESS for ether
    /// @dev checks that user sent ether/tokens to contract before trade
    /// @param source Source token
    /// @param srcAmount amount of source tokens
    /// @return true if input is valid
    function validateTradeInput(ERC20 source, uint srcAmount) internal view returns(bool) {
        require(srcAmount < MAX_QTY );
        if(source == ETH_TOKEN_ADDRESS) {
            require (msg.value == srcAmount);
        } else {
            require (msg.value == 0);
            require (source.allowance(msg.sender,this) >= srcAmount);
        }

        return true;
    }
}

contract SanityPricing is SanityPricingInterface, Withdrawable {
    mapping(bytes32=>uint) prices;

    function SanityPricing(address _admin) public {
        admin = _admin;
    }

    function setSanityPrices(ERC20[] sources, ERC20[] dests, uint[] rates) public onlyOperator {
        require(sources.length == dests.length);
        require(dests.length == rates.length);

        for(uint i = 0; i < sources.length; i++) {
            prices[keccak256(sources[i], dests[i])] = rates[i];
        }
    }

    function getSanityPrice(ERC20 src, ERC20 dest) view public returns(uint) {
        return prices[keccak256(src, dest)];
    }
}

contract FeeBurner is Withdrawable, FeeBurnerInterface {

    mapping(address=>uint) public reserveFeesInBps;
    mapping(address=>address) public reserveKNCWallet;
    mapping(address=>uint) public walletFeesInBps;

    mapping(address=>uint) public reserveFeeToBurn;
    mapping(address=>mapping(address=>uint)) public reserveFeeToWallet;

    BurnableToken public KNC;
    address public kyberNetwork;
    uint public KNCPerETHRate = 300;

    function FeeBurner(address _admin, BurnableToken KNCToken) public {
        admin = _admin;
        KNC = KNCToken;
    }

    function setReserveData(address reserve, uint feesInBps, address kncWallet) public onlyAdmin {
        require(feesInBps < 100); // make sure it is always < 1%
        reserveFeesInBps[reserve] = feesInBps;
        reserveKNCWallet[reserve] = kncWallet;
    }

    function setWalletFees(address wallet, uint feesInBps) public onlyAdmin {
        require(feesInBps < 10000); // under 100%
        walletFeesInBps[wallet] = feesInBps;
    }

    function setKyberNetwork(address network) public onlyAdmin {
        kyberNetwork = network;
    }

    function setKNCRate(uint rate) public onlyAdmin {
        KNCPerETHRate = rate;
    }

    event AssignFeeToWallet(address reserve, address wallet, uint walletFee);
    event BurnFees(address reserve, uint burnFee);

    function handleFees(uint tradeWeiAmount, address reserve, address wallet) public returns(bool) {
        require(msg.sender == kyberNetwork);

        uint kncAmount = tradeWeiAmount * KNCPerETHRate;
        uint fee = kncAmount * reserveFeesInBps[reserve] / 10000;

        uint walletFee = fee * walletFeesInBps[wallet] / 10000;
        assert(fee >= walletFee);
        uint feeToBurn = fee - walletFee;

        if(walletFee > 0) {
            reserveFeeToWallet[reserve][wallet] += walletFee;
            AssignFeeToWallet(reserve, wallet, walletFee);
        }

        if(feeToBurn > 0) {
            BurnFees(reserve, feeToBurn);
            reserveFeeToBurn[reserve] += feeToBurn;

        }

        return true;
    }

    // this function is callable by anyone
    event BurnReserveFees(address indexed reserve, address sender);
    function burnReserveFees(address reserve) public {
        uint burnAmount = reserveFeeToBurn[reserve];
        require(burnAmount > 0);
        reserveFeeToBurn[reserve] = 1; // leave 1 twei to avoid spikes in gas fee
        assert(KNC.burnFrom(reserveKNCWallet[reserve],burnAmount - 1));

        BurnReserveFees(reserve, msg.sender);
    }

    event SendFeeToWallet(address indexed wallet, address reserve, address sender);
    // this function is callable by anyone
    function sendFeeToWallet(address wallet, address reserve) public {
        uint feeAmount = reserveFeeToWallet[reserve][wallet];
        require(feeAmount > 0);
        reserveFeeToWallet[reserve][wallet] = 1; // leave 1 twei to avoid spikes in gas fee
        assert(KNC.transferFrom(reserveKNCWallet[reserve],wallet,feeAmount - 1));

        SendFeeToWallet(wallet,reserve,msg.sender);
    }
}

contract ExpectedRate is Withdrawable, ExpectedRateInterface {

    KyberNetwork kyberNetwork;
    uint public quantityFactor = 2;
    uint public minSlippageFactorInBps = 50;

    function ExpectedRate(KyberNetwork _kyberNetwork, address _admin) public {
        kyberNetwork = _kyberNetwork;
        admin = _admin;
    }

    event SetQuantityFactor (uint newFactor, uint oldFactor, address sender);

    function setQuantityFactor(uint newFactor) public onlyOperator {
        SetQuantityFactor(quantityFactor, newFactor, msg.sender);
        quantityFactor = newFactor;
    }

    event SetMinSlippageFactor (uint newMin, uint oldMin, address sender);

    function setMinSlippageFactor( uint bps ) public onlyOperator {
        SetMinSlippageFactor(bps,minSlippageFactorInBps,msg.sender);    
        minSlippageFactorInBps = bps;
    }

    function getExpectedRate(ERC20 source, ERC20 dest, uint srcQty)
        public view
        returns (uint expectedPrice, uint slippagePrice)
    {
        require (quantityFactor != 0);
        require (kyberNetwork != address (0));

        uint bestReserve;
        uint minSlippage;

        (bestReserve, expectedPrice) = kyberNetwork.findBestRate(source, dest, srcQty);
        (bestReserve, slippagePrice) = kyberNetwork.findBestRate(source, dest, (srcQty * quantityFactor));

        minSlippage = ((10000 - minSlippageFactorInBps) * expectedPrice) / 10000;
        if( slippagePrice >= minSlippage ) {
            slippagePrice = minSlippage;
        }

        return (expectedPrice, slippagePrice);
    }
}

contract VolumeImbalanceRecorder is Withdrawable {

    uint constant SLIDING_WINDOW_SIZE = 5;
    uint constant POW_2_64 = 2 ** 64;

    struct TokenControlInfo {
        uint minimalRecordResolution; // can be roughly 1 cent
        uint maxPerBlockImbalance; // in twei resolution
        uint maxTotalImbalance; // max total imbalance (without price updates)
                            // before halting trade
    }

    mapping(address => TokenControlInfo) tokenControlInfo;

    struct TokenImbalanceData {
        int  lastBlockBuyUnitsImbalance;
        uint lastBlock;

        int  totalBuyUnitsImbalance;
        uint lastPriceUpdateBlock;
    }

    mapping(address => mapping(uint=>uint)) tokenImbalanceData;

    function VolumeImbalanceRecorder(address _admin) public {
        admin = _admin;
    }

    function setTokenControlInfo(
        ERC20 token,
        uint minimalRecordResolution,
        uint maxPerBlockImbalance,
        uint maxTotalImbalance
    )
        public
        onlyAdmin
    {
        tokenControlInfo[token] =
            TokenControlInfo(
                minimalRecordResolution,
                maxPerBlockImbalance,
                maxTotalImbalance
            );
    }

    function getTokenControlInfo(ERC20 token) public view returns(uint, uint, uint) {
        return (tokenControlInfo[token].minimalRecordResolution,
                tokenControlInfo[token].maxPerBlockImbalance,
                tokenControlInfo[token].maxTotalImbalance);
    }

    function addImbalance(
        ERC20 token,
        int buyAmount,
        uint priceUpdateBlock,
        uint currentBlock
    )
        internal
    {
        uint currentBlockIndex = currentBlock % SLIDING_WINDOW_SIZE;
        int recordedBuyAmount = int(buyAmount / int(tokenControlInfo[token].minimalRecordResolution));

        int prevImbalance = 0;

        TokenImbalanceData memory currentBlockData = decodeTokenImbalanceData(tokenImbalanceData[token][currentBlockIndex]);

        // first scenario - this is not the first tx in the current block
        if(currentBlockData.lastBlock == currentBlock) {
            if(uint(currentBlockData.lastPriceUpdateBlock) == priceUpdateBlock) {
                // just increase imbalance
                currentBlockData.lastBlockBuyUnitsImbalance += recordedBuyAmount;
                currentBlockData.totalBuyUnitsImbalance += recordedBuyAmount;
            } else {
                // imbalance was changed in the middle of the block
                prevImbalance = getImbalanceInRange(token, priceUpdateBlock, currentBlock);
                currentBlockData.totalBuyUnitsImbalance = int(prevImbalance) + recordedBuyAmount;
                currentBlockData.lastBlockBuyUnitsImbalance += recordedBuyAmount;
                currentBlockData.lastPriceUpdateBlock = uint(priceUpdateBlock);
            }
        } else {
            // first tx in the current block
            int currentBlockImbalance;
            (prevImbalance, currentBlockImbalance) = getImbalanceSincePriceUpdate(token, priceUpdateBlock, currentBlock);

            currentBlockData.lastBlockBuyUnitsImbalance = recordedBuyAmount;
            currentBlockData.lastBlock = uint(currentBlock);
            currentBlockData.lastPriceUpdateBlock = uint(priceUpdateBlock);
            currentBlockData.totalBuyUnitsImbalance = int(prevImbalance) + recordedBuyAmount;
        }

        tokenImbalanceData[token][currentBlockIndex] = encodeTokenImbalanceData(currentBlockData);
    }

    function setGarbageToVolumeRecorder(ERC20 token) internal {
        for(uint i = 0 ; i < SLIDING_WINDOW_SIZE ; i++ ) {
            tokenImbalanceData[token][i] = 0x1;
        }
    }

    function getImbalanceInRange(ERC20 token, uint startBlock, uint endBlock) internal view returns(int buyImbalance) {
        // check the imbalance in the sliding window
        require(startBlock <= endBlock);

        buyImbalance = 0;

        for(uint windowInd = 0; windowInd < SLIDING_WINDOW_SIZE; windowInd++) {
            TokenImbalanceData memory perBlockData = decodeTokenImbalanceData(tokenImbalanceData[token][windowInd]);

            if(perBlockData.lastBlock <= endBlock && perBlockData.lastBlock >= startBlock) {
                buyImbalance += int(perBlockData.lastBlockBuyUnitsImbalance);
            }
        }
    }

    function getImbalanceSincePriceUpdate(ERC20 token, uint priceUpdateBlock, uint currentBlock)
        internal view
        returns(int buyImbalance, int currentBlockImbalance)
    {
        buyImbalance = 0;
        currentBlockImbalance = 0;
        uint latestBlock = 0;
        int imbalanceInRange = 0;
        uint startBlock = priceUpdateBlock;
        uint endBlock = currentBlock;

        for(uint windowInd = 0; windowInd < SLIDING_WINDOW_SIZE; windowInd++) {
            TokenImbalanceData memory perBlockData = decodeTokenImbalanceData(tokenImbalanceData[token][windowInd]);

            if(perBlockData.lastBlock <= endBlock && perBlockData.lastBlock >= startBlock) {
                imbalanceInRange += perBlockData.lastBlockBuyUnitsImbalance;
            }

            if(perBlockData.lastPriceUpdateBlock != priceUpdateBlock) continue;
            if(perBlockData.lastBlock < latestBlock) continue;

            latestBlock = perBlockData.lastBlock;
            buyImbalance = perBlockData.totalBuyUnitsImbalance;
            if(uint(perBlockData.lastBlock) == currentBlock) {
                currentBlockImbalance = perBlockData.lastBlockBuyUnitsImbalance;
            }
        }

        if(buyImbalance == 0) {
            buyImbalance = imbalanceInRange;
        }
    }

    function getImbalance(ERC20 token, uint priceUpdateBlock, uint currentBlock)
        internal view
        returns(int totalImbalance, int currentBlockImbalance)
    {

        int resolution = int(tokenControlInfo[token].minimalRecordResolution);

        (totalImbalance,currentBlockImbalance) = getImbalanceSincePriceUpdate(token,
                                                                              priceUpdateBlock,
                                                                              currentBlock);
        totalImbalance *= resolution;
        currentBlockImbalance *= resolution;
    }

    function getMaxPerBlockImbalance(ERC20 token) internal view returns(uint) {
        return tokenControlInfo[token].maxPerBlockImbalance;
    }

    function getMaxTotalImbalance(ERC20 token) internal view returns(uint) {
        return tokenControlInfo[token].maxTotalImbalance;
    }

    function encodeTokenImbalanceData(TokenImbalanceData data) internal pure returns(uint)  {
        uint result = uint(data.lastBlockBuyUnitsImbalance) & (POW_2_64 - 1);
        result |= data.lastBlock * POW_2_64;
        result |= (uint(data.totalBuyUnitsImbalance) & (POW_2_64 - 1)) * POW_2_64 * POW_2_64;
        result |= data.lastPriceUpdateBlock * POW_2_64 * POW_2_64 * POW_2_64;

        return result;
    }

    function decodeTokenImbalanceData(uint input) internal pure returns(TokenImbalanceData) {
        TokenImbalanceData memory data;

        data.lastBlockBuyUnitsImbalance = int(int64(input & (POW_2_64 - 1)));
        data.lastBlock = uint(uint64((input / POW_2_64) & (POW_2_64 - 1)));
        data.totalBuyUnitsImbalance = int(int64( (input / (POW_2_64 * POW_2_64)) & (POW_2_64 - 1)));
        data.lastPriceUpdateBlock = uint(uint64((input / (POW_2_64 * POW_2_64 * POW_2_64))));

        return data;
    }
}

contract Pricing is VolumeImbalanceRecorder, KyberConstants {

    // bps - basic price steps. one step is 1 / 10000 of the price.
    struct StepFunction {
        int[] x; // quantity for each step. Quantity of each step includes previous steps.
        int[] y; // price change per quantity step  in bps.
    }

    struct TokenData {
        bool listed;  // was added to reserve
        bool enabled; // whether trade is enabled

        // position in the compact data
        uint compactDataArrayIndex;
        uint compactDataFieldIndex;

        // price data. base and changes according to quantity and reserve balance.
        // generally speaking. Sell price is 1 / buy price i.e. the buy in the other direction.
        uint baseBuyPrice;  // in PRECISION units. see KyberConstants
        uint baseSellPrice; // PRECISION units. without (sell / buy) spread it is 1 / baseBuyPrice
        StepFunction buyPriceQtyStepFunction; // in bps. higher quantity - bigger the price.
        StepFunction sellPriceQtyStepFunction;// in bps. higher the qua
        StepFunction buyPriceImbalanceStepFunction; // in BPS. higher reserve imbalance - bigger the price.
        StepFunction sellPriceImbalanceStepFunction;
    }

    /*
    this is the data for tokenPricesCompactData
    but solidity compiler sucks, and cannot write this structure in a single storage write
    so we represent it as bytes32 and do the byte tricks ourselves.
    struct TokenPricesCompactData {
        bytes14 buy;  // change buy price of token from baseBuyPrice in 10 bps
        bytes14 sell; // change sell price of token from baseSellPrice in 10 bps

        uint32 blockNumber;
    } */

    uint public validPriceDurationInBlocks = 10; // prices are valid for this amount of blocks
    mapping(address=>TokenData) tokenData;
    bytes32[] tokenPricesCompactData;
    uint public numTokensInCurrentCompactData = 0;
    address public reserveContract;
    uint constant NUM_TOKENS_IN_COMPACT_DATA = 14;
    uint constant BYTES_14_OFFSET = (2 ** (8 * NUM_TOKENS_IN_COMPACT_DATA));

    function Pricing(address _admin) public VolumeImbalanceRecorder(_admin) { }

    function addToken(ERC20 token) public onlyAdmin {

        require(!tokenData[token].listed);
        tokenData[token].listed = true;

        if(numTokensInCurrentCompactData == 0) {
            tokenPricesCompactData.length++; // add new structure
        }

        tokenData[token].compactDataArrayIndex = tokenPricesCompactData.length - 1;
        tokenData[token].compactDataFieldIndex = numTokensInCurrentCompactData;

        numTokensInCurrentCompactData = (numTokensInCurrentCompactData + 1) % NUM_TOKENS_IN_COMPACT_DATA;

        setGarbageToVolumeRecorder(token);
    }

    function setCompactData(bytes14[] buy, bytes14[] sell, uint blockNumber, uint[] indices) public onlyOperator {

        require(buy.length == sell.length);
        require(indices.length == buy.length);

        uint bytes14Offset = BYTES_14_OFFSET;

        for(uint i = 0; i < indices.length; i++) {
            require(indices[i] < tokenPricesCompactData.length);
            uint data = uint(buy[i]) | uint(sell[i]) * bytes14Offset  | (blockNumber * (bytes14Offset*bytes14Offset));
            tokenPricesCompactData[indices[i]] = bytes32(data);
        }
    }

    function setBasePrice(
        ERC20[] tokens,
        uint[] baseBuy,
        uint[] baseSell,
        bytes14[] buy,
        bytes14[] sell,
        uint blockNumber,
        uint[] indices
    )
        public
        onlyOperator
    {
        require(tokens.length == baseBuy.length);
        require(tokens.length == baseSell.length);
        require(sell.length == buy.length);
        require(sell.length == indices.length);

        for(uint ind = 0; ind < tokens.length; ind++) {
            require(tokenData[tokens[ind]].listed);
            tokenData[tokens[ind]].baseBuyPrice = baseBuy[ind];
            tokenData[tokens[ind]].baseSellPrice = baseSell[ind];
        }

        setCompactData(buy, sell, blockNumber, indices);
    }

    function setQtyStepFunction(
        ERC20 token,
        int[] xBuy,
        int[] yBuy,
        int[] xSell,
        int[] ySell
    )
        public
        onlyOperator
    {
        require(xBuy.length == yBuy.length);
        require(xSell.length == ySell.length);
        require(tokenData[token].listed);

        tokenData[token].buyPriceQtyStepFunction = StepFunction(xBuy, yBuy);
        tokenData[token].sellPriceQtyStepFunction = StepFunction(xSell, ySell);
    }

    function setImbalanceStepFunction(
        ERC20 token,
        int[] xBuy,
        int[] yBuy,
        int[] xSell,
        int[] ySell
    )
        public
        onlyOperator
    {
        require(xBuy.length == yBuy.length);
        require(xSell.length == ySell.length);
        require(tokenData[token].listed);

        tokenData[token].buyPriceImbalanceStepFunction = StepFunction(xBuy, yBuy);
        tokenData[token].sellPriceImbalanceStepFunction = StepFunction(xSell, ySell);
    }

    function setValidPriceDurationInBlocks(uint duration) public onlyAdmin {
        validPriceDurationInBlocks = duration;
    }

    function enableTokenTrade(ERC20 token) public onlyAdmin {
        require(tokenData[token].listed);
        require(tokenControlInfo[token].minimalRecordResolution != 0);
        tokenData[token].enabled = true;
    }

    function disableTokenTrade(ERC20 token) public onlyAlerter {
        require(tokenData[token].listed);
        tokenData[token].enabled = false;
    }

    function setReserveAddress(address reserve) public onlyAdmin {
        reserveContract = reserve;
    }

    function recordImbalance(
        ERC20 token,
        int buyAmount,
        uint priceUpdateBlock,
        uint currentBlock
    )
        public
    {
        require(msg.sender == reserveContract);

        return addImbalance(token, buyAmount, priceUpdateBlock, currentBlock);
    }

    function getPrice(ERC20 token, uint currentBlockNumber, bool buy, uint qty) public view returns(uint) {
        // check if trade is enabled
        if(!tokenData[token].enabled) return 0;
        if(tokenControlInfo[token].minimalRecordResolution == 0) return 0; // token control info not set

        // get price update block
        bytes32 compactData = tokenPricesCompactData[tokenData[token].compactDataArrayIndex];

        uint updatePriceBlock = getLast4Bytes(compactData);
        if(currentBlockNumber >= updatePriceBlock + validPriceDurationInBlocks) return 0; // price is expired
        // check imbalance
        int totalImbalance;
        int blockImbalance;
        (totalImbalance, blockImbalance) = getImbalance(token, updatePriceBlock, currentBlockNumber);

        int imbalanceQty;

        // calculate actual price
        int extraBps;
        int8 priceUpdate;
        uint price;

        if(buy) {
            // start with base price
            price = tokenData[token].baseBuyPrice;

            // add price update
            priceUpdate = getPriceByteFromCompactData(compactData,token,true);
            extraBps = int(priceUpdate) * 10;
            price = addBps(price, extraBps);

            // compute token qty
            qty = getTokenQty(token, price, qty);
            imbalanceQty = int(qty);
            totalImbalance += imbalanceQty;

            // add qty overhead
            extraBps = executeStepFunction(tokenData[token].buyPriceQtyStepFunction, int(qty));
            price = addBps(price, extraBps);

            // add imbalance overhead
            extraBps = executeStepFunction(tokenData[token].buyPriceImbalanceStepFunction, totalImbalance);
            price = addBps(price, extraBps);

        } else {
            // start with base price
            price = tokenData[token].baseSellPrice;

            // add price update
            priceUpdate = getPriceByteFromCompactData(compactData,token,false);
            extraBps = int(priceUpdate) * 10;
            price = addBps(price, extraBps);

            // compute token qty
            imbalanceQty = -1 * int(qty);
            totalImbalance += imbalanceQty;

            // add qty overhead
            extraBps = executeStepFunction(tokenData[token].sellPriceQtyStepFunction, int(qty));
            price = addBps(price, extraBps);

            // add imbalance overhead
            extraBps = executeStepFunction(tokenData[token].sellPriceImbalanceStepFunction, totalImbalance);
            price = addBps(price, extraBps);

        }

        if(abs(totalImbalance + imbalanceQty) >= getMaxTotalImbalance(token)) return 0;
        if(abs(blockImbalance + imbalanceQty) >= getMaxPerBlockImbalance(token)) return 0;

        return price;
    }

    function getBasicPrice(ERC20 token, bool buy) public view returns(uint) {
        if(buy) return tokenData[token].baseBuyPrice;
        else return tokenData[token].baseSellPrice;
    }

    function getCompactData(ERC20 token) public view returns(uint, uint, byte, byte) {
        uint arrayIndex = tokenData[token].compactDataArrayIndex;
        uint fieldOffset = tokenData[token].compactDataFieldIndex;

        return (
            arrayIndex,
            fieldOffset,
            byte(getPriceByteFromCompactData(tokenPricesCompactData[arrayIndex], token, true)),
            byte(getPriceByteFromCompactData(tokenPricesCompactData[arrayIndex],token, false))
        );
    }

    function getPriceUpdateBlock(ERC20 token) public view returns(uint) {
        bytes32 compactData = tokenPricesCompactData[tokenData[token].compactDataArrayIndex];
        return getLast4Bytes(compactData);
    }

    function getTokenQty(ERC20 token, uint ethQty, uint rate) internal view returns(uint) {
        uint dstDecimals = token.decimals();
        uint srcDecimals = 18;

        return calcDstQty(ethQty,srcDecimals,dstDecimals,rate);
    }

    function getLast4Bytes(bytes32 b) pure internal returns(uint) {
        // cannot trust compiler with not turning bit operations into EXP opcode
        return uint(b) / (BYTES_14_OFFSET * BYTES_14_OFFSET);
    }

    function getPriceByteFromCompactData(bytes32 data, ERC20 token, bool buy) view internal returns(int8) {
        uint fieldOffset = tokenData[token].compactDataFieldIndex;
        uint byteOffset;
        if(buy) byteOffset = 32 - NUM_TOKENS_IN_COMPACT_DATA + fieldOffset;
        else byteOffset = 4 + fieldOffset;

        return int8(data[byteOffset]);
    }

    function executeStepFunction(StepFunction f, int x) pure internal returns(int) {
        uint len = f.y.length;
        for(uint ind = 0; ind < len; ind++) {
            if(x <= f.x[ind]) return f.y[ind];
        }

        return f.y[len-1];
    }

    function addBps(uint price, int bps) pure internal returns(uint) {
        uint maxBps = 100 * 100;
        return (price * uint(int(maxBps) + bps)) / maxBps;
    }

    function abs(int x) pure internal returns(uint) {
        if(x < 0) return uint(-1 * x);
        else return uint(x);
    }
}

    Contract ABI  
[{"constant":false,"inputs":[{"name":"alerter","type":"address"}],"name":"removeAlerter","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"reserve","type":"address"},{"name":"source","type":"address"},{"name":"dest","type":"address"},{"name":"add","type":"bool"}],"name":"listPairForReserve","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"kyberWhiteList","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getReserves","outputs":[{"name":"","type":"address[]"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"pendingAdmin","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getOperators","outputs":[{"name":"","type":"address[]"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"negligiblePriceDiff","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"token","type":"address"},{"name":"amount","type":"uint256"},{"name":"sendTo","type":"address"}],"name":"withdrawToken","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"maxGasPrice","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"newAlerter","type":"address"}],"name":"addAlerter","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"feeBurnerContract","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"expectedRateContract","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"user","type":"address"}],"name":"getUserCapInWei","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"newAdmin","type":"address"}],"name":"transferAdmin","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_enable","type":"bool"}],"name":"setEnable","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[],"name":"claimAdmin","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"","type":"address"}],"name":"isReserve","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getAlerters","outputs":[{"name":"","type":"address[]"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"source","type":"address"},{"name":"dest","type":"address"},{"name":"srcQuantity","type":"uint256"}],"name":"getExpectedRate","outputs":[{"name":"expectedPrice","type":"uint256"},{"name":"slippagePrice","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"","type":"uint256"}],"name":"reserves","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"newOperator","type":"address"}],"name":"addOperator","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"reserve","type":"address"},{"name":"add","type":"bool"}],"name":"addReserve","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"enable","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"operator","type":"address"}],"name":"removeOperator","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"source","type":"address"},{"name":"srcAmount","type":"uint256"},{"name":"dest","type":"address"},{"name":"destAddress","type":"address"},{"name":"maxDestAmount","type":"uint256"},{"name":"minConversionRate","type":"uint256"},{"name":"walletId","type":"address"}],"name":"walletTrade","outputs":[{"name":"","type":"uint256"}],"payable":true,"stateMutability":"payable","type":"function"},{"constant":false,"inputs":[{"name":"_whiteList","type":"address"},{"name":"_expectedRate","type":"address"},{"name":"_feeBurner","type":"address"},{"name":"_maxGasPrice","type":"uint256"},{"name":"_negligibleDiff","type":"uint256"}],"name":"setParams","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"source","type":"address"},{"name":"dest","type":"address"},{"name":"srcQty","type":"uint256"}],"name":"findBestRate","outputs":[{"name":"","type":"uint256"},{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"source","type":"address"},{"name":"srcAmount","type":"uint256"},{"name":"dest","type":"address"},{"name":"destAddress","type":"address"},{"name":"maxDestAmount","type":"uint256"},{"name":"minConversionRate","type":"uint256"},{"name":"walletId","type":"address"}],"name":"trade","outputs":[{"name":"","type":"uint256"}],"payable":true,"stateMutability":"payable","type":"function"},{"constant":false,"inputs":[{"name":"amount","type":"uint256"},{"name":"sendTo","type":"address"}],"name":"withdrawEther","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"getNumReserves","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"token","type":"address"},{"name":"user","type":"address"}],"name":"getBalance","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"admin","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"inputs":[{"name":"_admin","type":"address"}],"payable":false,"stateMutability":"nonpayable","type":"constructor"},{"payable":true,"stateMutability":"payable","type":"fallback"},{"anonymous":false,"inputs":[{"indexed":true,"name":"sender","type":"address"},{"indexed":false,"name":"source","type":"address"},{"indexed":false,"name":"dest","type":"address"},{"indexed":false,"name":"actualSrcAmount","type":"uint256"},{"indexed":false,"name":"actualDestAmount","type":"uint256"}],"name":"Trade","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"reserve","type":"address"},{"indexed":false,"name":"add","type":"bool"}],"name":"AddReserve","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"reserve","type":"address"},{"indexed":false,"name":"source","type":"address"},{"indexed":false,"name":"dest","type":"address"},{"indexed":false,"name":"add","type":"bool"}],"name":"ListPairsForReserve","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"sender","type":"address"},{"indexed":false,"name":"amount","type":"uint256"}],"name":"EtherReceival","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"token","type":"address"},{"indexed":false,"name":"amount","type":"uint256"},{"indexed":false,"name":"sendTo","type":"address"}],"name":"WithdrawToken","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"amount","type":"uint256"},{"indexed":false,"name":"sendTo","type":"address"}],"name":"WithdrawEther","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"pendingAdmin","type":"address"}],"name":"TransferAdmin","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"newAdmin","type":"address"},{"indexed":false,"name":"previousAdmin","type":"address"}],"name":"ClaimAdmin","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"newAlerter","type":"address"},{"indexed":false,"name":"isAdd","type":"bool"}],"name":"AddAlerter","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"newOperator","type":"address"},{"indexed":false,"name":"isAdd","type":"bool"}],"name":"AddOperator","type":"event"}]

  Contract Creation Code Switch To Opcodes View
6060604052600a600655640ba43b7400600c556001600d60006101000a81548160ff021916908315150217905550341561003857600080fd5b60405160208061416e83398101604052808051906020019091905050336000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550806000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505061408a806100e46000396000f300606060405260043610610196576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff16806301a12fd31461023e57806303141fcd14610277578063036a6195146102f95780630902f1ac1461034e57806326782247146103b857806327a099d81461040d5780633b075f93146104775780633ccdbb28146104a05780633de39c1114610501578063408ee7fe1461052a578063579425b7146105635780635dada964146105b85780636432679f1461060d57806375829def1461065a5780637726bed31461069357806377f50f97146106b85780637a2b0587146106cd5780637c423f541461071e578063809a9e55146107885780638334278d146108045780639870d7fe14610867578063a0d7bb1b146108a0578063a3907d71146108e4578063ac8a584a14610911578063b02cbe1a1461094a578063b5caadf214610a04578063b8388aca14610a8d578063cb3c28c714610b09578063ce56c45414610bc3578063cfff25bb14610c05578063d4fac45d14610c2e578063f851a44014610c9a575b600860003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff1615156101ee57600080fd5b3373ffffffffffffffffffffffffffffffffffffffff167f75f33ed68675112c77094e7c5b073890598be1d23e27cd7f6907b4a7d98ac619346040518082815260200191505060405180910390a2005b341561024957600080fd5b610275600480803573ffffffffffffffffffffffffffffffffffffffff16906020019091905050610cef565b005b341561028257600080fd5b6102f7600480803573ffffffffffffffffffffffffffffffffffffffff1690602001909190803573ffffffffffffffffffffffffffffffffffffffff1690602001909190803573ffffffffffffffffffffffffffffffffffffffff169060200190919080351515906020019091905050610fb1565b005b341561030457600080fd5b61030c6113f0565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b341561035957600080fd5b610361611416565b6040518080602001828103825283818151815260200191508051906020019060200280838360005b838110156103a4578082015181840152602081019050610389565b505050509050019250505060405180910390f35b34156103c357600080fd5b6103cb6114aa565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b341561041857600080fd5b6104206114d0565b6040518080602001828103825283818151815260200191508051906020019060200280838360005b83811015610463578082015181840152602081019050610448565b505050509050019250505060405180910390f35b341561048257600080fd5b61048a611564565b6040518082815260200191505060405180910390f35b34156104ab57600080fd5b6104ff600480803573ffffffffffffffffffffffffffffffffffffffff1690602001909190803590602001909190803573ffffffffffffffffffffffffffffffffffffffff1690602001909190505061156a565b005b341561050c57600080fd5b610514611737565b6040518082815260200191505060405180910390f35b341561053557600080fd5b610561600480803573ffffffffffffffffffffffffffffffffffffffff1690602001909190505061173d565b005b341561056e57600080fd5b61057661191f565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b34156105c357600080fd5b6105cb611945565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b341561061857600080fd5b610644600480803573ffffffffffffffffffffffffffffffffffffffff1690602001909190505061196b565b6040518082815260200191505060405180910390f35b341561066557600080fd5b610691600480803573ffffffffffffffffffffffffffffffffffffffff16906020019091905050611a54565b005b341561069e57600080fd5b6106b660048080351515906020019091905050611bb4565b005b34156106c357600080fd5b6106cb611c2c565b005b34156106d857600080fd5b610704600480803573ffffffffffffffffffffffffffffffffffffffff16906020019091905050611e08565b604051808215151515815260200191505060405180910390f35b341561072957600080fd5b610731611e28565b6040518080602001828103825283818151815260200191508051906020019060200280838360005b83811015610774578082015181840152602081019050610759565b505050509050019250505060405180910390f35b341561079357600080fd5b6107e7600480803573ffffffffffffffffffffffffffffffffffffffff1690602001909190803573ffffffffffffffffffffffffffffffffffffffff16906020019091908035906020019091905050611ebc565b604051808381526020018281526020019250505060405180910390f35b341561080f57600080fd5b610825600480803590602001909190505061204a565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b341561087257600080fd5b61089e600480803573ffffffffffffffffffffffffffffffffffffffff16906020019091905050612089565b005b34156108ab57600080fd5b6108e2600480803573ffffffffffffffffffffffffffffffffffffffff16906020019091908035151590602001909190505061226b565b005b34156108ef57600080fd5b6108f7612617565b604051808215151515815260200191505060405180910390f35b341561091c57600080fd5b610948600480803573ffffffffffffffffffffffffffffffffffffffff1690602001909190505061262a565b005b6109ee600480803573ffffffffffffffffffffffffffffffffffffffff1690602001909190803590602001909190803573ffffffffffffffffffffffffffffffffffffffff1690602001909190803573ffffffffffffffffffffffffffffffffffffffff1690602001909190803590602001909190803590602001909190803573ffffffffffffffffffffffffffffffffffffffff169060200190919050506128ef565b6040518082815260200191505060405180910390f35b3415610a0f57600080fd5b610a8b600480803573ffffffffffffffffffffffffffffffffffffffff1690602001909190803573ffffffffffffffffffffffffffffffffffffffff1690602001909190803573ffffffffffffffffffffffffffffffffffffffff1690602001909190803590602001909190803590602001909190505061290d565b005b3415610a9857600080fd5b610aec600480803573ffffffffffffffffffffffffffffffffffffffff1690602001909190803573ffffffffffffffffffffffffffffffffffffffff16906020019091908035906020019091905050612a40565b604051808381526020018281526020019250505060405180910390f35b610bad600480803573ffffffffffffffffffffffffffffffffffffffff1690602001909190803590602001909190803573ffffffffffffffffffffffffffffffffffffffff1690602001909190803573ffffffffffffffffffffffffffffffffffffffff1690602001909190803590602001909190803590602001909190803573ffffffffffffffffffffffffffffffffffffffff16906020019091905050612e8d565b6040518082815260200191505060405180910390f35b3415610bce57600080fd5b610c03600480803590602001909190803573ffffffffffffffffffffffffffffffffffffffff1690602001909190505061310b565b005b3415610c1057600080fd5b610c18613215565b6040518082815260200191505060405180910390f35b3415610c3957600080fd5b610c84600480803573ffffffffffffffffffffffffffffffffffffffff1690602001909190803573ffffffffffffffffffffffffffffffffffffffff16906020019091905050613222565b6040518082815260200191505060405180910390f35b3415610ca557600080fd5b610cad613352565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141515610d4c57600080fd5b600360008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff161515610da457600080fd5b6000600360008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff021916908315150217905550600090505b600580549050811015610fad578173ffffffffffffffffffffffffffffffffffffffff16600582815481101515610e3457fe5b906000526020600020900160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff161415610fa2576005600160058054905003815481101515610e9357fe5b906000526020600020900160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16600582815481101515610ece57fe5b906000526020600020900160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506005805480919060019003610f2c9190613f4d565b507f483b8090fb9483248853509c7f556286f45c7c554beaa8cd132546f774202a4d826000604051808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001821515151581526020019250505060405180910390a1610fad565b806001019050610e01565b5050565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614151561100c57600080fd5b80600e60008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008585604051808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166c010000000000000000000000000281526014018273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166c010000000000000000000000000281526014019250505060405180910390206000191660001916815260200190815260200160002060006101000a81548160ff02191690831515021790555073eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee73ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1614151561131357801561124a578273ffffffffffffffffffffffffffffffffffffffff1663095ea7b3857f80000000000000000000000000000000000000000000000000000000000000006000604051602001526040518363ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200182815260200192505050602060405180830381600087803b151561122957600080fd5b6102c65a03f1151561123a57600080fd5b5050506040518051905050611312565b8273ffffffffffffffffffffffffffffffffffffffff1663095ea7b385600080604051602001526040518363ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200182815260200192505050602060405180830381600087803b15156112f557600080fd5b6102c65a03f1151561130657600080fd5b50505060405180519050505b5b7ffec320f49e655894166933e8c35f01cdb484dc623f4fb53441633fbedb78dba884848484604051808573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018215151515815260200194505050505060405180910390a150505050565b600960009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b61141e613f79565b60078054806020026020016040519081016040528092919081815260200182805480156114a057602002820191906000526020600020905b8160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019060010190808311611456575b5050505050905090565b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6114d8613f8d565b600480548060200260200160405190810160405280929190818152602001828054801561155a57602002820191906000526020600020905b8160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019060010190808311611510575b5050505050905090565b60065481565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415156115c557600080fd5b8273ffffffffffffffffffffffffffffffffffffffff1663a9059cbb82846000604051602001526040518363ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200182815260200192505050602060405180830381600087803b151561167057600080fd5b6102c65a03f1151561168157600080fd5b50505060405180519050151561169357fe5b7fc7de2d139afb8c4257b3fac58f791fb657180f2f86753ed057e0c3a404f705a3838383604051808473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018381526020018273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001935050505060405180910390a1505050565b600c5481565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614151561179857600080fd5b600360008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff161515156117f157600080fd5b7f483b8090fb9483248853509c7f556286f45c7c554beaa8cd132546f774202a4d816001604051808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001821515151581526020019250505060405180910390a16001600360008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff021916908315150217905550600580548060010182816118cd9190613fa1565b9160005260206000209001600083909190916101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505050565b600b60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600a60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6000600960009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16636432679f836000604051602001526040518263ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001915050602060405180830381600087803b1515611a3257600080fd5b6102c65a03f11515611a4357600080fd5b505050604051805190509050919050565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141515611aaf57600080fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614151515611aeb57600080fd5b7fda7b0a7bc965abdec8a1a995575a891838264c2968e14bd456c5391827b7aa30600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a180600160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141515611c0f57600080fd5b80600d60006101000a81548160ff02191690831515021790555050565b3373ffffffffffffffffffffffffffffffffffffffff16600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16141515611c8857600080fd5b7f60cae9fabd3bef6b015e14f55d6c66df6c507bbacdb16149e2bf7c440690da27600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff166000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff16604051808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019250505060405180910390a1600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff166000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506000600160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550565b60086020528060005260406000206000915054906101000a900460ff1681565b611e30613f8d565b6005805480602002602001604051908101604052809291908181526020018280548015611eb257602002820191906000526020600020905b8160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019060010190808311611e68575b5050505050905090565b600080600073ffffffffffffffffffffffffffffffffffffffff16600a60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614151515611f1d57600080fd5b600a60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663809a9e558686866000604051604001526040518463ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200182815260200193505050506040805180830381600087803b151561201d57600080fd5b6102c65a03f1151561202e57600080fd5b5050506040518051906020018051905091509150935093915050565b60078181548110151561205957fe5b90600052602060002090016000915054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415156120e457600080fd5b600260008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff1615151561213d57600080fd5b7fbadd5a134a60c76befc7e7d53706d47a82ac7037171f88c24a7f70faa2998ef1816001604051808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001821515151581526020019250505060405180910390a16001600260008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff021916908315150217905550600480548060010182816122199190613fa1565b9160005260206000209001600083909190916101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505050565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415156122c857600080fd5b81156123fe57600780548060010182816122e29190613fcd565b9160005260206000209001600085909190916101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550506001600860008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055507f7fb71e76e724c32dea5a20b853f4e3a5878fde6e20ced9c2d40ec3257cb49416836001604051808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001821515151581526020019250505060405180910390a1612611565b6000600860008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff021916908315150217905550600090505b600780549050811015612610578273ffffffffffffffffffffffffffffffffffffffff1660078281548110151561248e57fe5b906000526020600020900160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16141561260357600060078054905014156124e957612612565b60078080546001900390816124fe9190613ff9565b81548110151561250a57fe5b906000526020600020900160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1660078281548110151561254557fe5b906000526020600020900160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055507f7fb71e76e724c32dea5a20b853f4e3a5878fde6e20ced9c2d40ec3257cb49416836000604051808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001821515151581526020019250505060405180910390a1612610565b808060010191505061245b565b5b5b505050565b600d60009054906101000a900460ff1681565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614151561268757600080fd5b600260008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff1615156126df57600080fd5b6000600260008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff021916908315150217905550600090505b6004805490508110156128eb578173ffffffffffffffffffffffffffffffffffffffff1660048281548110151561276f57fe5b906000526020600020900160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614156128e05760046001600480549050038154811015156127ce57fe5b906000526020600020900160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1660048281548110151561280957fe5b906000526020600020900160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550600160048181805490500391508161286a9190613f4d565b507fbadd5a134a60c76befc7e7d53706d47a82ac7037171f88c24a7f70faa2998ef1826000604051808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001821515151581526020019250505060405180910390a16128eb565b80600101905061273c565b5050565b600061290088888888888888612e8d565b9050979650505050505050565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614151561296857600080fd5b84600960006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555083600a60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555082600b60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555081600c81905550806006819055505050505050565b600080600080600080612a51614025565b612a59614025565b60008060008098506000975060009650600780549050955085604051805910612a7f5750595b9080825280602002602001820160405250945085604051805910612aa05750595b90808252806020026020018201604052509350600092505b85831015612d9e57600e6000600785815481101515612ad357fe5b906000526020600020900160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008f8f604051808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166c010000000000000000000000000281526014018273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166c010000000000000000000000000281526014019250505060405180910390206000191660001916815260200190815260200160002060009054906101000a900460ff161515612bfe57612d91565b600783815481101515612c0d57fe5b906000526020600020900160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16637cd442728f8f8f436000604051602001526040518563ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001838152602001828152602001945050505050602060405180830381600087803b1515612d1f57600080fd5b6102c65a03f11515612d3057600080fd5b505050604051805190508584815181101515612d4857fe5b9060200190602002018181525050888584815181101515612d6557fe5b906020019060200201511115612d90578483815181101515612d8357fe5b9060200190602002015198505b5b8280600101935050612ab8565b6000891115612e765760009150600654612710016127108a02811515612dc057fe5b049050600092505b85831015612e2157808584815181101515612ddf57fe5b90602001906020020151101515612e1457828488806001019950815181101515612e0557fe5b90602001906020020181815250505b8280600101935050612dc8565b6001871115612e415786600143034060019004811515612e3d57fe5b0691505b8382815181101515612e4f57fe5b9060200190602002015197508488815181101515612e6957fe5b9060200190602002015198505b87899a509a50505050505050505050935093915050565b6000806000806000806000600d60009054906101000a900460ff161515612eb357600080fd5b612ebd8e33613222565b9550612ec98c8c613222565b93506000612edc8f8f8f8f8f8f8f613377565b111515612ee557fe5b612eef8e33613222565b9450612efb8c8c613222565b9250858511151515612f0c57600080fd5b838310151515612f1b57600080fd5b73eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee73ffffffffffffffffffffffffffffffffffffffff168e73ffffffffffffffffffffffffffffffffffffffff161415612f6c5760129150612ff6565b8d73ffffffffffffffffffffffffffffffffffffffff1663313ce5676000604051602001526040518163ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401602060405180830381600087803b1515612fd857600080fd5b6102c65a03f11515612fe957600080fd5b5050506040518051905091505b73eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee73ffffffffffffffffffffffffffffffffffffffff168c73ffffffffffffffffffffffffffffffffffffffff16141561304757601290506130d1565b8b73ffffffffffffffffffffffffffffffffffffffff1663313ce5676000604051602001526040518163ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401602060405180830381600087803b15156130b357600080fd5b6102c65a03f115156130c457600080fd5b5050506040518051905090505b670de0b6b3a764000082600a0a858503020281600a0a8a8789030202111515156130fa57600080fd5b505050505050979650505050505050565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614151561316657600080fd5b8073ffffffffffffffffffffffffffffffffffffffff166108fc839081150290604051600060405180830381858888f1935050505015156131a657600080fd5b7fc82aba305b4a836b632cf1783a60b69af4f4b88b73d07be6fdf3ee5bfb2c7b358282604051808381526020018273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019250505060405180910390a15050565b6000600780549050905090565b600073eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee73ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16141561328b578173ffffffffffffffffffffffffffffffffffffffff1631905061334c565b8273ffffffffffffffffffffffffffffffffffffffff166370a08231836000604051602001526040518263ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001915050602060405180830381600087803b151561332e57600080fd5b6102c65a03f1151561333f57600080fd5b5050506040518051905090505b92915050565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6000806000806000806000600c543a1115151561339357600080fd5b600073ffffffffffffffffffffffffffffffffffffffff16600960009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16141515156133f157600080fd5b600073ffffffffffffffffffffffffffffffffffffffff16600b60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff161415151561344f57600080fd5b6134598e8e613789565b151561346457600080fd5b61346f8e8d8f612a40565b809650819750505060078681548110151561348657fe5b906000526020600020900160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1693506000851115156134c057fe5b620f4240670de0b6b3a764000002851015156134d857fe5b8885101515156134e457fe5b8c92506134f38e8d858861391a565b91508982111561350f5789915061350c8e8d8488613942565b92505b73eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee73ffffffffffffffffffffffffffffffffffffffff168e73ffffffffffffffffffffffffffffffffffffffff16141561355f57829050613563565b8190505b61356c3361196b565b811115151561357a57600080fd5b61358b8e848e8e86898b600161396a565b151561359357fe5b600b60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663fd062d3b82868b6000604051602001526040518463ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808481526020018373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019350505050602060405180830381600087803b151561369457600080fd5b6102c65a03f115156136a557600080fd5b5050506040518051905015156136b757fe5b3373ffffffffffffffffffffffffffffffffffffffff167fec0d3e799aa270a144d7e3be084ccfc657450e33ecea1b1a4154c95cedaae5c38f8e8686604051808573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200183815260200182815260200194505050505060405180910390a2819650505050505050979650505050505050565b60006b204fce5e3e25026110000000821015156137a557600080fd5b73eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee73ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1614156138005781341415156137fb57600080fd5b613910565b60003414151561380f57600080fd5b818373ffffffffffffffffffffffffffffffffffffffff1663dd62ed3e33306000604051602001526040518363ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200192505050602060405180830381600087803b15156138e757600080fd5b6102c65a03f115156138f857600080fd5b505050604051805190501015151561390f57600080fd5b5b6001905092915050565b60006139388361392987613d75565b61393287613d75565b85613e57565b9050949350505050565b60006139608361395187613d75565b61395a87613d75565b85613ed2565b9050949350505050565b6000806000905073eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee73ffffffffffffffffffffffffffffffffffffffff168a73ffffffffffffffffffffffffffffffffffffffff1614156139c157889050613abd565b8973ffffffffffffffffffffffffffffffffffffffff166323b872dd33308c6000604051602001526040518463ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018281526020019350505050602060405180830381600087803b1515613aa057600080fd5b6102c65a03f11515613ab157600080fd5b50505060405180519050505b8473ffffffffffffffffffffffffffffffffffffffff16636cf69811828c8c8c308a8a6000604051602001526040518863ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018681526020018573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018381526020018215151515815260200196505050505050506020604051808303818588803b1515613be457600080fd5b6125ee5a03f11515613bf557600080fd5b50505050604051805190501515613c0857fe5b73eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee73ffffffffffffffffffffffffffffffffffffffff168873ffffffffffffffffffffffffffffffffffffffff161415613c95578673ffffffffffffffffffffffffffffffffffffffff166108fc879081150290604051600060405180830381858888f193505050501515613c9057600080fd5b613d64565b8773ffffffffffffffffffffffffffffffffffffffff1663a9059cbb88886000604051602001526040518363ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200182815260200192505050602060405180830381600087803b1515613d4057600080fd5b6102c65a03f11515613d5157600080fd5b505050604051805190501515613d6357fe5b5b600191505098975050505050505050565b600073eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415613dc85760129050613e52565b8173ffffffffffffffffffffffffffffffffffffffff1663313ce5676000604051602001526040518163ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401602060405180830381600087803b1515613e3457600080fd5b6102c65a03f11515613e4557600080fd5b5050506040518051905090505b919050565b60008383101515613e9857601284840311151515613e7457600080fd5b670de0b6b3a7640000848403600a0a83870202811515613e9057fe5b049050613eca565b601283850311151515613eaa57600080fd5b828403600a0a670de0b6b3a764000002828602811515613ec657fe5b0490505b949350505050565b60008284101515613f1357601283850311151515613eef57600080fd5b81838503600a0a86670de0b6b3a76400000202811515613f0b57fe5b049050613f45565b601284840311151515613f2557600080fd5b838303600a0a820285670de0b6b3a764000002811515613f4157fe5b0490505b949350505050565b815481835581811511613f7457818360005260206000209182019101613f739190614039565b5b505050565b602060405190810160405280600081525090565b602060405190810160405280600081525090565b815481835581811511613fc857818360005260206000209182019101613fc79190614039565b5b505050565b815481835581811511613ff457818360005260206000209182019101613ff39190614039565b5b505050565b8154818355818115116140205781836000526020600020918201910161401f9190614039565b5b505050565b602060405190810160405280600081525090565b61405b91905b8082111561405757600081600090555060010161403f565b5090565b905600a165627a7a723058203a87ef3514d67149d017675828e12a3af8e4226db5310773ae91067d65188de80029000000000000000000000000bf3a8018427994b1c9f5bede3e0efa7954c50efc

    Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
000000000000000000000000bf3a8018427994b1c9f5bede3e0efa7954c50efc

-----Encoded View---------------
1 Constructor Arguments found :
Arg [0] : 000000000000000000000000bf3a8018427994b1c9f5bede3e0efa7954c50efc


   Swarm Source:
bzzr://3a87ef3514d67149d017675828e12a3af8e4226db5310773ae91067d65188de8

 

View All
Block Age transaction Difficulty GasUsed Reward
View All
Block Age UncleNumber Difficulty GasUsed Reward