Sponsored:   Temco - Join the Largest VC Backed ICO on the Bitcoin Network! TEMCO KYC Whitelist Starts Now!!
Contract Overview
Balance: 0 Ether
Ether Value: $0
Transactions: 27879 txns
Misc:
Address Watch: Add To Watch List
Contract Creator: 0x55bbdbf6bb8ba8c846d4e1a3c5a7ad6c5c8e5a31at txn 0x49cd27af439d4b31cb9d8ba76d336ebeb72dcc1748addebbe526049a4a009660
Token Balance:
 Latest 25 transactions from a total of 27879 transactions
(+2 PendingTxns)

TxHash Age From To Value [TxFee]
0x7824b937863ba4043081b511ea4887c1175d33197f9b614355adfc2d3d4ff017(pending)0x28626156ebae1ba2efa6082a6fccfedf5556fb40  IN  0x504b8a3f60fcf3bf2fc41e3be715e6fe68ce59ec0 Ether(Pending)
0xb02cf7017c94e9640581ddd91932d2b100283a6fefc473275d8207b1a26e475c(pending)0x28626156ebae1ba2efa6082a6fccfedf5556fb40  IN  0x504b8a3f60fcf3bf2fc41e3be715e6fe68ce59ec0 Ether(Pending)
0x0e99ec8f055c5d1124b887b7aaad995259f085a4cc234fe112a18a591af9420f8 mins ago0x28626156ebae1ba2efa6082a6fccfedf5556fb40  IN   0x504b8a3f60fcf3bf2fc41e3be715e6fe68ce59ec0 Ether0.000419157
0xfc99e17a1d1d57390f094414db989bba580e452869ca446a9675ac6c3bdef41920 mins ago0x28626156ebae1ba2efa6082a6fccfedf5556fb40  IN   0x504b8a3f60fcf3bf2fc41e3be715e6fe68ce59ec0 Ether0.000279438
0x2555363c160a93f877760a81d4b591e914185fa19c95466ca364e0987d47799b31 mins ago0x28626156ebae1ba2efa6082a6fccfedf5556fb40  IN   0x504b8a3f60fcf3bf2fc41e3be715e6fe68ce59ec0 Ether0.000232865
0x8e8536efac368d52b35bfeeae079163f9e05e222d201bcd2ca38b19b85dd80f940 mins ago0x28626156ebae1ba2efa6082a6fccfedf5556fb40  IN   0x504b8a3f60fcf3bf2fc41e3be715e6fe68ce59ec0 Ether0.000232865
0x872904b6c8238b65cb92f97e522898ebaa15549f5d241cbbafeb7d6971314ceb50 mins ago0x28626156ebae1ba2efa6082a6fccfedf5556fb40  IN   0x504b8a3f60fcf3bf2fc41e3be715e6fe68ce59ec0 Ether0.000232865
0xa9c6d2a35b48aca1f4476202f76f29945e5f8375f9f7eba41492a3ad5b7c5cc81 hr ago0x28626156ebae1ba2efa6082a6fccfedf5556fb40  IN   0x504b8a3f60fcf3bf2fc41e3be715e6fe68ce59ec0 Ether0.0002095785
0xac4f9f53e0534724691078f74e351a4dd7632a33d0e1611127cb30b3fa79d7d41 hr 10 mins ago0x28626156ebae1ba2efa6082a6fccfedf5556fb40  IN   0x504b8a3f60fcf3bf2fc41e3be715e6fe68ce59ec0 Ether0.000326011
0xc56f6c146bd304429f35ca68e984398bebf466c94809cb05cc4b45b318ced4751 hr 20 mins ago0x28626156ebae1ba2efa6082a6fccfedf5556fb40  IN   0x504b8a3f60fcf3bf2fc41e3be715e6fe68ce59ec0 Ether0.000232865
0x405850afe588806f62d53eef3c786be0c1176776a8379970c74dd93e36925d191 hr 29 mins ago0x28626156ebae1ba2efa6082a6fccfedf5556fb40  IN   0x504b8a3f60fcf3bf2fc41e3be715e6fe68ce59ec0 Ether0.000419157
0x06c12119fff92d28f5cf4c38d2e0d5ff76887fc5a7ac727842bb63a670c312d31 hr 40 mins ago0x28626156ebae1ba2efa6082a6fccfedf5556fb40  IN   0x504b8a3f60fcf3bf2fc41e3be715e6fe68ce59ec0 Ether0.000279438
0x415687cbeea27efaae65d18a4c68072ddea4474084b27892f05829c0f32fe1861 hr 50 mins ago0x28626156ebae1ba2efa6082a6fccfedf5556fb40  IN   0x504b8a3f60fcf3bf2fc41e3be715e6fe68ce59ec0 Ether0.00020585266
0xc5ae4e312766eb623d44c60d50418c4670d70ca7c82bb72e85f688f6483ba4a32 hrs ago0x28626156ebae1ba2efa6082a6fccfedf5556fb40  IN   0x504b8a3f60fcf3bf2fc41e3be715e6fe68ce59ec0 Ether0.0002049212
0x1debddfa412419bd82d08b60da84c79ed572255b9f0c75f3f269aed5a08a53812 hrs 10 mins ago0x28626156ebae1ba2efa6082a6fccfedf5556fb40  IN   0x504b8a3f60fcf3bf2fc41e3be715e6fe68ce59ec0 Ether0.0001117752
0x0fd59c11dac2fd12cbfcd6eccd27264f18a5a9a4948b2254a212b7309728d3602 hrs 20 mins ago0x28626156ebae1ba2efa6082a6fccfedf5556fb40  IN   0x504b8a3f60fcf3bf2fc41e3be715e6fe68ce59ec0 Ether0.000232865
0xbb77d5b9dd564c1102023ba7b2d1f22cbc0c74864a0f83298aa70ae3c2f53ab82 hrs 30 mins ago0x28626156ebae1ba2efa6082a6fccfedf5556fb40  IN   0x504b8a3f60fcf3bf2fc41e3be715e6fe68ce59ec0 Ether0.0002095785
0x8a404c42c26048f7016a485779fc323ecdca23678f4981c04216acc59865ac812 hrs 40 mins ago0x28626156ebae1ba2efa6082a6fccfedf5556fb40  IN   0x504b8a3f60fcf3bf2fc41e3be715e6fe68ce59ec0 Ether0.000139719
0x42885b2f5e6bb8452dd45bc8774d3105b954a87f432452fc32e11a60fc84d1c92 hrs 50 mins ago0x28626156ebae1ba2efa6082a6fccfedf5556fb40  IN   0x504b8a3f60fcf3bf2fc41e3be715e6fe68ce59ec0 Ether0.000232865
0x455e5ce254eacb68b7e56921f8437e1d7c3d1cee6ec5658ccb412cbb18c4b9693 hrs ago0x28626156ebae1ba2efa6082a6fccfedf5556fb40  IN   0x504b8a3f60fcf3bf2fc41e3be715e6fe68ce59ec0 Ether0.000326011
0x43278d5f95f7ee53aff9e71a7b5e03e7c8c40d293c9fe9524a6b8b7408bebea73 hrs 9 mins ago0x28626156ebae1ba2efa6082a6fccfedf5556fb40  IN   0x504b8a3f60fcf3bf2fc41e3be715e6fe68ce59ec0 Ether0.0002468369
0xfcab168c710399c0182f958219abfbfa75e3b362a515edf22f9be4fc320ee08d3 hrs 21 mins ago0x28626156ebae1ba2efa6082a6fccfedf5556fb40  IN   0x504b8a3f60fcf3bf2fc41e3be715e6fe68ce59ec0 Ether0.000232865
0xbf727c19a0537bb5b38b4d583d17d5e78914cd345cf87c331b73471073bb7c313 hrs 31 mins ago0x28626156ebae1ba2efa6082a6fccfedf5556fb40  IN   0x504b8a3f60fcf3bf2fc41e3be715e6fe68ce59ec0 Ether0.000232865
0x5ffb51403479e02c673abf5a63a08846c15d9930af88bca17af07b22f27f1c3a3 hrs 40 mins ago0x28626156ebae1ba2efa6082a6fccfedf5556fb40  IN   0x504b8a3f60fcf3bf2fc41e3be715e6fe68ce59ec0 Ether0.000232865
0x17f7a4f9d0b146dd29250e7cfd12c4107c3b75c3caaa22f0f782b3498bf4fe5f3 hrs 50 mins ago0x28626156ebae1ba2efa6082a6fccfedf5556fb40  IN   0x504b8a3f60fcf3bf2fc41e3be715e6fe68ce59ec0 Ether0.000232865
[ Download CSV Export  ] 
 Internal Transactions as a result of Contract Execution
View All
ParentTxHash Block Age From To Value
Warning: The Compiled Contract might be susceptible to ExpExponentCleanup (medium/high-severity), EventStructWrongData (very low-severity), NestedArrayFunctionCallDecoder (medium-severity) SolidityCompiler Bugs.

Contract Source Code Verified (Similar Match)
Note: Displaying Similar Match Verified Source Code At Contract 0xdbcd2Ae616E5886c36463eCB45a639C0Fa7583a4(Excluding Constructor Arguments if any)
Contract Name: ConversionRates
Compiler Text: v0.4.18+commit.9cf6e910
Optimization Enabled: Yes
Runs (Optimiser):  200



  Contract Source Code   Find Similiar Contracts

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

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

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

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

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

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

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

    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":"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":"token","type":"address"},{"name":"xBuy","type":"int256[]"},{"name":"yBuy","type":"int256[]"},{"name":"xSell","type":"int256[]"},{"name":"ySell","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"}],"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"}]

  Contract Creation Code Switch To Opcodes View
6060604052600a6009556000600d55341561001957600080fd5b60405160208061312b8339810160405280805160008054600160a060020a03191633600160a060020a03908116919091179091559092508291508116151561006057600080fd5b60008054600160a060020a03909216600160a060020a03199092169190911790555061309a806100916000396000f3006060604052600436106101a85763ffffffff60e060020a60003504166301a12fd381146101ad57806314673d31146101ce578063158859f7146101ed578063162656941461020c5780631a4813d7146102315780631d6a8bda146103c957806326782247146103e857806327a099d8146104175780632ba996a51461047d5780633ccdbb2814610490578063408ee7fe146104b95780635085c9f1146104d857806362674e93146104eb57806364887334146105105780636c6295b8146105e8578063721bba59146105fe57806375829def1461063957806377f50f97146106585780637acc86781461066b5780637c423f541461068a5780638036d7571461069d57806380d8b380146106bc5780639870d7fe146107d9578063a7f43acd146107f8578063a80c609e1461080b578063ac8a584a1461082d578063b8e9c22e1461084c578063bc9cbcc814610876578063bfee356914610993578063c6fd2103146109bb578063ce56c454146109e3578063cf8fee1114610a05578063d48bfca714610a29578063e4a2ac6214610a48578063e7d4fd9114610ab6578063f851a44014610af9575b600080fd5b34156101b857600080fd5b6101cc600160a060020a0360043516610b0c565b005b34156101d957600080fd5b6101cc600160a060020a0360043516610c7c565b34156101f857600080fd5b6101cc600160a060020a0360043516610cb9565b341561021757600080fd5b61021f610d29565b60405190815260200160405180910390f35b341561023c57600080fd5b6101cc60046024813581810190830135806020818102016040519081016040528093929190818152602001838360200280828437820191505050505050919080359060200190820180359060200190808060200260200160405190810160405280939291908181526020018383602002808284378201915050505050509190803590602001908201803590602001908080602002602001604051908101604052809392919081815260200183836020028082843782019150505050505091908035906020019082018035906020019080806020026020016040519081016040528093929190818152602001838360200280828437820191505050505050919080359060200190820180359060200190808060200260200160405190810160405280939291908181526020018383602002808284378201915050505050509190803590602001909190803590602001908201803590602001908080602002602001604051908101604052809392919081815260200183836020028082843750949650610d2f95505050505050565b34156103d457600080fd5b6101cc600160a060020a0360043516610e95565b34156103f357600080fd5b6103fb610f21565b604051600160a060020a03909116815260200160405180910390f35b341561042257600080fd5b61042a610f30565b60405160208082528190810183818151815260200191508051906020019060200280838360005b83811015610469578082015183820152602001610451565b505050509050019250505060405180910390f35b341561048857600080fd5b61042a610f99565b341561049b57600080fd5b6101cc600160a060020a036004358116906024359060443516610fff565b34156104c457600080fd5b6101cc600160a060020a03600435166110f6565b34156104e357600080fd5b61021f6111f2565b34156104f657600080fd5b61021f600160a060020a03600435166024356044356111f8565b341561051b57600080fd5b6101cc600460248135818101908301358060208181020160405190810160405280939291908181526020018383602002808284378201915050505050509190803590602001908201803590602001908080602002602001604051908101604052809392919081815260200183836020028082843782019150505050505091908035906020019091908035906020019082018035906020019080806020026020016040519081016040528093929190818152602001838360200280828437509496506114ec95505050505050565b34156105f357600080fd5b6101cc60043561162d565b341561060957600080fd5b61061d600160a060020a036004351661164d565b6040519115158252151560208201526040908101905180910390f35b341561064457600080fd5b6101cc600160a060020a0360043516611675565b341561066357600080fd5b6101cc611710565b341561067657600080fd5b6101cc600160a060020a03600435166117aa565b341561069557600080fd5b61042a61188c565b34156106a857600080fd5b61021f600160a060020a03600435166118f2565b34156106c757600080fd5b6101cc60048035600160a060020a031690604460248035908101908301358060208082020160405190810160405280939291908181526020018383602002808284378201915050505050509190803590602001908201803590602001908080602002602001604051908101604052809392919081815260200183836020028082843782019150505050505091908035906020019082018035906020019080806020026020016040519081016040528093929190818152602001838360200280828437820191505050505050919080359060200190820180359060200190808060200260200160405190810160405280939291908181526020018383602002808284375094965061193d95505050505050565b34156107e457600080fd5b6101cc600160a060020a0360043516611a85565b341561080357600080fd5b6103fb611b55565b341561081657600080fd5b61021f600160a060020a0360043516602435611b64565b341561083857600080fd5b6101cc600160a060020a0360043516611b81565b341561085757600080fd5b61021f600160a060020a03600435166024356044351515606435611ced565b341561088157600080fd5b6101cc60048035600160a060020a031690604460248035908101908301358060208082020160405190810160405280939291908181526020018383602002808284378201915050505050509190803590602001908201803590602001908080602002602001604051908101604052809392919081815260200183836020028082843782019150505050505091908035906020019082018035906020019080806020026020016040519081016040528093929190818152602001838360200280828437820191505050505050919080359060200190820180359060200190808060200260200160405190810160405280939291908181526020018383602002808284375094965061228395505050505050565b341561099e57600080fd5b6101cc600160a060020a03600435166024356044356064356123b2565b34156109c657600080fd5b6101cc600160a060020a0360043516602435604435606435612420565b34156109ee57600080fd5b6101cc600435600160a060020a0360243516612460565b3415610a1057600080fd5b61021f600160a060020a036004351660243515156124f3565b3415610a3457600080fd5b6101cc600160a060020a0360043516612541565b3415610a5357600080fd5b610a67600160a060020a036004351661264e565b60405193845260208401929092527fff00000000000000000000000000000000000000000000000000000000000000908116604080850191909152911660608301526080909101905180910390f35b3415610ac157600080fd5b610ad5600160a060020a0360043516612712565b60405180848152602001838152602001828152602001935050505060405180910390f35b3415610b0457600080fd5b6103fb61273a565b6000805433600160a060020a03908116911614610b2857600080fd5b600160a060020a03821660009081526003602052604090205460ff161515610b4f57600080fd5b50600160a060020a0381166000908152600360205260408120805460ff191690555b600554811015610c785781600160a060020a0316600582815481101515610b9457fe5b600091825260209091200154600160a060020a03161415610c7057600580546000198101908110610bc157fe5b60009182526020909120015460058054600160a060020a039092169183908110610be757fe5b60009182526020909120018054600160a060020a031916600160a060020a03929092169190911790556005805490610c23906000198301612fa5565b507f5611bf3e417d124f97bf2c788843ea8bb502b66079fbee02158ef30b172cb762826000604051600160a060020a039092168252151560208201526040908101905180910390a1610c78565b600101610b71565b5050565b60005433600160a060020a03908116911614610c9757600080fd5b600e8054600160a060020a031916600160a060020a0392909216919091179055565b600160a060020a03331660009081526003602052604090205460ff161515610ce057600080fd5b600160a060020a0381166000908152600b602052604090205460ff161515610d0757600080fd5b600160a060020a03166000908152600b60205260409020805461ff0019169055565b60095481565b600160a060020a03331660009081526002602052604081205460ff161515610d5657600080fd5b8651885114610d6457600080fd5b8551885114610d7257600080fd5b8451845114610d8057600080fd5b8151845114610d8e57600080fd5b5060005b8751811015610e7f57600b6000898381518110610dab57fe5b90602001906020020151600160a060020a0316815260208101919091526040016000205460ff161515610ddd57600080fd5b868181518110610de957fe5b90602001906020020151600b60008a8481518110610e0357fe5b90602001906020020151600160a060020a03168152602081019190915260400160002060030155858181518110610e3657fe5b90602001906020020151600b60008a8481518110610e5057fe5b90602001906020020151600160a060020a03168152602081019190915260400160002060040155600101610d92565b610e8b858585856114ec565b5050505050505050565b60005433600160a060020a03908116911614610eb057600080fd5b600160a060020a0381166000908152600b602052604090205460ff161515610ed757600080fd5b600160a060020a0381166000908152600660205260409020541515610efb57600080fd5b600160a060020a03166000908152600b60205260409020805461ff001916610100179055565b600154600160a060020a031681565b610f38612fce565b6004805480602002602001604051908101604052809291908181526020018280548015610f8e57602002820191906000526020600020905b8154600160a060020a03168152600190910190602001808311610f70575b505050505090505b90565b610fa1612fce565b600a805480602002602001604051908101604052809291908181526020018280548015610f8e57602002820191906000526020600020908154600160a060020a03168152600190910190602001808311610f70575050505050905090565b60005433600160a060020a0390811691161461101a57600080fd5b82600160a060020a031663a9059cbb828460006040516020015260405160e060020a63ffffffff8516028152600160a060020a0390921660048301526024820152604401602060405180830381600087803b151561107757600080fd5b6102c65a03f1151561108857600080fd5b50505060405180519050151561109d57600080fd5b7f72cb8a894ddb372ceec3d2a7648d86f17d5a15caae0e986c53109b8a9a9385e6838383604051600160a060020a03938416815260208101929092529091166040808301919091526060909101905180910390a1505050565b60005433600160a060020a0390811691161461111157600080fd5b600160a060020a03811660009081526003602052604090205460ff161561113757600080fd5b6005546032901061114757600080fd5b7f5611bf3e417d124f97bf2c788843ea8bb502b66079fbee02158ef30b172cb762816001604051600160a060020a039092168252151560208201526040908101905180910390a1600160a060020a0381166000908152600360205260409020805460ff1916600190811790915560058054909181016111c68382612fa5565b5060009182526020909120018054600160a060020a031916600160a060020a0392909216919091179055565b600d5481565b60008215156112235750600160a060020a0383166000908152600b60205260409020600501546114e5565b826001141561126657600160a060020a0384166000908152600b6020526040902060050180548390811061125357fe5b90600052602060002090015490506114e5565b82600214156112915750600160a060020a0383166000908152600b60205260409020600601546114e5565b82600314156112c157600160a060020a0384166000908152600b6020526040902060060180548390811061125357fe5b82600414156112ec5750600160a060020a0383166000908152600b60205260409020600701546114e5565b826005141561131c57600160a060020a0384166000908152600b6020526040902060070180548390811061125357fe5b82600614156113475750600160a060020a0383166000908152600b60205260409020600801546114e5565b826007141561137757600160a060020a0384166000908152600b6020526040902060080180548390811061125357fe5b82600814156113a25750600160a060020a0383166000908152600b60205260409020600901546114e5565b82600914156113d257600160a060020a0384166000908152600b6020526040902060090180548390811061125357fe5b82600a14156113fd5750600160a060020a0383166000908152600b60205260409020600a01546114e5565b82600b141561142d57600160a060020a0384166000908152600b60205260409020600a0180548390811061125357fe5b82600c14156114595750600160a060020a0383166000908152600b6020819052604090912001546114e5565b82600d141561148a57600160a060020a0384166000908152600b602081905260409091200180548390811061125357fe5b82600e14156114b55750600160a060020a0383166000908152600b60205260409020600c01546114e5565b82600f14156101a857600160a060020a0384166000908152600b60205260409020600c0180548390811061125357fe5b9392505050565b600160a060020a0333166000908152600260205260408120548190819060ff16151561151757600080fd5b855187511461152557600080fd5b865184511461153357600080fd5b63ffffffff85111561154457600080fd5b6e0100000000000000000000000000009250600091505b835182101561162457600c5484838151811061157357fe5b906020019060200201511061158757600080fd5b82830285028387848151811061159957fe5b9060200190602002015172010000000000000000000000000000000000009004028884815181106115c657fe5b90602001906020020151720100000000000000000000000000000000000090041717905080600c8584815181106115f957fe5b906020019060200201518154811061160d57fe5b60009182526020909120015560019091019061155b565b50505050505050565b60005433600160a060020a0390811691161461164857600080fd5b600955565b600160a060020a03166000908152600b602052604090205460ff808216926101009092041690565b60005433600160a060020a0390811691161461169057600080fd5b600160a060020a03811615156116a557600080fd5b6001547f3b81caf78fa51ecbc8acb482fd7012a277b428d9b80f9d156e8a54107496cc4090600160a060020a0316604051600160a060020a03909116815260200160405180910390a160018054600160a060020a031916600160a060020a0392909216919091179055565b60015433600160a060020a0390811691161461172b57600080fd5b6001546000547f65da1cfc2c2e81576ad96afb24a581f8e109b7a403b35cbd3243a1c99efdb9ed91600160a060020a039081169116604051600160a060020a039283168152911660208201526040908101905180910390a16001805460008054600160a060020a0319908116600160a060020a03841617909155169055565b60005433600160a060020a039081169116146117c557600080fd5b600160a060020a03811615156117da57600080fd5b7f3b81caf78fa51ecbc8acb482fd7012a277b428d9b80f9d156e8a54107496cc4081604051600160a060020a03909116815260200160405180910390a16000547f65da1cfc2c2e81576ad96afb24a581f8e109b7a403b35cbd3243a1c99efdb9ed908290600160a060020a0316604051600160a060020a039283168152911660208201526040908101905180910390a160008054600160a060020a031916600160a060020a0392909216919091179055565b611894612fce565b6005805480602002602001604051908101604052809291908181526020018280548015610f8e57602002820191906000526020600020908154600160a060020a03168152600190910190602001808311610f70575050505050905090565b600160a060020a0381166000908152600b6020526040812060010154600c8054839290811061191d57fe5b906000526020600020900154905061193481612749565b91505b50919050565b600160a060020a03331660009081526002602052604090205460ff16151561196457600080fd5b825184511461197257600080fd5b805182511461198057600080fd5b600a8451111561198f57600080fd5b600a8251111561199e57600080fd5b600160a060020a0385166000908152600b602052604090205460ff1615156119c557600080fd5b6040805190810160409081528582526020808301869052600160a060020a0388166000908152600b90915220600501815181908051611a08929160200190612fe0565b50602082015181600101908051611a23929160200190612fe0565b509050506040805190810160409081528382526020808301849052600160a060020a0388166000908152600b90915220600701815181908051611a6a929160200190612fe0565b50602082015181600101908051610e8b929160200190612fe0565b60005433600160a060020a03908116911614611aa057600080fd5b600160a060020a03811660009081526002602052604090205460ff1615611ac657600080fd5b60045460329010611ad657600080fd5b7f091a7a4b85135fdd7e8dbc18b12fabe5cc191ea867aa3c2e1a24a102af61d58b816001604051600160a060020a039092168252151560208201526040908101905180910390a1600160a060020a0381166000908152600260205260409020805460ff1916600190811790915560048054909181016111c68382612fa5565b600e54600160a060020a031681565b600760209081526000928352604080842090915290825290205481565b6000805433600160a060020a03908116911614611b9d57600080fd5b600160a060020a03821660009081526002602052604090205460ff161515611bc457600080fd5b50600160a060020a0381166000908152600260205260408120805460ff191690555b600454811015610c785781600160a060020a0316600482815481101515611c0957fe5b600091825260209091200154600160a060020a03161415611ce557600480546000198101908110611c3657fe5b60009182526020909120015460048054600160a060020a039092169183908110611c5c57fe5b60009182526020909120018054600160a060020a031916600160a060020a0392909216919091179055600480546000190190611c989082612fa5565b507f091a7a4b85135fdd7e8dbc18b12fabe5cc191ea867aa3c2e1a24a102af61d58b826000604051600160a060020a039092168252151560208201526040908101905180910390a1610c78565b600101611be6565b600160a060020a0384166000908152600b602052604081205481908190819081908190819081908190610100900460ff161515611d2d5760009850612273565b600160a060020a038d166000908152600660205260409020541515611d555760009850612273565b600160a060020a038d166000908152600b6020526040902060010154600c80549091908110611d8057fe5b9060005260206000209001549750611d9788612749565b60095490975087018c10611dae5760009850612273565b611db98d888e612756565b90965094508a15611ffd5750600160a060020a038c166000908152600b6020526040902060030154611ded888e600161278b565b91508160000b600a029250611e0281846127e4565b9050611e0f8d828c612830565b600160a060020a038e166000908152600b602052604090819020919b50968b01968b9550611efa91600501908051908101604052908160008201805480602002602001604051908101604052809291908181526020018280548015611e9357602002820191906000526020600020905b815481526020019060010190808311611e7f575b5050505050815260200160018201805480602002602001604051908101604052809291908181526020018280548015611eeb57602002820191906000526020600020905b815481526020019060010190808311611ed7575b5050505050815250508b61285a565b9250611f0681846127e4565b600160a060020a038e166000908152600b602052604090819020919250611fea91600901908051908101604052908160008201805480602002602001604051908101604052809291908181526020018280548015611f8357602002820191906000526020600020905b815481526020019060010190808311611f6f575b5050505050815260200160018201805480602002602001604051908101604052809291908181526020018280548015611fdb57602002820191906000526020600020905b815481526020019060010190808311611fc7575b5050505050815250508761285a565b9250611ff681846127e4565b905061222d565b50600160a060020a038c166000908152600b6020526040812060040154906120289089908f9061278b565b91508160000b600a02925061203d81846127e4565b600160a060020a038e166000908152600b6020526040908190206000198d0298890198965091925061212891600701908051908101604052908160008201805480602002602001604051908101604052809291908181526020018280548015611e935760200282019190600052602060002090815481526020019060010190808311611e7f575050505050815260200160018201805480602002602001604051908101604052809291908181526020018280548015611eeb5760200282019190600052602060002090815481526020019060010190808311611ed7575050505050815250508b61285a565b925061213481846127e4565b905061221e600b60008f600160a060020a0316600160a060020a03168152602001908152602001600020600b0160408051908101604052908160008201805480602002602001604051908101604052809291908181526020018280548015611f835760200282019190600052602060002090815481526020019060010190808311611f6f575050505050815260200160018201805480602002602001604051908101604052809291908181526020018280548015611fdb5760200282019190600052602060002090815481526020019060010190808311611fc7575050505050815250508761285a565b925061222a81846127e4565b90505b6122368d6128e2565b61223f87612900565b1061224d5760009850612273565b6122568d61291c565b612261858701612900565b1061226f5760009850612273565b8098505b5050505050505050949350505050565b600160a060020a03331660009081526002602052604090205460ff1615156122aa57600080fd5b82518451146122b857600080fd5b80518251146122c657600080fd5b600a845111156122d557600080fd5b600a825111156122e457600080fd5b600160a060020a0385166000908152600b602052604090205460ff16151561230b57600080fd5b6040805190810160409081528582526020808301869052600160a060020a0388166000908152600b9091522060090181518190805161234e929160200190612fe0565b50602082015181600101908051612369929160200190612fe0565b509050506040805190810160409081528382526020808301849052600160a060020a0388166000908152600b918290529190912001815181908051611a6a929160200190612fe0565b60005433600160a060020a039081169116146123cd57600080fd5b606060405190810160409081528482526020808301859052818301849052600160a060020a0387166000908152600690915220815181556020820151816001015560408201516002909101555050505050565b600e5433600160a060020a0390811691161461243b57600080fd5b81151561244e5761244b846118f2565b91505b61245a8484848461293a565b50505050565b60005433600160a060020a0390811691161461247b57600080fd5b600160a060020a03811682156108fc0283604051600060405180830381858888f1935050505015156124ac57600080fd5b7fec47e7ed86c86774d1a72c19f35c639911393fe7c1a34031fdbd260890da90de8282604051918252600160a060020a031660208201526040908101905180910390a15050565b6000811561251d5750600160a060020a0382166000908152600b602052604090206003015461253b565b50600160a060020a0382166000908152600b60205260409020600401545b92915050565b60005433600160a060020a0390811691161461255c57600080fd5b600160a060020a0381166000908152600b602052604090205460ff161561258257600080fd5b600160a060020a0381166000908152600b60205260409020805460ff19166001908117909155600a8054909181016125ba8382612fa5565b5060009182526020909120018054600160a060020a031916600160a060020a038316179055600d5415156125fc57600c8054906125fa9060018301612fa5565b505b600c54600160a060020a0382166000908152600b60205260409020600019909101600182810191909155600d546002909201829055600e910106600d5561264281612a6a565b61264b81612aa5565b50565b600160a060020a0381166000908152600b60205260408120548190819081908190819060ff16151561267f57600080fd5b5050600160a060020a0385166000908152600b602052604090206001810154600290910154600c8054839183916126cf9190849081106126bb57fe5b9060005260206000209001548a600161278b565b60f860020a026126fb600c868154811015156126e757fe5b9060005260206000209001548b600061278b565b60f860020a02955095509550955050509193509193565b600160a060020a03166000908152600660205260409020805460018201546002909201549092565b600054600160a060020a031681565b60e060020a81045b919050565b600160a060020a038316600090815260066020526040812054819061277c868686612b67565b90820297910295509350505050565b600160a060020a0382166000908152600b60205260408120600201548183156127b85750601281016127be565b50600481015b8581602081106127ca57fe5b1a60f860020a0260f860020a900492505b50509392505050565b60008069d3c21bcecceda10000008411156127fe57600080fd5b61270f1983121561280e57600080fd5b64174876e80083131561282057600080fd5b5050612710908101919091020490565b600080600061283e86612c55565b91506012905061285085828487612d0f565b9695505050505050565b60008060008460200151519150600090505b818110156128ba578451818151811061288157fe5b9060200190602002015184136128b257846020015181815181106128a157fe5b9060200190602002015192506128da565b60010161286c565b846020015160018303815181106128cd57fe5b9060200190602002015192505b505092915050565b600160a060020a031660009081526006602052604090206002015490565b60008082121561291557506000198102612751565b5080612751565b600160a060020a031660009081526006602052604090206001015490565b600080600061294761302b565b600160a060020a0388166000908152600660205260408120546005870695508881151561297057fe5b600160a060020a038b1660009081526007602090815260408083208a845290915281205492909105955093506129a590612da8565b91508582602001511415612a045786826060015114156129d9578382818151019052508360408301818151019052506129ff565b6129e4898888612e35565b84810160408401529250838281815101905250606082018790525b612a2e565b612a0f898888612b67565b8584526020840188905260608401899052858201604085015290935090505b612a3782612ebd565b600160a060020a039099166000908152600760209081526040808320978352969052949094209790975550505050505050565b60005b6005811015610c7857600160a060020a0382166000908152600760209081526040808320848452909152902060019081905501612a6d565b600160a060020a03811673eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee1415612aeb57600160a060020a03811660009081526008602052604090206012905561264b565b80600160a060020a031663313ce5676000604051602001526040518163ffffffff1660e060020a028152600401602060405180830381600087803b1515612b3157600080fd5b6102c65a03f11515612b4257600080fd5b5050506040518051600160a060020a0383166000908152600860205260409020555050565b6000806000806000806000612b7a61302b565b60009750600096506000955060009450899350889250600091505b6005821015612c3c57600160a060020a038b166000908152600760209081526040808320858452909152902054612bcb90612da8565b905082816020015111158015612be5575083816020015110155b15612bf1578051850194505b89816060015114612c0157612c31565b8581602001511015612c1257612c31565b80602001519550806040015197508881602001511415612c3157805196505b600190910190612b95565b871515612c47578497505b505050505050935093915050565b600080600160a060020a03831673eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee1415612c865760129150611937565b50600160a060020a03821660009081526008602052604090205480151561253b5782600160a060020a031663313ce5676000604051602001526040518163ffffffff1660e060020a028152600401602060405180830381600087803b1515612ced57600080fd5b6102c65a03f11515612cfe57600080fd5b505050604051805190509150611937565b60006b204fce5e3e25026110000000851115612d2a57600080fd5b69d3c21bcecceda1000000821115612d4157600080fd5b838310612d745760128484031115612d5857600080fd5b670de0b6b3a7640000858302858503600a0a025b049050612da0565b60128385031115612d8457600080fd5b828403600a0a670de0b6b3a764000002828602811515612d6c57fe5b949350505050565b612db061302b565b612db861302b565b67ffffffffffffffff83811660070b82526801000000000000000084041667ffffffffffffffff908116602083015270010000000000000000000000000000000084041660070b60408201527801000000000000000000000000000000000000000000000000830467ffffffffffffffff16606082015292915050565b600080612e4061302b565b83851115612e4d57600080fd5b60009250600091505b60058210156127db57600160a060020a0386166000908152600760209081526040808320858452909152902054612e8c90612da8565b905083816020015111158015612ea6575084816020015110155b15612eb2578051830192505b600190910190612e56565b600080678000000000000000835112612ed557600080fd5b677fffffffffffffff19835113612eeb57600080fd5b68010000000000000000836020015110612f0457600080fd5b678000000000000000604084015112612f1c57600080fd5b677fffffffffffffff19604084015113612f3557600080fd5b68010000000000000000836060015110612f4e57600080fd5b67ffffffffffffffff83511690506801000000000000000083602001510217680100000000000000008067ffffffffffffffff60408601511602021768010000000000000000808060608601510202021792915050565b815481835581811511612fc957600083815260209020612fc9918101908301613054565b505050565b60206040519081016040526000815290565b82805482825590600052602060002090810192821561301b579160200282015b8281111561301b578251825591602001919060010190613000565b50613027929150613054565b5090565b608060405190810160405280600081526020016000815260200160008152602001600081525090565b610f9691905b80821115613027576000815560010161305a5600a165627a7a723058200ef3073f487bcdca36f37ac65d9b555ce0cd9a3d31ce3723d09d77bd9f8a4222002900000000000000000000000060d8a82ed7efa7f27656cb34549fcd797a812235

   Swarm Source:
bzzr://0ef3073f487bcdca36f37ac65d9b555ce0cd9a3d31ce3723d09d77bd9f8a4222

 

View All
Block Age transaction Difficulty GasUsed Reward
View All
Block Age UncleNumber Difficulty GasUsed Reward
Make sure to use the "Vote Down" button for any spammy posts, and the "Vote Up" for interesting conversations.