Contract 0xfe96c7566c5f5d5555ebdc88b687456081114ebe

Contract Overview

Balance:
0 BNB
Txn Hash Method
Block
From
To
Value [Txn Fee]
0x7e84977791f9fb69e042984f788e1280c094a128bf15c302ee773996fdac90d4Set Compact Data95602782021-06-08 18:48:41176 days 15 hrs ago0xb517423119cbaa15b4385cffab0e00bde170dd6a IN  0xfe96c7566c5f5d5555ebdc88b687456081114ebe0 BNB0.00063172
0x326e6f4d8263a35e5000272ae9e02426391386b1a21e984545e2ecf5a49a6824Set Compact Data95602172021-06-08 18:45:38176 days 15 hrs ago0xb517423119cbaa15b4385cffab0e00bde170dd6a IN  0xfe96c7566c5f5d5555ebdc88b687456081114ebe0 BNB0.00063172
0x67fe74353c6d9a6d1877f77cb626f9d026303f034bff3d96f4727947bb1802f4Set Compact Data95601572021-06-08 18:42:38176 days 15 hrs ago0xb517423119cbaa15b4385cffab0e00bde170dd6a IN  0xfe96c7566c5f5d5555ebdc88b687456081114ebe0 BNB0.00063172
0x5ee26279608c26c6f716f855fc194c8c7f9f57ccc1bd9b4b3aa0caa0bd2849efSet Compact Data95600952021-06-08 18:39:32176 days 15 hrs ago0xb517423119cbaa15b4385cffab0e00bde170dd6a IN  0xfe96c7566c5f5d5555ebdc88b687456081114ebe0 BNB0.00063172
0x46a50e89fb4e8231dbffecc89b46c360c27797e0bac6e06d5eade848d90c4679Set Compact Data95600352021-06-08 18:36:32176 days 15 hrs ago0xb517423119cbaa15b4385cffab0e00bde170dd6a IN  0xfe96c7566c5f5d5555ebdc88b687456081114ebe0 BNB0.00063172
0xd068da850dddd8d1e553a9be89b5229abb766ff5c334d0c5d3ff096209d68a7cSet Compact Data95599722021-06-08 18:33:23176 days 15 hrs ago0xb517423119cbaa15b4385cffab0e00bde170dd6a IN  0xfe96c7566c5f5d5555ebdc88b687456081114ebe0 BNB0.00063172
0xd62ada34de344c8b9b80f885da011527ff406d1b5f82353d7262408b784a5fc0Set Compact Data95599122021-06-08 18:30:23176 days 16 hrs ago0xb517423119cbaa15b4385cffab0e00bde170dd6a IN  0xfe96c7566c5f5d5555ebdc88b687456081114ebe0 BNB0.00063172
0xc8f8d936515e2f2ad32ad96cce2b1745f6a0686eee6ea493f179d3f67dcd2e7cSet Compact Data95598512021-06-08 18:27:20176 days 16 hrs ago0xb517423119cbaa15b4385cffab0e00bde170dd6a IN  0xfe96c7566c5f5d5555ebdc88b687456081114ebe0 BNB0.00063172
0x61aa1d3f2bbea47622f37c7769462b3a6d86e91359d5aed7e594910a603a196dSet Compact Data95597882021-06-08 18:24:11176 days 16 hrs ago0xb517423119cbaa15b4385cffab0e00bde170dd6a IN  0xfe96c7566c5f5d5555ebdc88b687456081114ebe0 BNB0.00063172
0x3a56aebf735dff0d793556e694d6dd0b96c3376a20d1108c5ce05a563b5ccff0Set Compact Data95597262021-06-08 18:21:05176 days 16 hrs ago0xb517423119cbaa15b4385cffab0e00bde170dd6a IN  0xfe96c7566c5f5d5555ebdc88b687456081114ebe0 BNB0.00063172
0x807161a85dfc6fd18ef1393d93b229a230a8478bb55fd0ec19210e59c54baee1Set Compact Data95597102021-06-08 18:20:17176 days 16 hrs ago0xb517423119cbaa15b4385cffab0e00bde170dd6a IN  0xfe96c7566c5f5d5555ebdc88b687456081114ebe0 BNB0.00063172
0x6963d4eaaae75769f289120f3f68089cf56593aa084b21e4e631f69ea86109dfSet Compact Data95596922021-06-08 18:19:23176 days 16 hrs ago0xb517423119cbaa15b4385cffab0e00bde170dd6a IN  0xfe96c7566c5f5d5555ebdc88b687456081114ebe0 BNB0.00063172
0x562b7dbeadb341b6d10221942a74a32025c2d0c8f4682235dec58b7e0b9e78dbSet Compact Data95596672021-06-08 18:18:08176 days 16 hrs ago0xb517423119cbaa15b4385cffab0e00bde170dd6a IN  0xfe96c7566c5f5d5555ebdc88b687456081114ebe0 BNB0.00063172
0xf1edc6c77c1d3e914255858712ba30625fdbddb153efed624b2fea6532d6e26bSet Compact Data95596052021-06-08 18:15:02176 days 16 hrs ago0xb517423119cbaa15b4385cffab0e00bde170dd6a IN  0xfe96c7566c5f5d5555ebdc88b687456081114ebe0 BNB0.00063172
0x071b2f444d52e8ff3f6ea3fa70a735d4076f2a686413c71fd62d010b6b6c2e97Set Compact Data95595422021-06-08 18:11:53176 days 16 hrs ago0xb517423119cbaa15b4385cffab0e00bde170dd6a IN  0xfe96c7566c5f5d5555ebdc88b687456081114ebe0 BNB0.00063172
0x666bcb871e3bd855347d3b5fa8e362a933583dce0c140811d67bf6b8a2b222e9Set Compact Data95594812021-06-08 18:08:50176 days 16 hrs ago0xb517423119cbaa15b4385cffab0e00bde170dd6a IN  0xfe96c7566c5f5d5555ebdc88b687456081114ebe0 BNB0.00063172
0x1b8cce8e8daaaf73f036d7b6d45af69623d71275e7a187de16d64080d7ec8bb6Set Compact Data95594772021-06-08 18:08:38176 days 16 hrs ago0xb517423119cbaa15b4385cffab0e00bde170dd6a IN  0xfe96c7566c5f5d5555ebdc88b687456081114ebe0 BNB0.00063172
0xb65d2d1abd0da96bc9889f100704755c6592e65132ddfd36ad1a76233cae3fd5Set Compact Data95594662021-06-08 18:08:05176 days 16 hrs ago0xb517423119cbaa15b4385cffab0e00bde170dd6a IN  0xfe96c7566c5f5d5555ebdc88b687456081114ebe0 BNB0.00063172
0x9893c8027edf66a949ca527c9e50d5c0c28ce9f169852a73f39a3cfc753004baSet Compact Data95594212021-06-08 18:05:50176 days 16 hrs ago0xb517423119cbaa15b4385cffab0e00bde170dd6a IN  0xfe96c7566c5f5d5555ebdc88b687456081114ebe0 BNB0.00063148
0xc80fcb3e0059a449d6f6b11f6c48b4220ffe2613130b728e0b300b5f3be49c91Set Compact Data95593992021-06-08 18:04:44176 days 16 hrs ago0xb517423119cbaa15b4385cffab0e00bde170dd6a IN  0xfe96c7566c5f5d5555ebdc88b687456081114ebe0 BNB0.00063172
0x95b5de84b89c3673e8c4800701f33e42111ca4cc858265de7c4f4166853c8047Set Compact Data95593482021-06-08 18:02:11176 days 16 hrs ago0xb517423119cbaa15b4385cffab0e00bde170dd6a IN  0xfe96c7566c5f5d5555ebdc88b687456081114ebe0 BNB0.00063172
0x464c28a229876acb4801d546105c694ed480d379018fa71d8353ec90992a3c2fSet Compact Data95593112021-06-08 18:00:20176 days 16 hrs ago0xb517423119cbaa15b4385cffab0e00bde170dd6a IN  0xfe96c7566c5f5d5555ebdc88b687456081114ebe0 BNB0.00063172
0x85021ac3a10e856a89e6e72214b09c6d951be871d85bea2c075e9d55598619cdSet Compact Data95592502021-06-08 17:57:17176 days 16 hrs ago0xb517423119cbaa15b4385cffab0e00bde170dd6a IN  0xfe96c7566c5f5d5555ebdc88b687456081114ebe0 BNB0.00063172
0x3e4f051b4bd626966a223e0969c89baf49f3e8147ed384fbdb05cc415cf9c163Set Compact Data95591872021-06-08 17:54:08176 days 16 hrs ago0xb517423119cbaa15b4385cffab0e00bde170dd6a IN  0xfe96c7566c5f5d5555ebdc88b687456081114ebe0 BNB0.00063172
0xa2d5c7c4a0ef4209f546309a497f2b7c592af5d7d3aab366d3266091ecda1affSet Compact Data95591252021-06-08 17:51:02176 days 16 hrs ago0xb517423119cbaa15b4385cffab0e00bde170dd6a IN  0xfe96c7566c5f5d5555ebdc88b687456081114ebe0 BNB0.00063172
[ Download CSV Export 
Latest 25 internal transaction
Parent Txn Hash Block From To Value
0xdf4d8a138e9c059f51d8bf8c3088018750cc80e5305afe597a3c274aaef278a371929752021-03-18 11:08:09258 days 23 hrs ago 0xc1f6b9c8c79fd6be87ab017566a066c10e92e7e0 0xfe96c7566c5f5d5555ebdc88b687456081114ebe0 BNB
0xdf4d8a138e9c059f51d8bf8c3088018750cc80e5305afe597a3c274aaef278a371929752021-03-18 11:08:09258 days 23 hrs ago 0xc1f6b9c8c79fd6be87ab017566a066c10e92e7e0 0xfe96c7566c5f5d5555ebdc88b687456081114ebe0 BNB
0x80f52e687493b33fc193f3a61e96173e30147a01964d8a9a64a79d3ca4592fee71929522021-03-18 11:07:00258 days 23 hrs ago 0xc1f6b9c8c79fd6be87ab017566a066c10e92e7e0 0xfe96c7566c5f5d5555ebdc88b687456081114ebe0 BNB
0x80f52e687493b33fc193f3a61e96173e30147a01964d8a9a64a79d3ca4592fee71929522021-03-18 11:07:00258 days 23 hrs ago 0xc1f6b9c8c79fd6be87ab017566a066c10e92e7e0 0xfe96c7566c5f5d5555ebdc88b687456081114ebe0 BNB
0xe2e53db86e182e88bc1ee4c02740486e6f00a5648709cf3093c099223a2c28a671928022021-03-18 10:59:30258 days 23 hrs ago 0xc1f6b9c8c79fd6be87ab017566a066c10e92e7e0 0xfe96c7566c5f5d5555ebdc88b687456081114ebe0 BNB
0xe2e53db86e182e88bc1ee4c02740486e6f00a5648709cf3093c099223a2c28a671928022021-03-18 10:59:30258 days 23 hrs ago 0xc1f6b9c8c79fd6be87ab017566a066c10e92e7e0 0xfe96c7566c5f5d5555ebdc88b687456081114ebe0 BNB
0x4473ec7fcb115ff9efd78bcb4e245b9f96a91e2ab8d85720f8754f7d9ac615e271355602021-03-16 11:17:10260 days 23 hrs ago 0xc1f6b9c8c79fd6be87ab017566a066c10e92e7e0 0xfe96c7566c5f5d5555ebdc88b687456081114ebe0 BNB
0x4473ec7fcb115ff9efd78bcb4e245b9f96a91e2ab8d85720f8754f7d9ac615e271355602021-03-16 11:17:10260 days 23 hrs ago 0xc1f6b9c8c79fd6be87ab017566a066c10e92e7e0 0xfe96c7566c5f5d5555ebdc88b687456081114ebe0 BNB
0x8d51fd3f8d41afaba15fb2172dbf7663b36b040b3f0423c75a5642152c0a178871351232021-03-16 10:55:19260 days 23 hrs ago 0xc1f6b9c8c79fd6be87ab017566a066c10e92e7e0 0xfe96c7566c5f5d5555ebdc88b687456081114ebe0 BNB
0x8d51fd3f8d41afaba15fb2172dbf7663b36b040b3f0423c75a5642152c0a178871351232021-03-16 10:55:19260 days 23 hrs ago 0xc1f6b9c8c79fd6be87ab017566a066c10e92e7e0 0xfe96c7566c5f5d5555ebdc88b687456081114ebe0 BNB
0xa52aae6d0056e1764a6b933a59c4145f91807bec89ffaef9ac4c059e76559fd971073152021-03-15 11:19:23261 days 23 hrs ago 0xc1f6b9c8c79fd6be87ab017566a066c10e92e7e0 0xfe96c7566c5f5d5555ebdc88b687456081114ebe0 BNB
0xa52aae6d0056e1764a6b933a59c4145f91807bec89ffaef9ac4c059e76559fd971073152021-03-15 11:19:23261 days 23 hrs ago 0xc1f6b9c8c79fd6be87ab017566a066c10e92e7e0 0xfe96c7566c5f5d5555ebdc88b687456081114ebe0 BNB
0x503364edb491af3a38cb1858eb838b2ba8055761ed500855989f4459307cfa7b71049962021-03-15 9:21:17262 days 1 hr ago 0xc1f6b9c8c79fd6be87ab017566a066c10e92e7e0 0xfe96c7566c5f5d5555ebdc88b687456081114ebe0 BNB
0x503364edb491af3a38cb1858eb838b2ba8055761ed500855989f4459307cfa7b71049962021-03-15 9:21:17262 days 1 hr ago 0xc1f6b9c8c79fd6be87ab017566a066c10e92e7e0 0xfe96c7566c5f5d5555ebdc88b687456081114ebe0 BNB
0xeb894d5416b346de7148ceec137e8bed4c475d2f35be9146bdfde2505b80469f70693252021-03-14 3:37:15263 days 6 hrs ago 0xc1f6b9c8c79fd6be87ab017566a066c10e92e7e0 0xfe96c7566c5f5d5555ebdc88b687456081114ebe0 BNB
0xeb894d5416b346de7148ceec137e8bed4c475d2f35be9146bdfde2505b80469f70693252021-03-14 3:37:15263 days 6 hrs ago 0xc1f6b9c8c79fd6be87ab017566a066c10e92e7e0 0xfe96c7566c5f5d5555ebdc88b687456081114ebe0 BNB
0x1af6fa28391fe205bc819f88316755769ac10701905a92dd3248ba2213a9bafa70692962021-03-14 3:35:48263 days 6 hrs ago 0xc1f6b9c8c79fd6be87ab017566a066c10e92e7e0 0xfe96c7566c5f5d5555ebdc88b687456081114ebe0 BNB
0x1af6fa28391fe205bc819f88316755769ac10701905a92dd3248ba2213a9bafa70692962021-03-14 3:35:48263 days 6 hrs ago 0xc1f6b9c8c79fd6be87ab017566a066c10e92e7e0 0xfe96c7566c5f5d5555ebdc88b687456081114ebe0 BNB
0x87fc6708e47b3e0049399490117b325f734eb9d81cd3c1ae847872f083a1d2d470692672021-03-14 3:34:21263 days 6 hrs ago 0xc1f6b9c8c79fd6be87ab017566a066c10e92e7e0 0xfe96c7566c5f5d5555ebdc88b687456081114ebe0 BNB
0x87fc6708e47b3e0049399490117b325f734eb9d81cd3c1ae847872f083a1d2d470692672021-03-14 3:34:21263 days 6 hrs ago 0xc1f6b9c8c79fd6be87ab017566a066c10e92e7e0 0xfe96c7566c5f5d5555ebdc88b687456081114ebe0 BNB
0xa4e085258cd7459d68822f0557e64588efd3a75166a262cc9af3ab92d53d1ba470692072021-03-14 3:31:21263 days 6 hrs ago 0xc1f6b9c8c79fd6be87ab017566a066c10e92e7e0 0xfe96c7566c5f5d5555ebdc88b687456081114ebe0 BNB
0xa4e085258cd7459d68822f0557e64588efd3a75166a262cc9af3ab92d53d1ba470692072021-03-14 3:31:21263 days 6 hrs ago 0xc1f6b9c8c79fd6be87ab017566a066c10e92e7e0 0xfe96c7566c5f5d5555ebdc88b687456081114ebe0 BNB
0x6acf6c81f90c845fa49de412a85556eb5d61cdfdb3726bcd31d5c6b5b0fcade270691732021-03-14 3:29:39263 days 7 hrs ago 0xc1f6b9c8c79fd6be87ab017566a066c10e92e7e0 0xfe96c7566c5f5d5555ebdc88b687456081114ebe0 BNB
0x6acf6c81f90c845fa49de412a85556eb5d61cdfdb3726bcd31d5c6b5b0fcade270691732021-03-14 3:29:39263 days 7 hrs ago 0xc1f6b9c8c79fd6be87ab017566a066c10e92e7e0 0xfe96c7566c5f5d5555ebdc88b687456081114ebe0 BNB
0x56a7cfcb6ac0644236e9c3d43f471276dd8b2b9e3e6cf46ff9b781610dc82aad70691452021-03-14 3:28:15263 days 7 hrs ago 0xc1f6b9c8c79fd6be87ab017566a066c10e92e7e0 0xfe96c7566c5f5d5555ebdc88b687456081114ebe0 BNB
[ Download CSV Export 
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
ConversionRateEnhancedStepsWithCustomQuote

Compiler Version
v0.4.18+commit.9cf6e910

Optimization Enabled:
Yes with 30000 runs

Other Settings:
default evmVersion, MIT license

Contract Source Code (Solidity)

/**
 *Submitted for verification at BscScan.com on 2021-03-10
*/

// File: contracts/sol4/ERC20Interface.sol

pragma solidity 0.4.18;


// https://github.com/ethereum/EIPs/issues/20
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 Approval(address indexed _owner, address indexed _spender, uint _value);
}

// File: contracts/sol4/Utils.sol

pragma solidity 0.4.18;



/// @title Kyber constants contract
contract Utils {

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

    function setDecimals(ERC20 token) internal {
        if (token == ETH_TOKEN_ADDRESS) decimals[token] = ETH_DECIMALS;
        else decimals[token] = token.decimals();
    }

    function getDecimals(ERC20 token) internal view returns(uint) {
        if (token == ETH_TOKEN_ADDRESS) return ETH_DECIMALS; // save storage access
        uint tokenDecimals = decimals[token];
        // technically, there might be token with decimals 0
        // moreover, very possible that old tokens have decimals 0
        // these tokens will just have higher gas fees.
        if(tokenDecimals == 0) return token.decimals();

        return tokenDecimals;
    }

    function calcDstQty(uint srcQty, uint srcDecimals, uint dstDecimals, uint rate) internal pure returns(uint) {
        require(srcQty <= MAX_QTY);
        require(rate <= MAX_RATE);

        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) {
        require(dstQty <= MAX_QTY);
        require(rate <= MAX_RATE);
        
        //source quantity is rounded up. to avoid dest quantity being too low.
        uint numerator;
        uint denominator;
        if (srcDecimals >= dstDecimals) {
            require((srcDecimals - dstDecimals) <= MAX_DECIMALS);
            numerator = (PRECISION * dstQty * (10**(srcDecimals - dstDecimals)));
            denominator = rate;
        } else {
            require((dstDecimals - srcDecimals) <= MAX_DECIMALS);
            numerator = (PRECISION * dstQty);
            denominator = (rate * (10**(dstDecimals - srcDecimals)));
        }
        return (numerator + denominator - 1) / denominator; //avoid rounding down errors
    }
}

// File: contracts/sol4/ConversionRatesInterface.sol

pragma solidity 0.4.18;



interface ConversionRatesInterface {

    function recordImbalance(
        ERC20 token,
        int buyAmount,
        uint rateUpdateBlock,
        uint currentBlock
    )
        public;

    function getRate(ERC20 token, uint currentBlockNumber, bool buy, uint qty) public view returns(uint);
}

// File: contracts/sol4/PermissionGroups.sol

pragma solidity 0.4.18;


contract PermissionGroups {

    address public admin;
    address public pendingAdmin;
    mapping(address=>bool) internal operators;
    mapping(address=>bool) internal alerters;
    address[] internal operatorsGroup;
    address[] internal alertersGroup;
    uint constant internal MAX_GROUP_SIZE = 50;

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

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

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

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

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

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

    event TransferAdminPending(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));
        TransferAdminPending(pendingAdmin);
        pendingAdmin = newAdmin;
    }

    /**
     * @dev Allows the current admin to set the admin in one tx. Useful initial deployment.
     * @param newAdmin The address to transfer ownership to.
     */
    function transferAdminQuickly(address newAdmin) public onlyAdmin {
        require(newAdmin != address(0));
        TransferAdminPending(newAdmin);
        AdminClaimed(newAdmin, admin);
        admin = newAdmin;
    }

    event AdminClaimed( address newAdmin, address previousAdmin);

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

    event AlerterAdded (address newAlerter, bool isAdd);

    function addAlerter(address newAlerter) public onlyAdmin {
        require(!alerters[newAlerter]); // prevent duplicates.
        require(alertersGroup.length < MAX_GROUP_SIZE);

        AlerterAdded(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--;
                AlerterAdded(alerter, false);
                break;
            }
        }
    }

    event OperatorAdded(address newOperator, bool isAdd);

    function addOperator(address newOperator) public onlyAdmin {
        require(!operators[newOperator]); // prevent duplicates.
        require(operatorsGroup.length < MAX_GROUP_SIZE);

        OperatorAdded(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;
                OperatorAdded(operator, false);
                break;
            }
        }
    }
}

// File: contracts/sol4/Withdrawable.sol

pragma solidity 0.4.18;




/**
 * @title Contracts that should be able to recover tokens or ethers
 * @author Ilan Doron
 * @dev This allows to recover any tokens or Ethers received in a contract.
 * This will prevent any accidental loss of tokens.
 */
contract Withdrawable is PermissionGroups {

    event TokenWithdraw(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 {
        require(token.transfer(sendTo, amount));
        TokenWithdraw(token, amount, sendTo);
    }

    event EtherWithdraw(uint amount, address sendTo);

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

// File: contracts/sol4/VolumeImbalanceRecorder.sol

pragma solidity 0.4.18;




contract VolumeImbalanceRecorder is Withdrawable {

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

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

    mapping(address => TokenControlInfo) internal tokenControlInfo;

    struct TokenImbalanceData {
        int  lastBlockBuyUnitsImbalance;
        uint lastBlock;

        int  totalBuyUnitsImbalance;
        uint lastRateUpdateBlock;
    }

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

    function VolumeImbalanceRecorder(address _admin) public {
        require(_admin != address(0));
        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 rateUpdateBlock,
        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.lastRateUpdateBlock) == rateUpdateBlock) {
                // just increase imbalance
                currentBlockData.lastBlockBuyUnitsImbalance += recordedBuyAmount;
                currentBlockData.totalBuyUnitsImbalance += recordedBuyAmount;
            } else {
                // imbalance was changed in the middle of the block
                prevImbalance = getImbalanceInRange(token, rateUpdateBlock, currentBlock);
                currentBlockData.totalBuyUnitsImbalance = int(prevImbalance) + recordedBuyAmount;
                currentBlockData.lastBlockBuyUnitsImbalance += recordedBuyAmount;
                currentBlockData.lastRateUpdateBlock = uint(rateUpdateBlock);
            }
        } else {
            // first tx in the current block
            int currentBlockImbalance;
            (prevImbalance, currentBlockImbalance) = getImbalanceSinceRateUpdate(token, rateUpdateBlock, currentBlock);

            currentBlockData.lastBlockBuyUnitsImbalance = recordedBuyAmount;
            currentBlockData.lastBlock = uint(currentBlock);
            currentBlockData.lastRateUpdateBlock = uint(rateUpdateBlock);
            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 getImbalanceSinceRateUpdate(ERC20 token, uint rateUpdateBlock, uint currentBlock)
        internal view
        returns(int buyImbalance, int currentBlockImbalance)
    {
        buyImbalance = 0;
        currentBlockImbalance = 0;
        uint latestBlock = 0;
        int imbalanceInRange = 0;
        uint startBlock = rateUpdateBlock;
        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.lastRateUpdateBlock != rateUpdateBlock) 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 rateUpdateBlock, uint currentBlock)
        internal view
        returns(int totalImbalance, int currentBlockImbalance)
    {

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

        (totalImbalance, currentBlockImbalance) =
            getImbalanceSinceRateUpdate(
                token,
                rateUpdateBlock,
                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) {
        // check for overflows
        require(data.lastBlockBuyUnitsImbalance < int(POW_2_64 / 2));
        require(data.lastBlockBuyUnitsImbalance > int(-1 * int(POW_2_64) / 2));
        require(data.lastBlock < POW_2_64);
        require(data.totalBuyUnitsImbalance < int(POW_2_64 / 2));
        require(data.totalBuyUnitsImbalance > int(-1 * int(POW_2_64) / 2));
        require(data.lastRateUpdateBlock < POW_2_64);

        // do encoding
        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.lastRateUpdateBlock * 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.lastRateUpdateBlock = uint(uint64((input / (POW_2_64 * POW_2_64 * POW_2_64))));

        return data;
    }
}

// File: contracts/sol4/fprConversionRate/ConversionRates.sol

pragma solidity 0.4.18;






contract ConversionRates is ConversionRatesInterface, VolumeImbalanceRecorder, Utils {

    // bps - basic rate steps. one step is 1 / 10000 of the rate.
    struct StepFunction {
        int[] x; // quantity for each step. Quantity of each step includes previous steps.
        int[] y; // rate 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;

        // rate data. base and changes according to quantity and reserve balance.
        // generally speaking. Sell rate is 1 / buy rate i.e. the buy in the other direction.
        uint baseBuyRate;  // in PRECISION units. see KyberConstants
        uint baseSellRate; // PRECISION units. without (sell / buy) spread it is 1 / baseBuyRate
        StepFunction buyRateQtyStepFunction; // in bps. higher quantity - bigger the rate.
        StepFunction sellRateQtyStepFunction;// in bps. higher the qua
        StepFunction buyRateImbalanceStepFunction; // in BPS. higher reserve imbalance - bigger the rate.
        StepFunction sellRateImbalanceStepFunction;
    }

    /*
    this is the data for tokenRatesCompactData
    but solidity compiler optimizer is sub-optimal, and cannot write this structure in a single storage write
    so we represent it as bytes32 and do the byte tricks ourselves.
    struct TokenRatesCompactData {
        bytes14 buy;  // change buy rate of token from baseBuyRate in 10 bps
        bytes14 sell; // change sell rate of token from baseSellRate in 10 bps

        uint32 blockNumber;
    } */
    uint public validRateDurationInBlocks = 10; // rates are valid for this amount of blocks
    ERC20[] internal listedTokens;
    mapping(address=>TokenData) internal tokenData;
    bytes32[] internal tokenRatesCompactData;
    uint public numTokensInCurrentCompactData = 0;
    address public reserveContract;
    uint constant internal NUM_TOKENS_IN_COMPACT_DATA = 14;
    uint constant internal BYTES_14_OFFSET = (2 ** (8 * NUM_TOKENS_IN_COMPACT_DATA));
    uint constant internal MAX_STEPS_IN_FUNCTION = 10;
    int  constant internal MAX_BPS_ADJUSTMENT = 10 ** 11; // 1B %
    int  constant internal MIN_BPS_ADJUSTMENT = -100 * 100; // cannot go down by more than 100%

    function ConversionRates(address _admin) public VolumeImbalanceRecorder(_admin)
        { } // solhint-disable-line no-empty-blocks

    function addToken(ERC20 token) public onlyAdmin {

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

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

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

        numTokensInCurrentCompactData = (numTokensInCurrentCompactData + 1) % NUM_TOKENS_IN_COMPACT_DATA;

        setGarbageToVolumeRecorder(token);

        setDecimals(token);
    }

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

        require(buy.length == sell.length);
        require(indices.length == buy.length);
        require(blockNumber <= 0xFFFFFFFF);

        uint bytes14Offset = BYTES_14_OFFSET;

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

    function setBaseRate(
        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]].baseBuyRate = baseBuy[ind];
            tokenData[tokens[ind]].baseSellRate = 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(xBuy.length <= MAX_STEPS_IN_FUNCTION);
        require(xSell.length <= MAX_STEPS_IN_FUNCTION);
        require(tokenData[token].listed);

        tokenData[token].buyRateQtyStepFunction = StepFunction(xBuy, yBuy);
        tokenData[token].sellRateQtyStepFunction = 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(xBuy.length <= MAX_STEPS_IN_FUNCTION);
        require(xSell.length <= MAX_STEPS_IN_FUNCTION);
        require(tokenData[token].listed);

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

    function setValidRateDurationInBlocks(uint duration) public onlyAdmin {
        validRateDurationInBlocks = 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 rateUpdateBlock,
        uint currentBlock
    )
        public
    {
        require(msg.sender == reserveContract);

        if (rateUpdateBlock == 0) rateUpdateBlock = getRateUpdateBlock(token);

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

    /* solhint-disable function-max-lines */
    function getRate(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 rate update block
        bytes32 compactData = tokenRatesCompactData[tokenData[token].compactDataArrayIndex];

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

        // calculate actual rate
        int imbalanceQty;
        int extraBps;
        int8 rateUpdate;
        uint rate;

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

            // add rate update
            rateUpdate = getRateByteFromCompactData(compactData, token, true);
            extraBps = int(rateUpdate) * 10;
            rate = addBps(rate, extraBps);

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

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

            // add imbalance overhead
            extraBps = executeStepFunction(tokenData[token].buyRateImbalanceStepFunction, totalImbalance);
            rate = addBps(rate, extraBps);
        } else {
            // start with base rate
            rate = tokenData[token].baseSellRate;

            // add rate update
            rateUpdate = getRateByteFromCompactData(compactData, token, false);
            extraBps = int(rateUpdate) * 10;
            rate = addBps(rate, extraBps);

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

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

            // add imbalance overhead
            extraBps = executeStepFunction(tokenData[token].sellRateImbalanceStepFunction, totalImbalance);
            rate = addBps(rate, extraBps);
        }

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

        return rate;
    }
    /* solhint-enable function-max-lines */

    function getBasicRate(ERC20 token, bool buy) public view returns(uint) {
        if (buy)
            return tokenData[token].baseBuyRate;
        else
            return tokenData[token].baseSellRate;
    }

    function getCompactData(ERC20 token) public view returns(uint, uint, byte, byte) {
        require(tokenData[token].listed);

        uint arrayIndex = tokenData[token].compactDataArrayIndex;
        uint fieldOffset = tokenData[token].compactDataFieldIndex;

        return (
            arrayIndex,
            fieldOffset,
            byte(getRateByteFromCompactData(tokenRatesCompactData[arrayIndex], token, true)),
            byte(getRateByteFromCompactData(tokenRatesCompactData[arrayIndex], token, false))
        );
    }

    function getTokenBasicData(ERC20 token) public view returns(bool, bool) {
        return (tokenData[token].listed, tokenData[token].enabled);
    }

    /* solhint-disable code-complexity */
    function getStepFunctionData(ERC20 token, uint command, uint param) public view returns(int) {
        if (command == 0) return int(tokenData[token].buyRateQtyStepFunction.x.length);
        if (command == 1) return tokenData[token].buyRateQtyStepFunction.x[param];
        if (command == 2) return int(tokenData[token].buyRateQtyStepFunction.y.length);
        if (command == 3) return tokenData[token].buyRateQtyStepFunction.y[param];

        if (command == 4) return int(tokenData[token].sellRateQtyStepFunction.x.length);
        if (command == 5) return tokenData[token].sellRateQtyStepFunction.x[param];
        if (command == 6) return int(tokenData[token].sellRateQtyStepFunction.y.length);
        if (command == 7) return tokenData[token].sellRateQtyStepFunction.y[param];

        if (command == 8) return int(tokenData[token].buyRateImbalanceStepFunction.x.length);
        if (command == 9) return tokenData[token].buyRateImbalanceStepFunction.x[param];
        if (command == 10) return int(tokenData[token].buyRateImbalanceStepFunction.y.length);
        if (command == 11) return tokenData[token].buyRateImbalanceStepFunction.y[param];

        if (command == 12) return int(tokenData[token].sellRateImbalanceStepFunction.x.length);
        if (command == 13) return tokenData[token].sellRateImbalanceStepFunction.x[param];
        if (command == 14) return int(tokenData[token].sellRateImbalanceStepFunction.y.length);
        if (command == 15) return tokenData[token].sellRateImbalanceStepFunction.y[param];

        revert();
    }
    /* solhint-enable code-complexity */

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

    function getListedTokens() public view returns(ERC20[]) {
        return listedTokens;
    }

    function getTokenQty(ERC20 token, uint ethQty, uint rate) internal view returns(uint) {
        uint dstDecimals = getDecimals(token);
        uint srcDecimals = ETH_DECIMALS;

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

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

    function getRateByteFromCompactData(bytes32 data, ERC20 token, bool buy) internal view 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) internal pure 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 rate, int bps) internal pure returns(uint) {
        require(rate <= MAX_RATE);
        require(bps >= MIN_BPS_ADJUSTMENT);
        require(bps <= MAX_BPS_ADJUSTMENT);

        uint maxBps = 100 * 100;
        return (rate * uint(int(maxBps) + bps)) / maxBps;
    }

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

// File: contracts/sol4/fprConversionRate/ConversionRateEnhancedSteps.sol

pragma solidity 0.4.18;


/// @title ConversionRateEnhancedSteps contract - new ConversionRates contract with step function enhancement
/// Removed qty step function overhead
/// Also fixed following issues:
/// https://github.com/KyberNetwork/smart-contracts/issues/291
/// https://github.com/KyberNetwork/smart-contracts/issues/241
/// https://github.com/KyberNetwork/smart-contracts/issues/240


contract ConversionRateEnhancedSteps is ConversionRates {

    uint  constant internal MAX_RATE = (PRECISION * 10 ** 7); // up to 10M tokens per ETH
    uint constant internal MAX_STEPS_IN_FUNCTION = 16;
    int constant internal MAX_IMBALANCE = 2 ** 255 - 1;
    uint constant internal POW_2_128 = 2 ** 128;
    int128 constant internal MAX_STEP_VALUE = 2 ** 127 - 1;
    int128 constant internal MIN_STEP_VALUE = -1 * 2 ** 127;
    int constant internal MAX_BPS_ADJUSTMENT = 100 * 100;

    function ConversionRateEnhancedSteps(address _admin) public ConversionRates(_admin)
        { } // solhint-disable-line no-empty-blocks

    // Blocking set qty step func as we won't use
    function setQtyStepFunction(
        ERC20,
        int[],
        int[],
        int[],
        int[]
    )
        public
        onlyOperator
    {
        revert();
    }

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

        uint i;

        if (xBuy.length > 1) {
            // verify qty are increasing
            for(i = 0; i < xBuy.length - 1; i++) {
                require(xBuy[i] < xBuy[i + 1]);
            }
        }
        // only need to check last value as it's sorted array
        require(xBuy.length == 0 || xBuy[xBuy.length - 1] < MAX_STEP_VALUE);

        // verify yBuy
        for(i = 0; i < yBuy.length; i++) {
            require(yBuy[i] >= MIN_BPS_ADJUSTMENT);
            require(yBuy[i] <= MAX_BPS_ADJUSTMENT);
        }

        if (xSell.length > 1) {
            // verify qty are increasing
            for(i = 0; i < xSell.length - 1; i++) {
                require(xSell[i] < xSell[i + 1]);
            }
        }
        // only need to check last value as it's sorted array
        require(xSell.length == 0 || xSell[xSell.length - 1] < MAX_STEP_VALUE);

        // verify ySell
        for(i = 0; i < ySell.length; i++) {
            require(ySell[i] >= MIN_BPS_ADJUSTMENT);
            require(ySell[i] <= MAX_BPS_ADJUSTMENT);
        }

        int[] memory buyArray = new int[](yBuy.length);
        for(i = 0; i < yBuy.length; i++) {
            int128 xBuyVal = (i == yBuy.length - 1) ? MAX_STEP_VALUE : int128(xBuy[i]);
            buyArray[i] = encodeStepFunctionData(xBuyVal, int128(yBuy[i]));
        }

        int[] memory sellArray = new int[](ySell.length);
        for(i = 0; i < ySell.length; i++) {
            int128 xSellVal = (i == ySell.length - 1) ? MAX_STEP_VALUE : int128(xSell[i]);
            sellArray[i] = encodeStepFunctionData(xSellVal, int128(ySell[i]));
        }

        int[] memory emptyArr = new int[](0);
        tokenData[token].buyRateImbalanceStepFunction = StepFunction(buyArray, emptyArr);
        tokenData[token].sellRateImbalanceStepFunction = StepFunction(sellArray, emptyArr);
    }

    /* solhint-disable code-complexity */
    function getStepFunctionData(ERC20 token, uint command, uint param) public view returns(int) {
        if (command == 8) return int(tokenData[token].buyRateImbalanceStepFunction.x.length - 1);

        int stepXValue;
        int stepYValue;

        if (command == 9) {
            (stepXValue, stepYValue) = decodeStepFunctionData(tokenData[token].buyRateImbalanceStepFunction.x[param]);
            return stepXValue;
        }

        if (command == 10) return int(tokenData[token].buyRateImbalanceStepFunction.x.length);
        if (command == 11) {
            (stepXValue, stepYValue) = decodeStepFunctionData(tokenData[token].buyRateImbalanceStepFunction.x[param]);
            return stepYValue;
        }

        if (command == 12) return int(tokenData[token].sellRateImbalanceStepFunction.x.length - 1);
        if (command == 13) {
            (stepXValue, stepYValue) = decodeStepFunctionData(tokenData[token].sellRateImbalanceStepFunction.x[param]);
            return stepXValue;
        }

        if (command == 14) return int(tokenData[token].sellRateImbalanceStepFunction.x.length);
        if (command == 15) {
            (stepXValue, stepYValue) = decodeStepFunctionData(tokenData[token].sellRateImbalanceStepFunction.x[param]);
            return stepYValue;
        }

        revert();
    }

    /* solhint-disable function-max-lines */
    function getRate(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 rate update block
        bytes32 compactData = tokenRatesCompactData[tokenData[token].compactDataArrayIndex];

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

        // calculate actual rate
        int imbalanceQty;
        int extraBps;
        int8 rateUpdate;
        uint rate;

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

            // add rate update
            rateUpdate = getRateByteFromCompactData(compactData, token, true);
            extraBps = int(rateUpdate) * 10;
            rate = addBps(rate, extraBps);

            // compute token qty
            qty = getTokenQty(token, qty, rate);
            imbalanceQty = int(qty);

            // add imbalance overhead
            extraBps = executeStepFunction(
                tokenData[token].buyRateImbalanceStepFunction,
                totalImbalance,
                totalImbalance + imbalanceQty
            );
            rate = addBps(rate, extraBps);
            totalImbalance += imbalanceQty;
        } else {
            // start with base rate
            rate = tokenData[token].baseSellRate;

            // add rate update
            rateUpdate = getRateByteFromCompactData(compactData, token, false);
            extraBps = int(rateUpdate) * 10;
            rate = addBps(rate, extraBps);

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

            // add imbalance overhead
            extraBps = executeStepFunction(
                tokenData[token].sellRateImbalanceStepFunction,
                totalImbalance + imbalanceQty,
                totalImbalance
            );
            rate = addBps(rate, extraBps);
            totalImbalance += imbalanceQty;
        }

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

        return rate;
    }

    // Override function getImbalance to fix #240
    function getImbalance(ERC20 token, uint rateUpdateBlock, uint currentBlock)
        internal view
        returns(int totalImbalance, int currentBlockImbalance)
    {
        int resolution = int(tokenControlInfo[token].minimalRecordResolution);

        (totalImbalance, currentBlockImbalance) =
            getImbalanceSinceRateUpdate(
                token,
                rateUpdateBlock,
                currentBlock);

        if (!checkMultOverflow(totalImbalance, resolution)) {
            totalImbalance *= resolution;
        } else {
            totalImbalance = MAX_IMBALANCE;
        }

        if (!checkMultOverflow(currentBlockImbalance, resolution)) {
            currentBlockImbalance *= resolution;
        } else {
            currentBlockImbalance = MAX_IMBALANCE;
        }
    }

    function getImbalancePerToken(ERC20 token, uint whichBlock)
        public view
        returns(int totalImbalance, int currentBlockImbalance)
    {
        uint rateUpdateBlock = getRateUpdateBlock(token);
        // if whichBlock = 0, use latest block, otherwise use whichBlock
        uint usedBlock = whichBlock == 0 ? block.number : whichBlock;
        return getImbalance(token, rateUpdateBlock, usedBlock);
    }

    function addBps(uint rate, int bps) internal pure returns(uint) {
        require(rate <= MAX_RATE);
        require(bps >= MIN_BPS_ADJUSTMENT);
        require(bps <= MAX_BPS_ADJUSTMENT);

        uint maxBps = 100 * 100;
        return (rate * uint(int(maxBps) + bps)) / maxBps;
    }

    function executeStepFunction(StepFunction storage f, int from, int to) internal view returns(int) {

        uint len = f.x.length;

        if (len == 0 || from == to) { return 0; }

        int fromVal = from; // avoid modifying function parameters
        int change = 0; // amount change from initial amount when applying bps for each step
        int stepXValue;
        int stepYValue;

        for(uint ind = 0; ind < len; ind++) {
            (stepXValue, stepYValue) = decodeStepFunctionData(f.x[ind]);
            if (stepXValue <= fromVal) { continue; }
            // if it falls into step with y <= -10000, rate must be 0
            if (stepYValue == MIN_BPS_ADJUSTMENT) { return MIN_BPS_ADJUSTMENT; }
            // from here, from < stepXValue,
            // if from < to <= stepXValue, take [from, to] and return, else take [from, stepXValue]
            if (stepXValue >= to) {
                change += (to - fromVal) * stepYValue;
                return change / (to - from);
            } else {
                change += (stepXValue - fromVal) * stepYValue;
                fromVal = stepXValue;
            }
            // max change < MAX_QTY * BPS * 16 = (10 ** 28) * 10000 * 16 = 1.6e33
        }

        return change / (to - from);
    }

    // first 128 bits is value for x, next 128 bits is value for y
    function encodeStepFunctionData(int128 x, int128 y) internal pure returns(int data) {
        require(x <= MAX_STEP_VALUE && x >= MIN_STEP_VALUE);
        require(y <= MAX_STEP_VALUE && y >= MIN_STEP_VALUE);
        data = int(uint(y) & (POW_2_128 - 1));
        data |= int((uint(x) & (POW_2_128 - 1)) * POW_2_128);
    }

    function decodeStepFunctionData(int val) internal pure returns (int x, int y) {
        y = int(int128(uint(val) & (POW_2_128 - 1)));
        x = int(int128((uint(val) / POW_2_128) & (POW_2_128 - 1)));
        // default to be max value
        if (x == int(MAX_STEP_VALUE)) { x = MAX_IMBALANCE; }
    }

    function checkMultOverflow(int x, int y) internal pure returns(bool) {
        if (y == 0) return false;
        return (((x*y) / y) != x);
    }
}

// File: contracts/sol4/fprConversionRate/ConversionRateEnhancedStepsWithCustomQuote.sol

pragma solidity 0.4.18;


/// @title ConversionRateEnhancedStepsWithCustomQuote contract
/// - new ConversionRates contract support custom quote contracts
/// Removed qty step function overhead
/// Also fixed following issues:
/// https://github.com/KyberNetwork/smart-contracts/issues/291
/// https://github.com/KyberNetwork/smart-contracts/issues/241
/// https://github.com/KyberNetwork/smart-contracts/issues/240

contract ConversionRateEnhancedStepsWithCustomQuote is
    ConversionRateEnhancedSteps
{
    ERC20 internal quoteToken;
    uint internal decimals;

    function ConversionRateEnhancedStepsWithCustomQuote(
        address _admin,
        ERC20 _quoteToken
    ) public ConversionRateEnhancedSteps(_admin) {
        quoteToken = _quoteToken;
        decimals = _quoteToken.decimals();
    }

    function addToken(ERC20 token) public onlyAdmin {
        require(token != quoteToken);
        require(!tokenData[token].listed);
        tokenData[token].listed = true;
        listedTokens.push(token);

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

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

        numTokensInCurrentCompactData =
            (numTokensInCurrentCompactData + 1) %
            NUM_TOKENS_IN_COMPACT_DATA;

        setGarbageToVolumeRecorder(token);

        setDecimals(token);
    }

    function getTokenQty(
        ERC20 token,
        uint256 quoteQty,
        uint256 rate
    ) internal view returns (uint256) {
        uint256 dstDecimals = getDecimals(token);
        uint256 srcDecimals = decimals;

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

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":"setReserveAddress","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"token","type":"address"}],"name":"disableTokenTrade","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"validRateDurationInBlocks","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"tokens","type":"address[]"},{"name":"baseBuy","type":"uint256[]"},{"name":"baseSell","type":"uint256[]"},{"name":"buy","type":"bytes14[]"},{"name":"sell","type":"bytes14[]"},{"name":"blockNumber","type":"uint256"},{"name":"indices","type":"uint256[]"}],"name":"setBaseRate","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"token","type":"address"}],"name":"enableTokenTrade","outputs":[],"payable":false,"stateMutability":"nonpayable","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":"getListedTokens","outputs":[{"name":"","type":"address[]"}],"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":false,"inputs":[{"name":"newAlerter","type":"address"}],"name":"addAlerter","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"numTokensInCurrentCompactData","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"token","type":"address"},{"name":"whichBlock","type":"uint256"}],"name":"getImbalancePerToken","outputs":[{"name":"totalImbalance","type":"int256"},{"name":"currentBlockImbalance","type":"int256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"token","type":"address"},{"name":"command","type":"uint256"},{"name":"param","type":"uint256"}],"name":"getStepFunctionData","outputs":[{"name":"","type":"int256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"buy","type":"bytes14[]"},{"name":"sell","type":"bytes14[]"},{"name":"blockNumber","type":"uint256"},{"name":"indices","type":"uint256[]"}],"name":"setCompactData","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"duration","type":"uint256"}],"name":"setValidRateDurationInBlocks","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"token","type":"address"}],"name":"getTokenBasicData","outputs":[{"name":"","type":"bool"},{"name":"","type":"bool"}],"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":"claimAdmin","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"newAdmin","type":"address"}],"name":"transferAdminQuickly","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"getAlerters","outputs":[{"name":"","type":"address[]"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"token","type":"address"}],"name":"getRateUpdateBlock","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"","type":"address"},{"name":"","type":"int256[]"},{"name":"","type":"int256[]"},{"name":"","type":"int256[]"},{"name":"","type":"int256[]"}],"name":"setQtyStepFunction","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"newOperator","type":"address"}],"name":"addOperator","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"reserveContract","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"","type":"address"},{"name":"","type":"uint256"}],"name":"tokenImbalanceData","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"operator","type":"address"}],"name":"removeOperator","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"token","type":"address"},{"name":"currentBlockNumber","type":"uint256"},{"name":"buy","type":"bool"},{"name":"qty","type":"uint256"}],"name":"getRate","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"token","type":"address"},{"name":"xBuy","type":"int256[]"},{"name":"yBuy","type":"int256[]"},{"name":"xSell","type":"int256[]"},{"name":"ySell","type":"int256[]"}],"name":"setImbalanceStepFunction","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"token","type":"address"},{"name":"minimalRecordResolution","type":"uint256"},{"name":"maxPerBlockImbalance","type":"uint256"},{"name":"maxTotalImbalance","type":"uint256"}],"name":"setTokenControlInfo","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"token","type":"address"},{"name":"buyAmount","type":"int256"},{"name":"rateUpdateBlock","type":"uint256"},{"name":"currentBlock","type":"uint256"}],"name":"recordImbalance","outputs":[],"payable":false,"stateMutability":"nonpayable","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":"token","type":"address"},{"name":"buy","type":"bool"}],"name":"getBasicRate","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"token","type":"address"}],"name":"addToken","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"token","type":"address"}],"name":"getCompactData","outputs":[{"name":"","type":"uint256"},{"name":"","type":"uint256"},{"name":"","type":"bytes1"},{"name":"","type":"bytes1"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"token","type":"address"}],"name":"getTokenControlInfo","outputs":[{"name":"","type":"uint256"},{"name":"","type":"uint256"},{"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"},{"name":"_quoteToken","type":"address"}],"payable":false,"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":false,"name":"token","type":"address"},{"indexed":false,"name":"amount","type":"uint256"},{"indexed":false,"name":"sendTo","type":"address"}],"name":"TokenWithdraw","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"amount","type":"uint256"},{"indexed":false,"name":"sendTo","type":"address"}],"name":"EtherWithdraw","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"pendingAdmin","type":"address"}],"name":"TransferAdminPending","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"newAdmin","type":"address"},{"indexed":false,"name":"previousAdmin","type":"address"}],"name":"AdminClaimed","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"newAlerter","type":"address"},{"indexed":false,"name":"isAdd","type":"bool"}],"name":"AlerterAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"newOperator","type":"address"},{"indexed":false,"name":"isAdd","type":"bool"}],"name":"OperatorAdded","type":"event"}]

6060604052600a6009556000600d5534156200001a57600080fd5b60405160408062003e68833981016040528080519190602001805160008054600160a060020a03191633600160a060020a039081169190911790915590925083915081908190811615156200006e57600080fd5b60008054600160a060020a03928316600160a060020a0319918216178255600f8054938716939091168317905590925063313ce5679150604051602001526040518163ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401602060405180830381600087803b1515620000f457600080fd5b6102c65a03f115156200010657600080fd5b5050506040518051601055505050613d4480620001246000396000f3006060604052600436106101cc5763ffffffff7c010000000000000000000000000000000000000000000000000000000060003504166301a12fd381146101d157806314673d31146101ff578063158859f71461022b57806316265694146102575780631a4813d71461027c5780631d6a8bda14610414578063267822471461044057806327a099d81461047c5780632ba996a5146104e25780633ccdbb28146104f5578063408ee7fe1461052b5780635085c9f1146105575780635329dd311461056a57806362674e93146105b157806364887334146105e35780636c6295b8146106bb578063721bba59146106d157806375829def1461071957806377f50f97146107455780637acc8678146107585780637c423f54146107845780638036d7571461079757806380d8b380146107c35780639870d7fe146108ed578063a7f43acd14610919578063a80c609e1461092c578063ac8a584a1461095b578063b8e9c22e14610987578063bc9cbcc8146109be578063bfee356914610ae8578063c6fd210314610b1d578063ce56c45414610b52578063cf8fee1114610b81578063d48bfca714610bb2578063e4a2ac6214610bde578063e7d4fd9114610c59578063f851a44014610ca9575b600080fd5b34156101dc57600080fd5b6101fd73ffffffffffffffffffffffffffffffffffffffff60043516610cbc565b005b341561020a57600080fd5b6101fd73ffffffffffffffffffffffffffffffffffffffff60043516610f06565b341561023657600080fd5b6101fd73ffffffffffffffffffffffffffffffffffffffff60043516610f75565b341561026257600080fd5b61026a611029565b60405190815260200160405180910390f35b341561028757600080fd5b6101fd6004602481358181019083013580602081810201604051908101604052809392919081815260200183836020028082843782019150505050505091908035906020019082018035906020019080806020026020016040519081016040528093929190818152602001838360200280828437820191505050505050919080359060200190820180359060200190808060200260200160405190810160405280939291908181526020018383602002808284378201915050505050509190803590602001908201803590602001908080602002602001604051908101604052809392919081815260200183836020028082843782019150505050505091908035906020019082018035906020019080806020026020016040519081016040528093929190818152602001838360200280828437820191505050505050919080359060200190919080359060200190820180359060200190808060200260200160405190810160405280939291908181526020018383602002808284375094965061102f95505050505050565b341561041f57600080fd5b6101fd73ffffffffffffffffffffffffffffffffffffffff600435166111c9565b341561044b57600080fd5b6104536112a6565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390f35b341561048757600080fd5b61048f6112c2565b60405160208082528190810183818151815260200191508051906020019060200280838360005b838110156104ce5780820151838201526020016104b6565b505050509050019250505060405180910390f35b34156104ed57600080fd5b61048f611338565b341561050057600080fd5b6101fd73ffffffffffffffffffffffffffffffffffffffff60043581169060243590604435166113ab565b341561053657600080fd5b6101fd73ffffffffffffffffffffffffffffffffffffffff600435166114ef565b341561056257600080fd5b61026a611662565b341561057557600080fd5b61059973ffffffffffffffffffffffffffffffffffffffff60043516602435611668565b60405191825260208201526040908101905180910390f35b34156105bc57600080fd5b61026a73ffffffffffffffffffffffffffffffffffffffff600435166024356044356116a1565b34156105ee57600080fd5b6101fd6004602481358181019083013580602081810201604051908101604052809392919081815260200183836020028082843782019150505050505091908035906020019082018035906020019080806020026020016040519081016040528093929190818152602001838360200280828437820191505050505050919080359060200190919080359060200190820180359060200190808060200260200160405190810160405280939291908181526020018383602002808284375094965061190d95505050505050565b34156106c657600080fd5b6101fd600435611a5b565b34156106dc57600080fd5b6106fd73ffffffffffffffffffffffffffffffffffffffff60043516611a88565b6040519115158252151560208201526040908101905180910390f35b341561072457600080fd5b6101fd73ffffffffffffffffffffffffffffffffffffffff60043516611ac0565b341561075057600080fd5b6101fd611bb4565b341561076357600080fd5b6101fd73ffffffffffffffffffffffffffffffffffffffff60043516611c9a565b341561078f57600080fd5b61048f611de2565b34156107a257600080fd5b61026a73ffffffffffffffffffffffffffffffffffffffff60043516611e55565b34156107ce57600080fd5b6101fd6004803573ffffffffffffffffffffffffffffffffffffffff16906044602480359081019083013580602080820201604051908101604052809392919081815260200183836020028082843782019150505050505091908035906020019082018035906020019080806020026020016040519081016040528093929190818152602001838360200280828437820191505050505050919080359060200190820180359060200190808060200260200160405190810160405280939291908181526020018383602002808284378201915050505050509190803590602001908201803590602001908080602002602001604051908101604052809392919081815260200183836020028082843750949650611ead95505050505050565b34156108f857600080fd5b6101fd73ffffffffffffffffffffffffffffffffffffffff60043516611ee1565b341561092457600080fd5b610453612003565b341561093757600080fd5b61026a73ffffffffffffffffffffffffffffffffffffffff6004351660243561201f565b341561096657600080fd5b6101fd73ffffffffffffffffffffffffffffffffffffffff6004351661203c565b341561099257600080fd5b61026a73ffffffffffffffffffffffffffffffffffffffff600435166024356044351515606435612282565b34156109c957600080fd5b6101fd6004803573ffffffffffffffffffffffffffffffffffffffff1690604460248035908101908301358060208082020160405190810160405280939291908181526020018383602002808284378201915050505050509190803590602001908201803590602001908080602002602001604051908101604052809392919081815260200183836020028082843782019150505050505091908035906020019082018035906020019080806020026020016040519081016040528093929190818152602001838360200280828437820191505050505050919080359060200190820180359060200190808060200260200160405190810160405280939291908181526020018383602002808284375094965061253e95505050505050565b3415610af357600080fd5b6101fd73ffffffffffffffffffffffffffffffffffffffff60043516602435604435606435612a95565b3415610b2857600080fd5b6101fd73ffffffffffffffffffffffffffffffffffffffff60043516602435604435606435612b1d565b3415610b5d57600080fd5b6101fd60043573ffffffffffffffffffffffffffffffffffffffff60243516612b6a565b3415610b8c57600080fd5b61026a73ffffffffffffffffffffffffffffffffffffffff600435166024351515612c24565b3415610bbd57600080fd5b6101fd73ffffffffffffffffffffffffffffffffffffffff60043516612c8c565b3415610be957600080fd5b610c0a73ffffffffffffffffffffffffffffffffffffffff60043516612e56565b60405193845260208401929092527fff00000000000000000000000000000000000000000000000000000000000000908116604080850191909152911660608301526080909101905180910390f35b3415610c6457600080fd5b610c8573ffffffffffffffffffffffffffffffffffffffff60043516612f6c565b60405180848152602001838152602001828152602001935050505060405180910390f35b3415610cb457600080fd5b610453612fa1565b600080543373ffffffffffffffffffffffffffffffffffffffff908116911614610ce557600080fd5b73ffffffffffffffffffffffffffffffffffffffff821660009081526003602052604090205460ff161515610d1957600080fd5b5073ffffffffffffffffffffffffffffffffffffffff8116600090815260036020526040812080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001690555b600554811015610f02578173ffffffffffffffffffffffffffffffffffffffff16600582815481101515610d9657fe5b60009182526020909120015473ffffffffffffffffffffffffffffffffffffffff161415610efa57600580547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8101908110610dee57fe5b6000918252602090912001546005805473ffffffffffffffffffffffffffffffffffffffff9092169183908110610e2157fe5b600091825260209091200180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff929092169190911790556005805490610ea0907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8301613c4f565b507f5611bf3e417d124f97bf2c788843ea8bb502b66079fbee02158ef30b172cb76282600060405173ffffffffffffffffffffffffffffffffffffffff9092168252151560208201526040908101905180910390a1610f02565b600101610d66565b5050565b6000543373ffffffffffffffffffffffffffffffffffffffff908116911614610f2e57600080fd5b600e80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b73ffffffffffffffffffffffffffffffffffffffff331660009081526003602052604090205460ff161515610fa957600080fd5b73ffffffffffffffffffffffffffffffffffffffff81166000908152600b602052604090205460ff161515610fdd57600080fd5b73ffffffffffffffffffffffffffffffffffffffff166000908152600b6020526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055565b60095481565b73ffffffffffffffffffffffffffffffffffffffff331660009081526002602052604081205460ff16151561106357600080fd5b865188511461107157600080fd5b855188511461107f57600080fd5b845184511461108d57600080fd5b815184511461109b57600080fd5b5060005b87518110156111b357600b60008983815181106110b857fe5b9060200190602002015173ffffffffffffffffffffffffffffffffffffffff16815260208101919091526040016000205460ff1615156110f757600080fd5b86818151811061110357fe5b90602001906020020151600b60008a848151811061111d57fe5b9060200190602002015173ffffffffffffffffffffffffffffffffffffffff16815260208101919091526040016000206003015585818151811061115d57fe5b90602001906020020151600b60008a848151811061117757fe5b9060200190602002015173ffffffffffffffffffffffffffffffffffffffff16815260208101919091526040016000206004015560010161109f565b6111bf8585858561190d565b5050505050505050565b6000543373ffffffffffffffffffffffffffffffffffffffff9081169116146111f157600080fd5b73ffffffffffffffffffffffffffffffffffffffff81166000908152600b602052604090205460ff16151561122557600080fd5b73ffffffffffffffffffffffffffffffffffffffff8116600090815260066020526040902054151561125657600080fd5b73ffffffffffffffffffffffffffffffffffffffff166000908152600b6020526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff16610100179055565b60015473ffffffffffffffffffffffffffffffffffffffff1681565b6112ca613c78565b600480548060200260200160405190810160405280929190818152602001828054801561132d57602002820191906000526020600020905b815473ffffffffffffffffffffffffffffffffffffffff168152600190910190602001808311611302575b505050505090505b90565b611340613c78565b600a80548060200260200160405190810160405280929190818152602001828054801561132d5760200282019190600052602060002090815473ffffffffffffffffffffffffffffffffffffffff168152600190910190602001808311611302575050505050905090565b6000543373ffffffffffffffffffffffffffffffffffffffff9081169116146113d357600080fd5b8273ffffffffffffffffffffffffffffffffffffffff1663a9059cbb82846000604051602001526040517c010000000000000000000000000000000000000000000000000000000063ffffffff851602815273ffffffffffffffffffffffffffffffffffffffff90921660048301526024820152604401602060405180830381600087803b151561146357600080fd5b6102c65a03f1151561147457600080fd5b50505060405180519050151561148957600080fd5b7f72cb8a894ddb372ceec3d2a7648d86f17d5a15caae0e986c53109b8a9a9385e683838360405173ffffffffffffffffffffffffffffffffffffffff938416815260208101929092529091166040808301919091526060909101905180910390a1505050565b6000543373ffffffffffffffffffffffffffffffffffffffff90811691161461151757600080fd5b73ffffffffffffffffffffffffffffffffffffffff811660009081526003602052604090205460ff161561154a57600080fd5b6005546032901061155a57600080fd5b7f5611bf3e417d124f97bf2c788843ea8bb502b66079fbee02158ef30b172cb76281600160405173ffffffffffffffffffffffffffffffffffffffff9092168252151560208201526040908101905180910390a173ffffffffffffffffffffffffffffffffffffffff8116600090815260036020526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016600190811790915560058054909181016116118382613c4f565b50600091825260209091200180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b600d5481565b60008060008061167786611e55565b915084156116855784611687565b435b9050611694868383612fbd565b9350935050509250929050565b600080600084600814156117015773ffffffffffffffffffffffffffffffffffffffff86166000908152600b60205260409020600901547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff019250611904565b84600914156117615773ffffffffffffffffffffffffffffffffffffffff86166000908152600b60205260409020600901805461175491908690811061174357fe5b906000526020600020900154613078565b9093508392509050611904565b84600a141561179a5773ffffffffffffffffffffffffffffffffffffffff86166000908152600b60205260409020600901549250611904565b84600b14156117e85773ffffffffffffffffffffffffffffffffffffffff86166000908152600b6020526040902060090180546117dc91908690811061174357fe5b93509150829050611904565b84600c14156118445773ffffffffffffffffffffffffffffffffffffffff86166000908152600b6020819052604090912001547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff019250611904565b84600d14156118875773ffffffffffffffffffffffffffffffffffffffff86166000908152600b6020819052604090912001805461175491908690811061174357fe5b84600e14156118c15773ffffffffffffffffffffffffffffffffffffffff86166000908152600b6020819052604090912001549250611904565b84600f14156101cc5773ffffffffffffffffffffffffffffffffffffffff86166000908152600b602081905260409091200180546117dc91908690811061174357fe5b50509392505050565b73ffffffffffffffffffffffffffffffffffffffff33166000908152600260205260408120548190819060ff16151561194557600080fd5b855187511461195357600080fd5b865184511461196157600080fd5b63ffffffff85111561197257600080fd5b6e0100000000000000000000000000009250600091505b8351821015611a5257600c548483815181106119a157fe5b90602001906020020151106119b557600080fd5b8283028502838784815181106119c757fe5b9060200190602002015172010000000000000000000000000000000000009004028884815181106119f457fe5b90602001906020020151720100000000000000000000000000000000000090041717905080600c858481518110611a2757fe5b9060200190602002015181548110611a3b57fe5b600091825260209091200155600190910190611989565b50505050505050565b6000543373ffffffffffffffffffffffffffffffffffffffff908116911614611a8357600080fd5b600955565b73ffffffffffffffffffffffffffffffffffffffff81166000908152600b602052604090205460ff808216916101009004165b915091565b6000543373ffffffffffffffffffffffffffffffffffffffff908116911614611ae857600080fd5b73ffffffffffffffffffffffffffffffffffffffff81161515611b0a57600080fd5b6001547f3b81caf78fa51ecbc8acb482fd7012a277b428d9b80f9d156e8a54107496cc409073ffffffffffffffffffffffffffffffffffffffff1660405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390a1600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b6001543373ffffffffffffffffffffffffffffffffffffffff908116911614611bdc57600080fd5b6001546000547f65da1cfc2c2e81576ad96afb24a581f8e109b7a403b35cbd3243a1c99efdb9ed9173ffffffffffffffffffffffffffffffffffffffff908116911660405173ffffffffffffffffffffffffffffffffffffffff9283168152911660208201526040908101905180910390a160018054600080547fffffffffffffffffffffffff000000000000000000000000000000000000000090811673ffffffffffffffffffffffffffffffffffffffff841617909155169055565b6000543373ffffffffffffffffffffffffffffffffffffffff908116911614611cc257600080fd5b73ffffffffffffffffffffffffffffffffffffffff81161515611ce457600080fd5b7f3b81caf78fa51ecbc8acb482fd7012a277b428d9b80f9d156e8a54107496cc408160405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390a16000547f65da1cfc2c2e81576ad96afb24a581f8e109b7a403b35cbd3243a1c99efdb9ed90829073ffffffffffffffffffffffffffffffffffffffff1660405173ffffffffffffffffffffffffffffffffffffffff9283168152911660208201526040908101905180910390a1600080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b611dea613c78565b600580548060200260200160405190810160405280929190818152602001828054801561132d5760200282019190600052602060002090815473ffffffffffffffffffffffffffffffffffffffff168152600190910190602001808311611302575050505050905090565b73ffffffffffffffffffffffffffffffffffffffff81166000908152600b6020526040812060010154600c80548392908110611e8d57fe5b9060005260206000209001549050611ea4816130ec565b91505b50919050565b73ffffffffffffffffffffffffffffffffffffffff331660009081526002602052604090205460ff1615156101cc57600080fd5b6000543373ffffffffffffffffffffffffffffffffffffffff908116911614611f0957600080fd5b73ffffffffffffffffffffffffffffffffffffffff811660009081526002602052604090205460ff1615611f3c57600080fd5b60045460329010611f4c57600080fd5b7f091a7a4b85135fdd7e8dbc18b12fabe5cc191ea867aa3c2e1a24a102af61d58b81600160405173ffffffffffffffffffffffffffffffffffffffff9092168252151560208201526040908101905180910390a173ffffffffffffffffffffffffffffffffffffffff8116600090815260026020526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016600190811790915560048054909181016116118382613c4f565b600e5473ffffffffffffffffffffffffffffffffffffffff1681565b600760209081526000928352604080842090915290825290205481565b600080543373ffffffffffffffffffffffffffffffffffffffff90811691161461206557600080fd5b73ffffffffffffffffffffffffffffffffffffffff821660009081526002602052604090205460ff16151561209957600080fd5b5073ffffffffffffffffffffffffffffffffffffffff8116600090815260026020526040812080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001690555b600454811015610f02578173ffffffffffffffffffffffffffffffffffffffff1660048281548110151561211657fe5b60009182526020909120015473ffffffffffffffffffffffffffffffffffffffff16141561227a57600480547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff810190811061216e57fe5b6000918252602090912001546004805473ffffffffffffffffffffffffffffffffffffffff90921691839081106121a157fe5b600091825260209091200180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055600480547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01906122209082613c4f565b507f091a7a4b85135fdd7e8dbc18b12fabe5cc191ea867aa3c2e1a24a102af61d58b82600060405173ffffffffffffffffffffffffffffffffffffffff9092168252151560208201526040908101905180910390a1610f02565b6001016120e6565b73ffffffffffffffffffffffffffffffffffffffff84166000908152600b602052604081205481908190819081908190819081908190610100900460ff1615156122cf576000985061252e565b73ffffffffffffffffffffffffffffffffffffffff8d166000908152600660205260409020541515612304576000985061252e565b73ffffffffffffffffffffffffffffffffffffffff8d166000908152600b6020526040902060010154600c8054909190811061233c57fe5b9060005260206000209001549750612353886130ec565b60095490975087018c1061236a576000985061252e565b6123758d888e612fbd565b90965094508a1561242a575073ffffffffffffffffffffffffffffffffffffffff8c166000908152600b60205260409020600301546123b6888e6001613112565b91508160000b600a0292506123cb81846131af565b90506123d88d8b83613216565b73ffffffffffffffffffffffffffffffffffffffff8e166000908152600b60205260409020909a508a94506124139060090187808701613241565b925061241f81846131af565b9584019590506124e8565b5073ffffffffffffffffffffffffffffffffffffffff8c166000908152600b6020526040812060040154906124629089908f90613112565b91508160000b600a02925061247781846131af565b73ffffffffffffffffffffffffffffffffffffffff8e166000908152600b602081905260409091207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8d0296509192506124d5910187860188613241565b92506124e181846131af565b9584019590505b6124f18d613342565b6124fa8761336d565b10612508576000985061252e565b6125118d6133a7565b61251c85870161336d565b1061252a576000985061252e565b8098505b5050505050505050949350505050565b6000612548613c78565b6000612552613c78565b600061255c613c78565b73ffffffffffffffffffffffffffffffffffffffff331660009081526002602052604090205460ff16151561259057600080fd5b88518a51600101146125a157600080fd5b86518851600101146125b257600080fd5b6010895111156125c157600080fd5b6010875111156125d057600080fd5b73ffffffffffffffffffffffffffffffffffffffff8b166000908152600b602052604090205460ff16151561260457600080fd5b60018a51111561266357600095505b60018a51038610156126635789866001018151811061262e57fe5b906020019060200201518a878151811061264457fe5b906020019060200201511261265857600080fd5b600190950194612613565b8951158061269957506f7fffffffffffffffffffffffffffffff8a60018151038151811061268d57fe5b90602001906020020151125b15156126a457600080fd5b600095505b8851861015612723577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd8f08987815181106126df57fe5b9060200190602002015112156126f457600080fd5b61271089878151811061270357fe5b90602001906020020151131561271857600080fd5b6001909501946126a9565b60018851111561278257600095505b60018851038610156127825787866001018151811061274d57fe5b9060200190602002015188878151811061276357fe5b906020019060200201511261277757600080fd5b600190950194612732565b875115806127b857506f7fffffffffffffffffffffffffffffff886001815103815181106127ac57fe5b90602001906020020151125b15156127c357600080fd5b600095505b8651861015612842577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd8f08787815181106127fe57fe5b90602001906020020151121561281357600080fd5b61271087878151811061282257fe5b90602001906020020151131561283757600080fd5b6001909501946127c8565b88516040518059106128515750595b90808252806020026020018201604052509450600095505b88518610156128ec57600189510386146128985789868151811061288957fe5b906020019060200201516128aa565b6f7fffffffffffffffffffffffffffffff5b93506128cb848a88815181106128bc57fe5b906020019060200201516133d2565b8587815181106128d757fe5b60209081029091010152600190950194612869565b86516040518059106128fb5750595b90808252806020026020018201604052509250600095505b865186101561298757600187510386146129425787868151811061293357fe5b90602001906020020151612954565b6f7fffffffffffffffffffffffffffffff5b9150612966828888815181106128bc57fe5b83878151811061297257fe5b60209081029091010152600190950194612913565b60006040518059106129965750595b90808252806020026020018201604052509050604080519081016040908152868252602080830184905273ffffffffffffffffffffffffffffffffffffffff8e166000908152600b909152206009018151819080516129f9929160200190613c8a565b50602082015181600101908051612a14929160200190613c8a565b50905050604080519081016040908152848252602080830184905273ffffffffffffffffffffffffffffffffffffffff8e166000908152600b918290529190912001815181908051612a6a929160200190613c8a565b50602082015181600101908051612a85929160200190613c8a565b5050505050505050505050505050565b6000543373ffffffffffffffffffffffffffffffffffffffff908116911614612abd57600080fd5b60606040519081016040908152848252602080830185905281830184905273ffffffffffffffffffffffffffffffffffffffff87166000908152600690915220815181556020820151816001015560408201516002909101555050505050565b600e543373ffffffffffffffffffffffffffffffffffffffff908116911614612b4557600080fd5b811515612b5857612b5584611e55565b91505b612b64848484846134b2565b50505050565b6000543373ffffffffffffffffffffffffffffffffffffffff908116911614612b9257600080fd5b73ffffffffffffffffffffffffffffffffffffffff811682156108fc0283604051600060405180830381858888f193505050501515612bd057600080fd5b7fec47e7ed86c86774d1a72c19f35c639911393fe7c1a34031fdbd260890da90de828260405191825273ffffffffffffffffffffffffffffffffffffffff1660208201526040908101905180910390a15050565b60008115612c5b575073ffffffffffffffffffffffffffffffffffffffff82166000908152600b6020526040902060030154612c86565b5073ffffffffffffffffffffffffffffffffffffffff82166000908152600b60205260409020600401545b92915050565b6000543373ffffffffffffffffffffffffffffffffffffffff908116911614612cb457600080fd5b600f5473ffffffffffffffffffffffffffffffffffffffff82811691161415612cdc57600080fd5b73ffffffffffffffffffffffffffffffffffffffff81166000908152600b602052604090205460ff1615612d0f57600080fd5b73ffffffffffffffffffffffffffffffffffffffff81166000908152600b6020526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001908117909155600a805490918101612d728382613c4f565b50600091825260209091200180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff8316179055600d541515612dd957600c805490612dd79060018301613c4f565b505b600c5473ffffffffffffffffffffffffffffffffffffffff82166000908152600b602052604090207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff909101600182810191909155600d546002909201829055600e910106600d55612e4a81613609565b612e5381613651565b50565b73ffffffffffffffffffffffffffffffffffffffff81166000908152600b60205260408120548190819081908190819060ff161515612e9457600080fd5b505073ffffffffffffffffffffffffffffffffffffffff85166000908152600b602052604090206001810154600290910154600c805483918391612ef1919084908110612edd57fe5b9060005260206000209001548a6001613112565b7f010000000000000000000000000000000000000000000000000000000000000002612f39600c86815481101515612f2557fe5b9060005260206000209001548b6000613112565b7f010000000000000000000000000000000000000000000000000000000000000002955095509550955050509193509193565b73ffffffffffffffffffffffffffffffffffffffff166000908152600660205260409020805460018201546002909201549092565b60005473ffffffffffffffffffffffffffffffffffffffff1681565b73ffffffffffffffffffffffffffffffffffffffff83166000908152600660205260408120548190612ff0868686613760565b9093509150612fff838261385b565b151561300e5791820291613032565b7f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff92505b61303c828261385b565b151561304b579081029061306f565b7f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff91505b50935093915050565b60006fffffffffffffffffffffffffffffffff828116600f0b90700100000000000000000000000000000000840416600f0b91506f7fffffffffffffffffffffffffffffff821415611abb577f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff9150915091565b7c010000000000000000000000000000000000000000000000000000000081045b919050565b73ffffffffffffffffffffffffffffffffffffffff82166000908152600b602052604081206002015481831561314c575060128101613152565b50600481015b85816020811061315e57fe5b1a7f0100000000000000000000000000000000000000000000000000000000000000027f01000000000000000000000000000000000000000000000000000000000000009004925050509392505050565b6000806a084595161401484a0000008411156131ca57600080fd5b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd8f08312156131f757600080fd5b61271083131561320657600080fd5b5050612710908101919091020490565b600080600061322486613884565b915060105490506132378582848761397e565b9695505050505050565b8254600090818080808085158061325757508789145b156132655760009650613335565b5087935060009250825b85811015613324578954613289908b908390811061174357fe5b909350915084831361329a5761331c565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd8f08214156132ea577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd8f09650613335565b87831261330f578185890302840193508888038481151561330757fe5b059650613335565b8185840302840193508294505b60010161326f565b8888038481151561333157fe5b0596505b5050505050509392505050565b73ffffffffffffffffffffffffffffffffffffffff1660009081526006602052604090206002015490565b6000808212156133a057507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff810261310d565b508061310d565b73ffffffffffffffffffffffffffffffffffffffff1660009081526006602052604090206001015490565b60006f7fffffffffffffffffffffffffffffff600f84900b1380159061341c57507fffffffffffffffffffffffffffffffff80000000000000000000000000000000600f84900b12155b151561342757600080fd5b6f7fffffffffffffffffffffffffffffff600f83900b1380159061346f57507fffffffffffffffffffffffffffffffff80000000000000000000000000000000600f83900b12155b151561347a57600080fd5b50600f91820b6fffffffffffffffffffffffffffffffff908116700100000000000000000000000000000000029190920b9091161790565b60008060006134bf613cd5565b73ffffffffffffffffffffffffffffffffffffffff8816600090815260066020526040812054600587069550888115156134f557fe5b73ffffffffffffffffffffffffffffffffffffffff8b1660009081526007602090815260408083208a8452909152812054929091059550935061353790613a17565b9150858260200151141561359657868260600151141561356b57838281815101905250836040830181815101905250613591565b613576898888613aa4565b84810160408401529250838281815101905250606082018790525b6135c0565b6135a1898888613760565b8584526020840188905260608401899052858201604085015290935090505b6135c982613b39565b73ffffffffffffffffffffffffffffffffffffffff9099166000908152600760209081526040808320978352969052949094209790975550505050505050565b60005b6005811015610f025773ffffffffffffffffffffffffffffffffffffffff8216600090815260076020908152604080832084845290915290206001908190550161360c565b73ffffffffffffffffffffffffffffffffffffffff811673eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee14156136b15773ffffffffffffffffffffffffffffffffffffffff8116600090815260086020526040902060129055612e53565b8073ffffffffffffffffffffffffffffffffffffffff1663313ce5676000604051602001526040518163ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401602060405180830381600087803b151561371d57600080fd5b6102c65a03f1151561372e57600080fd5b505050604051805173ffffffffffffffffffffffffffffffffffffffff83166000908152600860205260409020555050565b6000806000806000806000613773613cd5565b60009750600096506000955060009450899350889250600091505b60058210156138425773ffffffffffffffffffffffffffffffffffffffff8b1660009081526007602090815260408083208584529091529020546137d190613a17565b9050828160200151111580156137eb575083816020015110155b156137f7578051850194505b8981606001511461380757613837565b858160200151101561381857613837565b8060200151955080604001519750888160200151141561383757805196505b60019091019061378e565b87151561384d578497505b505050505050935093915050565b600081151561386c57506000612c86565b828283850281151561387a57fe5b0514159392505050565b60008073ffffffffffffffffffffffffffffffffffffffff831673eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee14156138c25760129150611ea7565b5073ffffffffffffffffffffffffffffffffffffffff8216600090815260086020526040902054801515612c86578273ffffffffffffffffffffffffffffffffffffffff1663313ce5676000604051602001526040518163ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401602060405180830381600087803b151561395c57600080fd5b6102c65a03f1151561396d57600080fd5b505050604051805190509150611ea7565b60006b204fce5e3e2502611000000085111561399957600080fd5b69d3c21bcecceda10000008211156139b057600080fd5b8383106139e357601284840311156139c757600080fd5b670de0b6b3a7640000858302858503600a0a025b049050613a0f565b601283850311156139f357600080fd5b828403600a0a670de0b6b3a7640000028286028115156139db57fe5b949350505050565b613a1f613cd5565b613a27613cd5565b67ffffffffffffffff83811660070b82526801000000000000000084041667ffffffffffffffff908116602083015270010000000000000000000000000000000084041660070b60408201527801000000000000000000000000000000000000000000000000830467ffffffffffffffff16606082015292915050565b600080613aaf613cd5565b83851115613abc57600080fd5b60009250600091505b60058210156119045773ffffffffffffffffffffffffffffffffffffffff86166000908152600760209081526040808320858452909152902054613b0890613a17565b905083816020015111158015613b22575084816020015110155b15613b2e578051830192505b600190910190613ac5565b600080678000000000000000835112613b5157600080fd5b7fffffffffffffffffffffffffffffffffffffffffffffffff8000000000000000835113613b7e57600080fd5b68010000000000000000836020015110613b9757600080fd5b678000000000000000604084015112613baf57600080fd5b7fffffffffffffffffffffffffffffffffffffffffffffffff8000000000000000604084015113613bdf57600080fd5b68010000000000000000836060015110613bf857600080fd5b67ffffffffffffffff83511690506801000000000000000083602001510217680100000000000000008067ffffffffffffffff60408601511602021768010000000000000000808060608601510202021792915050565b815481835581811511613c7357600083815260209020613c73918101908301613cfe565b505050565b60206040519081016040526000815290565b828054828255906000526020600020908101928215613cc5579160200282015b82811115613cc5578251825591602001919060010190613caa565b50613cd1929150613cfe565b5090565b608060405190810160405280600081526020016000815260200160008152602001600081525090565b61133591905b80821115613cd15760008155600101613d045600a165627a7a72305820022ee5985152f7a0bd923f02c03eb73494e8a9174f2a5b654aa7a336c2dffd380029000000000000000000000000fc68e9b0d3497db6dc1ce68d25d45315b8cc3076000000000000000000000000fcdccd4cd29bd4b53274c8e900b00a6db3460e08

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

000000000000000000000000fc68e9b0d3497db6dc1ce68d25d45315b8cc3076000000000000000000000000fcdccd4cd29bd4b53274c8e900b00a6db3460e08

-----Decoded View---------------
Arg [0] : _admin (address): 0xfc68e9b0d3497db6dc1ce68d25d45315b8cc3076
Arg [1] : _quoteToken (address): 0xfcdccd4cd29bd4b53274c8e900b00a6db3460e08

-----Encoded View---------------
2 Constructor Arguments found :
Arg [0] : 000000000000000000000000fc68e9b0d3497db6dc1ce68d25d45315b8cc3076
Arg [1] : 000000000000000000000000fcdccd4cd29bd4b53274c8e900b00a6db3460e08


Deployed ByteCode Sourcemap

43514:1474:0:-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;6397:463;;;;;;;;;;;;;;;;;;23463:105;;;;;;;;;;;;;;;;23302:153;;;;;;;;;;;;;;;;18797:42;;;;;;;;;;;;;;;;;;;;;;;;;;;20925:767;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;20925:767:0;;-1:-1:-1;20925:767:0;;-1:-1:-1;;;;;;20925:767:0;23073:221;;;;;;;;;;;;;;;;4021:27;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;4632:98;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;23:1:-1;8:100;33:3;30:1;27:2;8:100;;;99:1;94:3;90;84:5;71:3;;;64:6;52:2;45:3;8:100;;;12:14;3:109;;;;;;;;;;;;;;;;;29661:94:0;;;;;;;;;;;;8303:189;;;;;;;;;;;;;;;;;;;;;;;;6081:308;;;;;;;;;;;;;;;;19027:45;;;;;;;;;;;;40079:427;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;35156:1348;;;;;;;;;;;;;;;;;;;;20295:622;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;20295:622:0;;-1:-1:-1;20295:622:0;;-1:-1:-1;;;;;;20295:622:0;22940:125;;;;;;;;;;;;;;27616:149;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;5050:187;;;;;;;;;;;;;;;;5819:194;;;;;;;;;;;;5418:223;;;;;;;;;;;;;;;;4738:96;;;;;;;;;;;;29440:213;;;;;;;;;;;;;;;;32560:185;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;32560:185:0;;-1:-1:-1;32560:185:0;;-1:-1:-1;;;;;;32560:185:0;6929:319;;;;;;;;;;;;;;;;19079:30;;;;;;;;;;;;9562:65;;;;;;;;;;;;;;;;;;7256:481;;;;;;;;;;;;;;;;36558:2628;;;;;;;;;;;;;;;;;;;;;;;;32753:2352;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;32753:2352:0;;-1:-1:-1;32753:2352:0;;-1:-1:-1;;;;;;32753:2352:0;9773:412;;;;;;;;;;;;;;;;;;;;;;23576:378;;;;;;;;;;;;;;;;;;;;;;8604:153;;;;;;;;;;;;;;;;;;26846:212;;;;;;;;;;;;;;;;;;;;43923:750;;;;;;;;;;;;;;;;27066:542;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;10193:278;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;3994:20;;;;;;;;;;;;6397:463;6546:6;4414:5;;4400:10;4414:5;4400:19;;;4414:5;;4400:19;4392:28;;;;;;6474:17;;;;;;;:8;:17;;;;;;;;6466:26;;;;;;;;-1:-1:-1;6503:17:0;;;6523:5;6503:17;;;:8;:17;;;;;:25;;;;;;6541:312;6562:13;:20;6558:24;;6541:312;;;6628:7;6608:27;;:13;6622:1;6608:16;;;;;;;;;;;;;;;;;;;;;;:27;6604:238;;;6675:13;6689:20;;:24;;;;6675:39;;;;;;;;;;;;;;;;6656:13;:16;;6675:39;;;;;6670:1;;6656:16;;;;;;;;;;;;;;;:58;;;;;;;;;;;;;;;6733:13;:22;;;;;;;;;:::i;:::-;;6774:28;6787:7;6796:5;6774:28;;;;;;;;;;;;;;;;;;;;;;;;;6821:5;;6604:238;6584:3;;6541:312;;;6397:463;;:::o;23463:105::-;4414:5;;4400:10;4414:5;4400:19;;;4414:5;;4400:19;4392:28;;;;;;23535:15;:25;;;;;;;;;;;;;;;23463:105::o;23302:153::-;4583:20;4592:10;4583:20;;;;;:8;:20;;;;;;;;4575:29;;;;;;;;23380:16;;;;;;;:9;:16;;;;;:23;;;23372:32;;;;;;;;23415:16;;23442:5;23415:16;;;:9;:16;;;;;:32;;;;;;23302:153::o;18797:42::-;;;;:::o;20925:767::-;4491:21;4501:10;4491:21;21388:8;4491:21;;;:9;:21;;;;;;;;4483:30;;;;;;;;21209:7;:14;21192:6;:13;:31;21184:40;;;;;;21260:8;:15;21243:6;:13;:32;21235:41;;;;;;21310:3;:10;21295:4;:11;:25;21287:34;;;;;;21355:7;:14;21340:4;:11;:29;21332:38;;;;;;-1:-1:-1;21399:1:0;21383:242;21408:6;:13;21402:3;:19;21383:242;;;21453:9;:22;21463:6;21470:3;21463:11;;;;;;;;;;;;;;;;21453:22;;;;;;;;;;;;;-1:-1:-1;21453:22:0;:29;;;21445:38;;;;;;;;21535:7;21543:3;21535:12;;;;;;;;;;;;;;;;21498:9;:22;21508:6;21515:3;21508:11;;;;;;;;;;;;;;;;21498:22;;;;;;;;;;;;;-1:-1:-1;21498:22:0;:34;;:49;21600:8;21609:3;21600:8;:13;;;;;;;;;;;;;;;21562:9;:22;21572:6;21579:3;21572:11;;;;;;;;;;;;;;;;21562:22;;;;;;;;;;;;;-1:-1:-1;21562:22:0;:35;;:51;21423:5;;21383:242;;;21637:47;21652:3;21657:4;21663:11;21676:7;21637:14;:47::i;:::-;20925:767;;;;;;;;:::o;23073:221::-;4414:5;;4400:10;4414:5;4400:19;;;4414:5;;4400:19;4392:28;;;;;;23148:16;;;;;;;:9;:16;;;;;:23;;;23140:32;;;;;;;;23191:23;;;;;;;:16;:23;;;;;:47;:52;;23183:61;;;;;;23255:16;;;;;;:9;:16;;;;;:31;;;;;;;;23073:221::o;4021:27::-;;;;;;:::o;4632:98::-;4679:9;;:::i;:::-;4708:14;4701:21;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;4632:98;;:::o;29661:94::-;29708:7;;:::i;:::-;29735:12;29728:19;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;29661:94;:::o;8303:189::-;4414:5;;4400:10;4414:5;4400:19;;;4414:5;;4400:19;4392:28;;;;;;8406:5;:14;;;8421:6;8429;8406:30;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8398:39;;;;;;;;8448:36;8462:5;8469:6;8477;8448:36;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8303:189;;;:::o;6081:308::-;4414:5;;4400:10;4414:5;4400:19;;;4414:5;;4400:19;4392:28;;;;;;6158:20;;;;;;;:8;:20;;;;;;;;6157:21;6149:30;;;;;;6221:13;:20;4269:2;6221:37;;6213:46;;;;;;6272:30;6285:10;6297:4;6272:30;;;;;;;;;;;;;;;;;;;;;;;;;6313:20;;;;;;;:8;:20;;;;;:27;;;;6336:4;6313:27;;;;;;6351:13;:30;;:13;;:30;;;:13;:30;;:::i;:::-;-1:-1:-1;6351:30:0;;;;;;;;;;;;;;;;;;;;;;;;6081:308::o;19027:45::-;;;;:::o;40079:427::-;40177:18;40197:25;40240:20;40373:14;40263:25;40282:5;40263:18;:25::i;:::-;40240:48;-1:-1:-1;40390:15:0;;:43;;40423:10;40390:43;;;40408:12;40390:43;40373:60;;40451:47;40464:5;40471:15;40488:9;40451:12;:47::i;:::-;40444:54;;;;40079:427;;;;;;;:::o;35156:1348::-;35244:3;35361:14;35386;35264:7;35275:1;35264:12;35260:88;;;35289:16;;;;;;;:9;:16;;;;;:45;;:54;:58;;;-1:-1:-1;35278:70:0;;35260:88;35417:7;35428:1;35417:12;35413:182;;;35496:16;;;;;;;:9;:16;;;;;:45;;:54;;35473:78;;35496:45;35544:5;;35496:54;;;;;;;;;;;;;;;35473:22;:78::i;:::-;35446:105;;-1:-1:-1;35446:105:0;;-1:-1:-1;35446:105:0;-1:-1:-1;35566:17:0;;35413:182;35611:7;35622:2;35611:13;35607:85;;;35637:16;;;;;;;:9;:16;;;;;:45;;:54;;-1:-1:-1;35626:66:0;;35607:85;35707:7;35718:2;35707:13;35703:183;;;35787:16;;;;;;;:9;:16;;;;;:45;;:54;;35764:78;;35787:45;35835:5;;35787:54;;;;;35764:78;35737:105;-1:-1:-1;35737:105:0;-1:-1:-1;35737:105:0;;-1:-1:-1;35857:17:0;;35703:183;35902:7;35913:2;35902:13;35898:90;;;35928:16;;;;;;;:9;:16;;;;;;;;:46;:55;:59;;;-1:-1:-1;35917:71:0;;35898:90;36003:7;36014:2;36003:13;35999:184;;;36083:16;;;;;;;:9;:16;;;;;;;;:46;:55;;36060:79;;36083:46;36132:5;;36083:55;;;;;35999:184;36199:7;36210:2;36199:13;36195:86;;;36225:16;;;;;;;:9;:16;;;;;;;;:46;:55;;-1:-1:-1;36214:67:0;;36195:86;36296:7;36307:2;36296:13;36292:184;;;36376:16;;;;;;;:9;:16;;;;;;;;:46;:55;;36353:79;;36376:46;36425:5;;36376:55;;;;;35156:1348;;;;;;;;:::o;20295:622::-;4491:21;4501:10;4491:21;20557:18;4491:21;;;:9;:21;;;;;;20557:18;;;;4491:21;;4483:30;;;;;;;;20439:4;:11;20425:3;:10;:25;20417:34;;;;;;20488:3;:10;20470:7;:14;:28;20462:37;;;;;;20533:10;20518:25;;;20510:34;;;;;;19219:37;;-1:-1:-1;20620:1:0;;-1:-1:-1;20606:304:0;20627:7;:14;20623:1;:18;20606:304;;;20684:21;:28;20671:7;20679:1;20671:7;:10;;;;;;;;;;;;;;;:41;20663:50;;;;;;20819:13;20803;:29;20788:11;:45;20771:13;20760:4;20765:1;20760:7;;;;;;;;;;;;;;;;20755:13;;;:29;20745:3;20749:1;20745:6;;;;;;;;;;;;;;;;20740:12;;;:44;:94;;-1:-1:-1;20740:94:0;20849:21;20871:7;20879:1;20871:7;:10;;;;;;;;;;;;;;;20849:33;;;;;;;;;;;;;;;;;:49;20643:3;;;;;20606:304;;;20295:622;;;;;;;:::o;22940:125::-;4414:5;;4400:10;4414:5;4400:19;;;4414:5;;4400:19;4392:28;;;;;;23021:25;:36;22940:125::o;27616:149::-;27707:16;;;27676:4;27707:16;;;:9;:16;;;;;:23;;;;;;;27732:24;;;27616:149;;;;:::o;5050:187::-;4414:5;;4400:10;4414:5;4400:19;;;4414:5;;4400:19;4392:28;;;;;;5127:22;;;;;5119:31;;;;;;5182:12;;5161:34;;5182:12;;5161:34;;;;;;;;;;;;;;;;;5206:12;:23;;;;;;;;;;;;;;;5050:187::o;5819:194::-;5867:12;;5883:10;5867:26;;;;:12;;:26;5859:35;;;;;;5918:12;;;5932:5;5905:33;;5918:12;;;;;5932:5;5905:33;;;;;;;;;;;;;;;;;;;;;;;;;5957:12;;;;5949:20;;;;;;5957:12;;;5949:20;;;;5980:25;;;5819:194::o;5418:223::-;4414:5;;4400:10;4414:5;4400:19;;;4414:5;;4400:19;4392:28;;;;;;5502:22;;;;;5494:31;;;;;;5536:30;5557:8;5536:30;;;;;;;;;;;;;;;;;5600:5;;5577:29;;5590:8;;5600:5;;5577:29;;;;;;;;;;;;;;;;;;;;;;;;;5617:5;:16;;;;;;;;;;;;;;;5418:223::o;4738:96::-;4784:9;;:::i;:::-;4813:13;4806:20;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;4738:96;:::o;29440:213::-;29562:16;;;29501:4;29562:16;;;:9;:16;;;;;:38;;;29540:21;:61;;29501:4;;29562:38;29540:61;;;;;;;;;;;;;;;29518:83;;29619:26;29633:11;29619:13;:26::i;:::-;29612:33;;29440:213;;;;;:::o;32560:185::-;4491:21;4501:10;4491:21;;;;;:9;:21;;;;;;;;4483:30;;;;;;;6929:319;4414:5;;4400:10;4414:5;4400:19;;;4414:5;;4400:19;4392:28;;;;;;7008:22;;;;;;;:9;:22;;;;;;;;7007:23;6999:32;;;;;;7073:14;:21;4269:2;7073:38;;7065:47;;;;;;7125:32;7139:11;7152:4;7125:32;;;;;;;;;;;;;;;;;;;;;;;;;7168:22;;;;;;;:9;:22;;;;;:29;;;;7193:4;7168:29;;;;;;7208:14;:32;;:14;;:32;;;:14;:32;;:::i;19079:30::-;;;;;;:::o;9562:65::-;;;;;;;;;;;;;;;;;;;;;;;;:::o;7256:481::-;7411:6;4414:5;;4400:10;4414:5;4400:19;;;4414:5;;4400:19;4392:28;;;;;;7335:19;;;;;;;:9;:19;;;;;;;;7327:28;;;;;;;;-1:-1:-1;7366:19:0;;;7388:5;7366:19;;;:9;:19;;;;;:27;;;;;;7406:324;7427:14;:21;7423:25;;7406:324;;;7495:8;7474:29;;:14;7489:1;7474:17;;;;;;;;;;;;;;;;;;;;;;:29;7470:249;;;7544:14;7559:21;;:25;;;;7544:41;;;;;;;;;;;;;;;;7524:14;:17;;7544:41;;;;;7539:1;;7524:17;;;;;;;;;;;;;;;:61;;;;;;;;;;;;;;;7604:14;:26;;;;;;;;;:::i;:::-;;7649:30;7663:8;7673:5;7649:30;;;;;;;;;;;;;;;;;;;;;;;;;7698:5;;7470:249;7450:3;;7406:324;;36558:2628;36713:16;;;36653:4;36713:16;;;:9;:16;;;;;:24;36653:4;;;;;;;;;;;;;;;;36713:24;;;;;36712:25;36708:39;;;36746:1;36739:8;;;;36708:39;36762:23;;;;;;;:16;:23;;;;;:47;:52;36758:66;;;36823:1;36816:8;;;;36758:66;36945:16;;;;;;;:9;:16;;;;;:38;;;36923:21;:61;;:21;;36945:38;36923:61;;;;;;;;;;;;;;;36901:83;;37020:26;37034:11;37020:13;:26::i;:::-;37101:25;;36997:49;;-1:-1:-1;37083:43:0;;37061:65;;37057:79;;37135:1;37128:8;;;;37057:79;37287:56;37300:5;37307:15;37324:18;37287:12;:56::i;:::-;37252:91;;-1:-1:-1;37252:91:0;-1:-1:-1;37488:1497:0;;;;-1:-1:-1;37556:16:0;;;;;;;:9;:16;;;;;:28;;;37646:52;37673:11;37566:5;37693:4;37646:26;:52::i;:::-;37633:65;;37728:10;37724:15;;37742:2;37724:20;37713:31;;37766:22;37773:4;37779:8;37766:6;:22::i;:::-;37759:29;;37845;37857:5;37864:3;37869:4;37845:11;:29::i;:::-;38017:16;;;;;;;:9;:16;;;;;37839:35;;-1:-1:-1;37839:35:0;;-1:-1:-1;37979:179:0;;38017:45;;38081:14;38114:29;;;37979:19;:179::i;:::-;37968:190;;38180:22;38187:4;38193:8;38180:6;:22::i;:::-;38217:30;;;;38173:29;-1:-1:-1;37488:1497:0;;;-1:-1:-1;38324:16:0;;;;;;;:9;:16;;;;;:29;;;;38415:53;;38442:11;;38334:5;;38415:26;:53::i;:::-;38402:66;;38498:10;38494:15;;38512:2;38494:20;38483:31;;38536:22;38543:4;38549:8;38536:6;:22::i;:::-;38742:16;;;;;;;:9;:16;;;;;;;;38624:2;:13;;;-1:-1:-1;38529:29:0;;-1:-1:-1;38704:180:0;;38742:46;38807:29;;;:14;38704:19;:180::i;:::-;38693:191;;38906:22;38913:4;38919:8;38906:6;:22::i;:::-;38943:30;;;;38899:29;-1:-1:-1;37488:1497:0;39024:27;39045:5;39024:20;:27::i;:::-;39001:19;39005:14;39001:3;:19::i;:::-;:50;38997:64;;39060:1;39053:8;;;;38997:64;39114:30;39138:5;39114:23;:30::i;:::-;39076:34;39097:12;39080:14;:29;39076:3;:34::i;:::-;:68;39072:82;;39153:1;39146:8;;;;39072:82;39174:4;39167:11;;36558:2628;;;;;;;;;;;;;;;:::o;32753:2352::-;33216:6;34308:21;;:::i;:::-;34413:14;34588:22;;:::i;:::-;34696:15;34877:21;;:::i;:::-;4491;4501:10;4491:21;;;;;:9;:21;;;;;;;;4483:30;;;;;;;;32983:4;:11;32964:4;:11;32978:1;32964:15;:30;32956:39;;;;;;33034:5;:12;33014:5;:12;33029:1;33014:16;:32;33006:41;;;;;;32065:2;33066:4;:11;:36;;33058:45;;;;;;32065:2;33122:5;:12;:37;;33114:46;;;;;;33179:16;;;;;;;:9;:16;;;;;:23;;;33171:32;;;;;;;;33253:1;33239:4;:11;:15;33235:191;;;33321:1;33317:5;;33313:102;33342:1;33328:4;:11;:15;33324:1;:19;33313:102;;;33387:4;33392:1;33396;33392:5;33387:11;;;;;;;;;;;;;;;;33377:4;33382:1;33377:7;;;;;;;;;;;;;;;;:21;33369:30;;;;;;33345:3;;;;;33313:102;;;33507:4;:11;:16;;:58;;-1:-1:-1;32223:12:0;33527:4;33546:1;33527:4;33532:11;:15;33527:21;;;;;;;;;;;;;;;;:38;33507:58;33499:67;;;;;;;;33611:1;33607:5;;33603:151;33618:4;:11;33614:1;:15;33603:151;;;19431:10;33659:4;33664:1;33659:7;;;;;;;;;;;;;;;;:29;;33651:38;;;;;;32347:9;33712:4;33717:1;33712:7;;;;;;;;;;;;;;;;:29;;33704:38;;;;;;33631:3;;;;;33603:151;;;33785:1;33770:5;:12;:16;33766:195;;;33853:1;33849:5;;33845:105;33875:1;33860:5;:12;:16;33856:1;:20;33845:105;;;33921:5;33927:1;33931;33927:5;33921:12;;;;;;;;;;;;;;;;33910:5;33916:1;33910:8;;;;;;;;;;;;;;;;:23;33902:32;;;;;;33878:3;;;;;33845:105;;;34042:5;:12;:17;;:61;;-1:-1:-1;32223:12:0;34063:5;34084:1;34063:5;34069:12;:16;34063:23;;;;;;;;;;;;;;;;:40;34042:61;34034:70;;;;;;;;34150:1;34146:5;;34142:154;34157:5;:12;34153:1;:16;34142:154;;;19431:10;34199:5;34205:1;34199:8;;;;;;;;;;;;;;;;:30;;34191:39;;;;;;32347:9;34253:5;34259:1;34253:8;;;;;;;;;;;;;;;;:30;;34245:39;;;;;;34171:3;;;;;34142:154;;;34342:4;:11;34332:22;;;;;;;;;;;;;;;;;;;;;;;;34308:46;;34373:1;34369:5;;34365:211;34380:4;:11;34376:1;:15;34365:211;;;34450:1;34436:4;:11;:15;34431:1;:20;34430:57;;34479:4;34484:1;34479:7;;;;;;;;;;;;;;;;34430:57;;;32223:12;34430:57;34413:74;;34516:48;34539:7;34555:4;34560:1;34555:7;;;;;;;;;;;;;;;;34516:22;:48::i;:::-;34502:8;34511:1;34502:11;;;;;;;;;;;;;;;;:62;34393:3;;;;;34365:211;;;34623:5;:12;34613:23;;;;;;;;;;;;;;;;;;;;;;;;34588:48;;34655:1;34651:5;;34647:218;34662:5;:12;34658:1;:16;34647:218;;;34735:1;34720:5;:12;:16;34715:1;:21;34714:59;;34764:5;34770:1;34764:8;;;;;;;;;;;;;;;;34714:59;;;32223:12;34714:59;34696:77;;34803:50;34826:8;34843:5;34849:1;34843:8;;;;;;;34803:50;34788:9;34798:1;34788:12;;;;;;;;;;;;;;;;:65;34676:3;;;;;34647:218;;;34911:1;34901:12;;;;;;;;;;;;;;;;;;;;;;;;34877:36;;34972:32;;;;;;;;;;;;;;;;;;;;34924:16;;;-1:-1:-1;34924:16:0;;;:9;:16;;;;:45;;34972:32;34924:80;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;35064:33;;;;;;;;;;;;;;;;;;;;35015:16;;;-1:-1:-1;35015:16:0;;;:9;:16;;;;;;;;:46;35064:33;35015:82;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;;;;;;;;;;;;;;32753:2352:0:o;9773:412::-;4414:5;;4400:10;4414:5;4400:19;;;4414:5;;4400:19;4392:28;;;;;;10029:148;;;;;;;;;;;;;;;;;;;;;;;;;;9990:23;;;-1:-1:-1;9990:23:0;;;:16;:23;;;;10029:148;9990:187;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;9773:412:0:o;23576:378::-;23767:15;;23753:10;23767:15;23753:29;;;23767:15;;23753:29;23745:38;;;;;;23800:20;;23796:69;;;23840:25;23859:5;23840:18;:25::i;:::-;23822:43;;23796:69;23885:61;23898:5;23905:9;23916:15;23933:12;23885;:61::i;:::-;23576:378;;;;:::o;8604:153::-;4414:5;;4400:10;4414:5;4400:19;;;4414:5;;4400:19;4392:28;;;;;;8686:15;;;:23;;;;8702:6;8686:23;;;;;;;;;;;;;;;;;;;;;;;;;;8720:29;8734:6;8742;8720:29;;;;;;;;;;;;;;;;;;;;;;8604:153;;:::o;26846:212::-;26911:4;26932:3;26928:122;;;-1:-1:-1;26957:16:0;;;;;;;:9;:16;;;;;:28;;;26950:35;;26928:122;-1:-1:-1;27021:16:0;;;;;;;:9;:16;;;;;:29;;;26928:122;26846:212;;;;:::o;43923:750::-;4414:5;;4400:10;4414:5;4400:19;;;4414:5;;4400:19;4392:28;;;;;;43999:10;;;43990:19;;;43999:10;;43990:19;;43982:28;;;;;;44030:16;;;;;;;:9;:16;;;;;:23;;;44029:24;44021:33;;;;;;44065:16;;;;;;;:9;:16;;;;;:30;;;;44091:4;44065:30;;;;;;44106:12;:24;;:12;;:24;;;:12;:24;;:::i;:::-;-1:-1:-1;44106:24:0;;;;;;;;;;;;;;;;;;;44147:29;;:34;44143:118;;;44198:21;:30;;;;;;;;;:::i;:::-;;44143:118;44327:21;:28;44273:16;;;;;;;:9;:16;;;;;44327:45;;;;44371:1;44273:38;;;:99;;;;44424:29;;44383:38;;;;:70;;;19168:2;;44512:33;44511:77;44466:29;:122;44601:33;44628:5;44601:26;:33::i;:::-;44647:18;44659:5;44647:11;:18::i;:::-;43923:750;:::o;27066:542::-;27166:16;;;27123:4;27166:16;;;:9;:16;;;;;:23;27123:4;;;;;;;;;;27166:23;;27158:32;;;;;;;;-1:-1:-1;;27221:16:0;;;;;;;:9;:16;;;;;:38;;;;27289;;;;;27445:21;:33;;27221:38;;27289;;27418:74;;27445:21;27221:38;;27445:33;;;;;;;;;;;;;;;27480:5;27487:4;27418:26;:74::i;:::-;27413:80;;27513:75;27540:21;27562:10;27540:33;;;;;;;;;;;;;;;;;;;27575:5;27582;27513:26;:75::i;:::-;27508:81;;27340:260;;;;;;;;27066:542;;;;;;;:::o;10193:278::-;10292:23;;10255:4;10292:23;;;:16;:23;;;;;:47;;10358:44;;;;10421:41;;;;;10292:47;;10193:278::o;3994:20::-;;;;;;:::o;39245:826::-;39445:23;;;39361:18;39445:23;;;:16;:23;;;;;:47;39361:18;;39561:117;39462:5;39631:15;39665:12;39561:27;:117::i;:::-;39506:172;;-1:-1:-1;39506:172:0;-1:-1:-1;39696:45:0;39506:172;39730:10;39696:17;:45::i;:::-;39695:46;39691:170;;;39758:28;;;;39691:170;;;32112:12;39819:30;;39691:170;39878:52;39896:21;39919:10;39878:17;:52::i;:::-;39877:53;39873:191;;;39947:35;;;;39873:191;;;32112:12;40015:37;;39873:191;39245:826;;;;;;;:::o;42523:308::-;42587:5;42640:13;42627:27;;;42616:40;;;32166:8;42632:3;42683:21;42682:41;42671:54;;;-1:-1:-1;32223:12:0;42776:24;;42772:52;;;32112:12;42804:17;;42523:308;;;:::o;30025:215::-;30198:33;30187:45;;30025:215;;;;:::o;30248:393::-;30379:16;;;30343:4;30379:16;;;:9;:16;;;;;:38;;;30343:4;30454:137;;;;-1:-1:-1;30489:31:0;:45;;30454:137;;;-1:-1:-1;30576:1:0;:15;;30454:137;30616:4;30621:10;30616:16;;;;;;;;;;30611:22;;;30604:29;;30248:393;;;;;;;:::o;40514:293::-;40572:4;;31963:19;40597:16;;;40589:25;;;;;;19431:10;40633:25;;;40625:34;;;;;;32347:9;40678:25;;;40670:34;;;;;;-1:-1:-1;;40731:9:0;40771:17;;;40759:30;;;;40758:41;;40514:293::o;44681:304::-;44804:7;44824:19;44875;44846:18;44858:5;44846:11;:18::i;:::-;44824:40;;44897:8;;44875:30;;44925:52;44936:8;44946:11;44959;44972:4;44925:10;:52::i;:::-;44918:59;44681:304;-1:-1:-1;;;;;;44681:304:0:o;40815:1297::-;40937:10;;40908:3;;;;;;;40964:8;;;:22;;;40984:2;40976:4;:10;40964:22;40960:41;;;40997:1;40990:8;;;;40960:41;-1:-1:-1;41027:4:0;;-1:-1:-1;41094:1:0;;-1:-1:-1;41094:1:0;41227:838;41251:3;41245;:9;41227:838;;;41328:8;;41305:32;;41328:1;;41332:3;;41328:8;;;;;41305:32;41278:59;;-1:-1:-1;41278:59:0;-1:-1:-1;41356:21:0;;;41352:40;;41381:8;;41352:40;19431:10;41481;:32;41477:68;;;19431:10;41517:25;;;;41477:68;41710:16;;;41706:265;;41774:10;41763:7;41758:2;:12;41757:27;41747:37;;;;41825:4;41820:2;:9;41810:6;:20;;;;;;;;41803:27;;;;41706:265;41906:10;41895:7;41882:10;:20;41881:35;41871:45;;;;41945:10;41935:20;;41706:265;41256:5;;41227:838;;;42099:4;42094:2;:9;42084:6;:20;;;;;;;;42077:27;;40815:1297;;;;;;;;;;;;:::o;15407:138::-;15496:23;;15472:4;15496:23;;;:16;:23;;;;;:41;;;;15407:138::o;31215:153::-;31257:4;31282:1;31278;:5;31274:86;;;-1:-1:-1;31310:2:0;:6;;31298:19;;31274:86;-1:-1:-1;31358:1:0;31346:14;;15255:144;15347:23;;15323:4;15347:23;;;:16;:23;;;;;:44;;;;15255:144::o;42188:327::-;42262:8;32223:12;42291:19;;;;;;;;:42;;-1:-1:-1;32284:13:0;42314:19;;;;;;42291:42;42283:51;;;;;;;;32223:12;42353:19;;;;;;;;:42;;-1:-1:-1;32284:13:0;42376:19;;;;;;42353:42;42345:51;;;;;;;;-1:-1:-1;42418:7:0;42468;;;42429:13;42468:25;;;32166:8;42467:39;42418:7;;;;:25;;;42455:52;;42188:327::o;10479:2047::-;10647:22;10717:21;10823:17;10857:42;;:::i;:::-;10761:23;;;11947:25;10761:23;;;:16;:23;;;;;:47;8955:1;10672:34;;;-1:-1:-1;10745:9:0;:64;;;;;;;10940:25;;;10843:1;10940:25;;;:18;:25;;;;;;;;:44;;;;;;;;;10745:64;;;;;-1:-1:-1;10843:1:0;-1:-1:-1;10915:70:0;;:24;:70::i;:::-;10857:128;;11107:12;11077:16;:26;;;:42;11073:1344;;;11186:15;11145:16;:36;;;11140:61;11136:733;;;11313:17;11266:16;11313:17;11266:16;:64;;;;-1:-1:-1;11392:17:0;11349:39;;;11392:17;11349:39;:60;;;;-1:-1:-1;11136:733:0;;;11535:57;11555:5;11562:15;11579:12;11535:19;:57::i;:::-;11653:38;;;11611:39;;;:80;11519:73;-1:-1:-1;11674:17:0;11611:16;11674:17;11611:16;11710:64;;;;-1:-1:-1;11793:36:0;;;:60;;;11136:733;11073:1344;;;12028:65;12056:5;12063:15;12080:12;12028:27;:65::i;:::-;12110:63;;;12188:26;;;:47;;;12250:36;;;:60;;;12367:38;;;12325:39;;;:80;11987:106;;-1:-1:-1;11987:106:0;-1:-1:-1;11073:1344:0;12476:42;12501:16;12476:24;:42::i;:::-;12429:25;;;;;;;;:18;:25;;;;;;;;:44;;;;;;;;;;:89;;;;-1:-1:-1;;;;;;;10479:2047:0:o;12534:184::-;12608:6;12603:108;8955:1;12620;:23;12603:108;;;12665:25;;;;;;;:18;:25;;;;;;;;:28;;;;;;;;12696:3;12665:34;;;;12645:3;12603:108;;1368:174;1426:26;;;966:44;1426:26;1422:112;;;1454:15;;;;;;;:8;:15;;;;;1310:2;1454:30;;1422:112;;;1518:5;:14;;;:16;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;1500:15;;;;;;;:8;:15;;;;;:34;-1:-1:-1;1368:174:0;:::o;13385:1324::-;13516:16;13534:25;13640:16;13671:20;13706:15;13750:13;13796:14;13877:38;;:::i;:::-;13592:1;13577:16;;13628:1;13604:25;;13659:1;13640:20;;13694:1;13671:24;;13724:15;13706:33;;13766:12;13750:28;;13813:1;13796:18;;13791:818;8955:1;13816:9;:31;13791:818;;;13943:25;;;;;;;:18;:25;;;;;;;;:36;;;;;;;;;13918:62;;:24;:62::i;:::-;13877:103;;14027:8;14001:12;:22;;;:34;;:74;;;;;14065:10;14039:12;:22;;;:36;;14001:74;13997:174;;;14116:12;:39;14096:59;;;;13997:174;14227:15;14191:12;:32;;;:51;14187:65;;14244:8;;14187:65;14296:11;14271:12;:22;;;:36;14267:50;;;14309:8;;14267:50;14348:12;:22;;;14334:36;;14400:12;:35;;;14385:50;;14486:12;14459;:22;;;14454:44;14450:148;;;14543:12;:39;14519:63;;14450:148;13849:11;;;;;13791:818;;;14625:17;;14621:81;;;14674:16;14659:31;;14621:81;13385:1324;;;;;;;;;;;;:::o;42839:148::-;42902:4;42923:6;;42919:24;;;-1:-1:-1;42938:5:0;42931:12;;42919:24;42977:1;42971;42966;42964;:3;42963:9;;;;;;;;42962:16;;;42839:148;-1:-1:-1;;;42839:148:0:o;1550:479::-;1606:4;;1627:26;;;966:44;1627:26;1623:51;;;1310:2;1655:19;;;;1623:51;-1:-1:-1;1729:15:0;;;;;;;:8;:15;;;;;;1945:18;;1942:46;;;1972:5;:14;;;:16;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;1965:23;;;;2037:569;2139:4;1106:6;2164:17;;;2156:26;;;;;;1171:17;2201:16;;;2193:25;;;;;;2235:26;;;2231:368;;1262:2;2287:25;;;2286:43;;2278:52;;;;;;1055:6;2353:13;;;2375:25;;;2370:2;:31;2353:49;2352:63;;2345:70;;;;2231:368;1262:2;2457:25;;;2456:43;;2448:52;;;;;;2573:11;2559;:25;2554:2;:31;1055:6;2541:45;2532:4;2523:6;:13;2522:65;;;;;;2231:368;2037:569;;;;;;:::o;16434:514::-;16502:18;;:::i;:::-;16533:30;;:::i;:::-;16629:12;16620:22;;;16610:34;;16576:68;;8997:7;16620:5;16685:16;16684:35;16672:49;;;;16655:14;;;:66;16782:19;16773:5;:29;16772:48;16762:60;;16732:27;;;:90;16882:30;16873:5;:40;16860:56;;16833:24;;;:83;:24;16434:514;-1:-1:-1;;16434:514:0:o;12726:651::-;12822:16;12983:14;13064:38;;:::i;:::-;12913:22;;;;12905:31;;;;;;12964:1;12949:16;;13000:1;12983:18;;12978:392;8955:1;13003:9;:31;12978:392;;;13130:25;;;;;;;:18;:25;;;;;;;;:36;;;;;;;;;13105:62;;:24;:62::i;:::-;13064:103;;13214:8;13188:12;:22;;;:34;;:74;;;;;13252:10;13226:12;:22;;;:36;;13188:74;13184:175;;;13303:12;:39;13283:60;;;;13184:175;13036:11;;;;;12978:392;;15553:873;15634:4;;15729:12;15691:4;:31;:51;15683:60;;;;;;15800:22;15762:4;:31;:61;15754:70;;;;;;8997:7;15843:4;:14;;;:25;15835:34;;;;;;15922:12;15888:27;;;;:47;15880:56;;;;;;15989:22;15955:27;;;;:57;15947:66;;;;;;8997:7;16032:4;:24;;;:35;16024:44;;;;;;16160:12;16124:4;:31;16119:54;16105:68;;8997:7;16194:4;:14;;;:25;16184:35;8997:7;;16278:12;16246:27;;;;16241:50;16240:63;:74;16230:84;8997:7;;;16335:24;;;;:35;:46;:57;16325:67;;15553:873;-1:-1:-1;;15553:873:0:o;43514:1474::-;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;:::o;:::-;;;;;;;;;;;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;43514:1474:0;;;-1:-1:-1;43514:1474:0;:::i;:::-;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;:::-;;;;;;;;;;;;;;;;;

Swarm Source

bzzr://022ee5985152f7a0bd923f02c03eb73494e8a9174f2a5b654aa7a336c2dffd38
Block Transaction Gas Used Reward
Age Block Fee Address BC Fee Address Voting Power Jailed Incoming
Block Uncle Number Difficulty Gas Used Reward
Loading