ETH Price: $1,638.41 (+2.37%)
Gas: 18 Gwei
 

Overview

ETH Balance

0 ETH

Eth Value

$0.00

Sponsored

Transaction Hash
Method
Block
From
To
Value
Set Admin127357092021-06-30 13:48:30820 days 1 hr ago1625060910IN
Lido: Stable Swap Oracle
0 ETH0.0004237615
Submit State123169292021-04-26 16:00:30884 days 23 hrs ago1619452830IN
Lido: Stable Swap Oracle
0 ETH0.086807650
0x60806040123166682021-04-26 15:05:01885 days 14 mins ago1619449501IN
 Create: StableSwapStateOracle
0 ETH0.1471314775

View more zero value Internal Transactions in Advanced View mode

Advanced mode:
Loading...
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
StableSwapStateOracle

Compiler Version
v0.6.12+commit.27d51765

Optimization Enabled:
Yes with 200 runs

Other Settings:
default evmVersion, MIT license

Contract Source Code (Solidity)

/**
 *Submitted for verification at Etherscan.io on 2021-04-26
*/

pragma solidity 0.6.12;

// SPDX-License-Identifier: MIT AND Apache-2.0

// License: MIT

/**
 * @dev Wrappers over Solidity's arithmetic operations with added overflow
 * checks.
 *
 * Copied from: https://github.com/OpenZeppelin/openzeppelin-contracts/blob/solc-0.6/contracts/math/SafeMath.sol
 */
library SafeMath {
    /**
     * @dev Returns the addition of two unsigned integers, reverting on
     * overflow.
     *
     * Counterpart to Solidity's `+` operator.
     *
     * Requirements:
     *
     * - Addition cannot overflow.
     */
    function add(uint256 a, uint256 b) internal pure returns (uint256) {
        uint256 c = a + b;
        require(c >= a, "SafeMath: addition overflow");
        return c;
    }

    /**
     * @dev Returns the subtraction of two unsigned integers, reverting on
     * overflow (when the result is negative).
     *
     * Counterpart to Solidity's `-` operator.
     *
     * Requirements:
     *
     * - Subtraction cannot overflow.
     */
    function sub(uint256 a, uint256 b) internal pure returns (uint256) {
        require(b <= a, "SafeMath: subtraction overflow");
        return a - b;
    }

    /**
     * @dev Returns the multiplication of two unsigned integers, reverting on
     * overflow.
     *
     * Counterpart to Solidity's `*` operator.
     *
     * Requirements:
     *
     * - Multiplication cannot overflow.
     */
    function mul(uint256 a, uint256 b) internal pure returns (uint256) {
        if (a == 0) return 0;
        uint256 c = a * b;
        require(c / a == b, "SafeMath: multiplication overflow");
        return c;
    }

    /**
     * @dev Returns the integer division of two unsigned integers, reverting on
     * division by zero. The result is rounded towards zero.
     *
     * Counterpart to Solidity's `/` operator. Note: this function uses a
     * `revert` opcode (which leaves remaining gas untouched) while Solidity
     * uses an invalid opcode to revert (consuming all remaining gas).
     *
     * Requirements:
     *
     * - The divisor cannot be zero.
     */
    function div(uint256 a, uint256 b) internal pure returns (uint256) {
        require(b > 0, "SafeMath: division by zero");
        return a / b;
    }
}


// License: Apache-2.0

/*
* @author Hamdi Allam [email protected]
* Please reach out with any questions or concerns
*/

library RLPReader {
    uint8 constant STRING_SHORT_START = 0x80;
    uint8 constant STRING_LONG_START  = 0xb8;
    uint8 constant LIST_SHORT_START   = 0xc0;
    uint8 constant LIST_LONG_START    = 0xf8;
    uint8 constant WORD_SIZE = 32;

    struct RLPItem {
        uint len;
        uint memPtr;
    }

    struct Iterator {
        RLPItem item;   // Item that's being iterated over.
        uint nextPtr;   // Position of the next item in the list.
    }

    /*
    * @dev Returns the next element in the iteration. Reverts if it has not next element.
    * @param self The iterator.
    * @return The next element in the iteration.
    */
    function next(Iterator memory self) internal pure returns (RLPItem memory) {
        require(hasNext(self));

        uint ptr = self.nextPtr;
        uint itemLength = _itemLength(ptr);
        self.nextPtr = ptr + itemLength;

        return RLPItem(itemLength, ptr);
    }

    /*
    * @dev Returns true if the iteration has more elements.
    * @param self The iterator.
    * @return true if the iteration has more elements.
    */
    function hasNext(Iterator memory self) internal pure returns (bool) {
        RLPItem memory item = self.item;
        return self.nextPtr < item.memPtr + item.len;
    }

    /*
    * @param item RLP encoded bytes
    */
    function toRlpItem(bytes memory item) internal pure returns (RLPItem memory) {
        uint memPtr;
        assembly {
            memPtr := add(item, 0x20)
        }

        return RLPItem(item.length, memPtr);
    }

    /*
    * @dev Create an iterator. Reverts if item is not a list.
    * @param self The RLP item.
    * @return An 'Iterator' over the item.
    */
    function iterator(RLPItem memory self) internal pure returns (Iterator memory) {
        require(isList(self));

        uint ptr = self.memPtr + _payloadOffset(self.memPtr);
        return Iterator(self, ptr);
    }

    /*
    * @param the RLP item.
    */
    function rlpLen(RLPItem memory item) internal pure returns (uint) {
        return item.len;
    }

    /*
     * @param the RLP item.
     * @return (memPtr, len) pair: location of the item's payload in memory.
     */
    function payloadLocation(RLPItem memory item) internal pure returns (uint, uint) {
        uint offset = _payloadOffset(item.memPtr);
        uint memPtr = item.memPtr + offset;
        uint len = item.len - offset; // data length
        return (memPtr, len);
    }

    /*
    * @param the RLP item.
    */
    function payloadLen(RLPItem memory item) internal pure returns (uint) {
        (, uint len) = payloadLocation(item);
        return len;
    }

    /*
    * @param the RLP item containing the encoded list.
    */
    function toList(RLPItem memory item) internal pure returns (RLPItem[] memory) {
        require(isList(item));

        uint items = numItems(item);
        RLPItem[] memory result = new RLPItem[](items);

        uint memPtr = item.memPtr + _payloadOffset(item.memPtr);
        uint dataLen;
        for (uint i = 0; i < items; i++) {
            dataLen = _itemLength(memPtr);
            result[i] = RLPItem(dataLen, memPtr);
            memPtr = memPtr + dataLen;
        }

        return result;
    }

    // @return indicator whether encoded payload is a list. negate this function call for isData.
    function isList(RLPItem memory item) internal pure returns (bool) {
        if (item.len == 0) return false;

        uint8 byte0;
        uint memPtr = item.memPtr;
        assembly {
            byte0 := byte(0, mload(memPtr))
        }

        if (byte0 < LIST_SHORT_START)
            return false;
        return true;
    }

    /*
     * @dev A cheaper version of keccak256(toRlpBytes(item)) that avoids copying memory.
     * @return keccak256 hash of RLP encoded bytes.
     */
    function rlpBytesKeccak256(RLPItem memory item) internal pure returns (bytes32) {
        uint256 ptr = item.memPtr;
        uint256 len = item.len;
        bytes32 result;
        assembly {
            result := keccak256(ptr, len)
        }
        return result;
    }

    /*
     * @dev A cheaper version of keccak256(toBytes(item)) that avoids copying memory.
     * @return keccak256 hash of the item payload.
     */
    function payloadKeccak256(RLPItem memory item) internal pure returns (bytes32) {
        (uint memPtr, uint len) = payloadLocation(item);
        bytes32 result;
        assembly {
            result := keccak256(memPtr, len)
        }
        return result;
    }

    /** RLPItem conversions into data types **/

    // @returns raw rlp encoding in bytes
    function toRlpBytes(RLPItem memory item) internal pure returns (bytes memory) {
        bytes memory result = new bytes(item.len);
        if (result.length == 0) return result;

        uint ptr;
        assembly {
            ptr := add(0x20, result)
        }

        copy(item.memPtr, ptr, item.len);
        return result;
    }

    // any non-zero byte except "0x80" is considered true
    function toBoolean(RLPItem memory item) internal pure returns (bool) {
        require(item.len == 1);
        uint result;
        uint memPtr = item.memPtr;
        assembly {
            result := byte(0, mload(memPtr))
        }

        // SEE Github Issue #5.
        // Summary: Most commonly used RLP libraries (i.e Geth) will encode
        // "0" as "0x80" instead of as "0". We handle this edge case explicitly
        // here.
        if (result == 0 || result == STRING_SHORT_START) {
            return false;
        } else {
            return true;
        }
    }

    function toAddress(RLPItem memory item) internal pure returns (address) {
        // 1 byte for the length prefix
        require(item.len == 21);

        return address(toUint(item));
    }

    function toUint(RLPItem memory item) internal pure returns (uint) {
        require(item.len > 0 && item.len <= 33);

        (uint memPtr, uint len) = payloadLocation(item);

        uint result;
        assembly {
            result := mload(memPtr)

            // shfit to the correct location if neccesary
            if lt(len, 32) {
                result := div(result, exp(256, sub(32, len)))
            }
        }

        return result;
    }

    // enforces 32 byte length
    function toUintStrict(RLPItem memory item) internal pure returns (uint) {
        // one byte prefix
        require(item.len == 33);

        uint result;
        uint memPtr = item.memPtr + 1;
        assembly {
            result := mload(memPtr)
        }

        return result;
    }

    function toBytes(RLPItem memory item) internal pure returns (bytes memory) {
        require(item.len > 0);

        (uint memPtr, uint len) = payloadLocation(item);
        bytes memory result = new bytes(len);

        uint destPtr;
        assembly {
            destPtr := add(0x20, result)
        }

        copy(memPtr, destPtr, len);
        return result;
    }

    /*
    * Private Helpers
    */

    // @return number of payload items inside an encoded list.
    function numItems(RLPItem memory item) private pure returns (uint) {
        if (item.len == 0) return 0;

        uint count = 0;
        uint currPtr = item.memPtr + _payloadOffset(item.memPtr);
        uint endPtr = item.memPtr + item.len;
        while (currPtr < endPtr) {
           currPtr = currPtr + _itemLength(currPtr); // skip over an item
           count++;
        }

        return count;
    }

    // @return entire rlp item byte length
    function _itemLength(uint memPtr) private pure returns (uint) {
        uint itemLen;
        uint byte0;
        assembly {
            byte0 := byte(0, mload(memPtr))
        }

        if (byte0 < STRING_SHORT_START)
            itemLen = 1;

        else if (byte0 < STRING_LONG_START)
            itemLen = byte0 - STRING_SHORT_START + 1;

        else if (byte0 < LIST_SHORT_START) {
            assembly {
                let byteLen := sub(byte0, 0xb7) // # of bytes the actual length is
                memPtr := add(memPtr, 1) // skip over the first byte

                /* 32 byte word size */
                let dataLen := div(mload(memPtr), exp(256, sub(32, byteLen))) // right shifting to get the len
                itemLen := add(dataLen, add(byteLen, 1))
            }
        }

        else if (byte0 < LIST_LONG_START) {
            itemLen = byte0 - LIST_SHORT_START + 1;
        }

        else {
            assembly {
                let byteLen := sub(byte0, 0xf7)
                memPtr := add(memPtr, 1)

                let dataLen := div(mload(memPtr), exp(256, sub(32, byteLen))) // right shifting to the correct length
                itemLen := add(dataLen, add(byteLen, 1))
            }
        }

        return itemLen;
    }

    // @return number of bytes until the data
    function _payloadOffset(uint memPtr) private pure returns (uint) {
        uint byte0;
        assembly {
            byte0 := byte(0, mload(memPtr))
        }

        if (byte0 < STRING_SHORT_START)
            return 0;
        else if (byte0 < STRING_LONG_START || (byte0 >= LIST_SHORT_START && byte0 < LIST_LONG_START))
            return 1;
        else if (byte0 < LIST_SHORT_START)  // being explicit
            return byte0 - (STRING_LONG_START - 1) + 1;
        else
            return byte0 - (LIST_LONG_START - 1) + 1;
    }

    /*
    * @param src Pointer to source
    * @param dest Pointer to destination
    * @param len Amount of memory to copy from the source
    */
    function copy(uint src, uint dest, uint len) private pure {
        if (len == 0) return;

        // copy as many word sizes as possible
        for (; len >= WORD_SIZE; len -= WORD_SIZE) {
            assembly {
                mstore(dest, mload(src))
            }

            src += WORD_SIZE;
            dest += WORD_SIZE;
        }

        // left over bytes. Mask is used to remove unwanted bytes from the word
        uint mask = 256 ** (WORD_SIZE - len) - 1;
        assembly {
            let srcpart := and(mload(src), not(mask)) // zero out src
            let destpart := and(mload(dest), mask) // retrieve the bytes
            mstore(dest, or(destpart, srcpart))
        }
    }
}


// License: MIT

/**
 * Copied from https://github.com/lorenzb/proveth/blob/c74b20e/onchain/ProvethVerifier.sol
 * with minor performance and code style-related modifications.
 */

library MerklePatriciaProofVerifier {
    using RLPReader for RLPReader.RLPItem;
    using RLPReader for bytes;

    /// @dev Validates a Merkle-Patricia-Trie proof.
    ///      If the proof proves the inclusion of some key-value pair in the
    ///      trie, the value is returned. Otherwise, i.e. if the proof proves
    ///      the exclusion of a key from the trie, an empty byte array is
    ///      returned.
    /// @param rootHash is the Keccak-256 hash of the root node of the MPT.
    /// @param path is the key of the node whose inclusion/exclusion we are
    ///        proving.
    /// @param stack is the stack of MPT nodes (starting with the root) that
    ///        need to be traversed during verification.
    /// @return value whose inclusion is proved or an empty byte array for
    ///         a proof of exclusion
    function extractProofValue(
        bytes32 rootHash,
        bytes memory path,
        RLPReader.RLPItem[] memory stack
    ) internal pure returns (bytes memory value) {
        bytes memory mptKey = _decodeNibbles(path, 0);
        uint256 mptKeyOffset = 0;

        bytes32 nodeHashHash;
        bytes memory rlpNode;
        RLPReader.RLPItem[] memory node;

        RLPReader.RLPItem memory rlpValue;

        if (stack.length == 0) {
            // Root hash of empty Merkle-Patricia-Trie
            require(rootHash == 0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421);
            return new bytes(0);
        }

        // Traverse stack of nodes starting at root.
        for (uint256 i = 0; i < stack.length; i++) {

            // We use the fact that an rlp encoded list consists of some
            // encoding of its length plus the concatenation of its
            // *rlp-encoded* items.

            // The root node is hashed with Keccak-256 ...
            if (i == 0 && rootHash != stack[i].rlpBytesKeccak256()) {
                revert();
            }
            // ... whereas all other nodes are hashed with the MPT
            // hash function.
            if (i != 0 && nodeHashHash != _mptHashHash(stack[i])) {
                revert();
            }
            // We verified that stack[i] has the correct hash, so we
            // may safely decode it.
            node = stack[i].toList();

            if (node.length == 2) {
                // Extension or Leaf node

                bool isLeaf;
                bytes memory nodeKey;
                (isLeaf, nodeKey) = _merklePatriciaCompactDecode(node[0].toBytes());

                uint256 prefixLength = _sharedPrefixLength(mptKeyOffset, mptKey, nodeKey);
                mptKeyOffset += prefixLength;

                if (prefixLength < nodeKey.length) {
                    // Proof claims divergent extension or leaf. (Only
                    // relevant for proofs of exclusion.)
                    // An Extension/Leaf node is divergent iff it "skips" over
                    // the point at which a Branch node should have been had the
                    // excluded key been included in the trie.
                    // Example: Imagine a proof of exclusion for path [1, 4],
                    // where the current node is a Leaf node with
                    // path [1, 3, 3, 7]. For [1, 4] to be included, there
                    // should have been a Branch node at [1] with a child
                    // at 3 and a child at 4.

                    // Sanity check
                    if (i < stack.length - 1) {
                        // divergent node must come last in proof
                        revert();
                    }

                    return new bytes(0);
                }

                if (isLeaf) {
                    // Sanity check
                    if (i < stack.length - 1) {
                        // leaf node must come last in proof
                        revert();
                    }

                    if (mptKeyOffset < mptKey.length) {
                        return new bytes(0);
                    }

                    rlpValue = node[1];
                    return rlpValue.toBytes();
                } else { // extension
                    // Sanity check
                    if (i == stack.length - 1) {
                        // shouldn't be at last level
                        revert();
                    }

                    if (!node[1].isList()) {
                        // rlp(child) was at least 32 bytes. node[1] contains
                        // Keccak256(rlp(child)).
                        nodeHashHash = node[1].payloadKeccak256();
                    } else {
                        // rlp(child) was less than 32 bytes. node[1] contains
                        // rlp(child).
                        nodeHashHash = node[1].rlpBytesKeccak256();
                    }
                }
            } else if (node.length == 17) {
                // Branch node

                if (mptKeyOffset != mptKey.length) {
                    // we haven't consumed the entire path, so we need to look at a child
                    uint8 nibble = uint8(mptKey[mptKeyOffset]);
                    mptKeyOffset += 1;
                    if (nibble >= 16) {
                        // each element of the path has to be a nibble
                        revert();
                    }

                    if (_isEmptyBytesequence(node[nibble])) {
                        // Sanity
                        if (i != stack.length - 1) {
                            // leaf node should be at last level
                            revert();
                        }

                        return new bytes(0);
                    } else if (!node[nibble].isList()) {
                        nodeHashHash = node[nibble].payloadKeccak256();
                    } else {
                        nodeHashHash = node[nibble].rlpBytesKeccak256();
                    }
                } else {
                    // we have consumed the entire mptKey, so we need to look at what's contained in this node.

                    // Sanity
                    if (i != stack.length - 1) {
                        // should be at last level
                        revert();
                    }

                    return node[16].toBytes();
                }
            }
        }
    }


    /// @dev Computes the hash of the Merkle-Patricia-Trie hash of the RLP item.
    ///      Merkle-Patricia-Tries use a weird "hash function" that outputs
    ///      *variable-length* hashes: If the item is shorter than 32 bytes,
    ///      the MPT hash is the item. Otherwise, the MPT hash is the
    ///      Keccak-256 hash of the item.
    ///      The easiest way to compare variable-length byte sequences is
    ///      to compare their Keccak-256 hashes.
    /// @param item The RLP item to be hashed.
    /// @return Keccak-256(MPT-hash(item))
    function _mptHashHash(RLPReader.RLPItem memory item) private pure returns (bytes32) {
        if (item.len < 32) {
            return item.rlpBytesKeccak256();
        } else {
            return keccak256(abi.encodePacked(item.rlpBytesKeccak256()));
        }
    }

    function _isEmptyBytesequence(RLPReader.RLPItem memory item) private pure returns (bool) {
        if (item.len != 1) {
            return false;
        }
        uint8 b;
        uint256 memPtr = item.memPtr;
        assembly {
            b := byte(0, mload(memPtr))
        }
        return b == 0x80 /* empty byte string */;
    }


    function _merklePatriciaCompactDecode(bytes memory compact) private pure returns (bool isLeaf, bytes memory nibbles) {
        require(compact.length > 0);
        uint256 first_nibble = uint8(compact[0]) >> 4 & 0xF;
        uint256 skipNibbles;
        if (first_nibble == 0) {
            skipNibbles = 2;
            isLeaf = false;
        } else if (first_nibble == 1) {
            skipNibbles = 1;
            isLeaf = false;
        } else if (first_nibble == 2) {
            skipNibbles = 2;
            isLeaf = true;
        } else if (first_nibble == 3) {
            skipNibbles = 1;
            isLeaf = true;
        } else {
            // Not supposed to happen!
            revert();
        }
        return (isLeaf, _decodeNibbles(compact, skipNibbles));
    }


    function _decodeNibbles(bytes memory compact, uint256 skipNibbles) private pure returns (bytes memory nibbles) {
        require(compact.length > 0);

        uint256 length = compact.length * 2;
        require(skipNibbles <= length);
        length -= skipNibbles;

        nibbles = new bytes(length);
        uint256 nibblesLength = 0;

        for (uint256 i = skipNibbles; i < skipNibbles + length; i += 1) {
            if (i % 2 == 0) {
                nibbles[nibblesLength] = bytes1((uint8(compact[i/2]) >> 4) & 0xF);
            } else {
                nibbles[nibblesLength] = bytes1((uint8(compact[i/2]) >> 0) & 0xF);
            }
            nibblesLength += 1;
        }

        assert(nibblesLength == nibbles.length);
    }


    function _sharedPrefixLength(uint256 xsOffset, bytes memory xs, bytes memory ys) private pure returns (uint256) {
        uint256 i;
        for (i = 0; i + xsOffset < xs.length && i < ys.length; i++) {
            if (xs[i + xsOffset] != ys[i]) {
                return i;
            }
        }
        return i;
    }
}


// License: MIT

/**
 * @title A helper library for verification of Merkle Patricia account and state proofs.
 */
library Verifier {
    using RLPReader for RLPReader.RLPItem;
    using RLPReader for bytes;

    uint256 constant HEADER_STATE_ROOT_INDEX = 3;
    uint256 constant HEADER_NUMBER_INDEX = 8;
    uint256 constant HEADER_TIMESTAMP_INDEX = 11;

    struct BlockHeader {
        bytes32 hash;
        bytes32 stateRootHash;
        uint256 number;
        uint256 timestamp;
    }

    struct Account {
        bool exists;
        uint256 nonce;
        uint256 balance;
        bytes32 storageRoot;
        bytes32 codeHash;
    }

    struct SlotValue {
        bool exists;
        uint256 value;
    }


    /**
     * @notice Parses block header and verifies its presence onchain within the latest 256 blocks.
     * @param _headerRlpBytes RLP-encoded block header.
     */
    function verifyBlockHeader(bytes memory _headerRlpBytes)
        internal view returns (BlockHeader memory)
    {
        BlockHeader memory header = parseBlockHeader(_headerRlpBytes);
        // ensure that the block is actually in the blockchain
        require(header.hash == blockhash(header.number), "blockhash mismatch");
        return header;
    }


    /**
     * @notice Parses RLP-encoded block header.
     * @param _headerRlpBytes RLP-encoded block header.
     */
    function parseBlockHeader(bytes memory _headerRlpBytes)
        internal pure returns (BlockHeader memory)
    {
        BlockHeader memory result;
        RLPReader.RLPItem[] memory headerFields = _headerRlpBytes.toRlpItem().toList();

        result.stateRootHash = bytes32(headerFields[HEADER_STATE_ROOT_INDEX].toUint());
        result.number = headerFields[HEADER_NUMBER_INDEX].toUint();
        result.timestamp = headerFields[HEADER_TIMESTAMP_INDEX].toUint();
        result.hash = keccak256(_headerRlpBytes);

        return result;
    }


    /**
     * @notice Verifies Merkle Patricia proof of an account and extracts the account fields.
     *
     * @param _addressHash Keccak256 hash of the address corresponding to the account.
     * @param _stateRootHash MPT root hash of the Ethereum state trie.
     */
    function extractAccountFromProof(
        bytes32 _addressHash, // keccak256(abi.encodePacked(address))
        bytes32 _stateRootHash,
        RLPReader.RLPItem[] memory _proof
    )
        internal pure returns (Account memory)
    {
        bytes memory acctRlpBytes = MerklePatriciaProofVerifier.extractProofValue(
            _stateRootHash,
            abi.encodePacked(_addressHash),
            _proof
        );

        Account memory account;

        if (acctRlpBytes.length == 0) {
            return account;
        }

        RLPReader.RLPItem[] memory acctFields = acctRlpBytes.toRlpItem().toList();
        require(acctFields.length == 4);

        account.exists = true;
        account.nonce = acctFields[0].toUint();
        account.balance = acctFields[1].toUint();
        account.storageRoot = bytes32(acctFields[2].toUint());
        account.codeHash = bytes32(acctFields[3].toUint());

        return account;
    }


    /**
     * @notice Verifies Merkle Patricia proof of a slot and extracts the slot's value.
     *
     * @param _slotHash Keccak256 hash of the slot position.
     * @param _storageRootHash MPT root hash of the account's storage trie.
     */
    function extractSlotValueFromProof(
        bytes32 _slotHash,
        bytes32 _storageRootHash,
        RLPReader.RLPItem[] memory _proof
    )
        internal pure returns (SlotValue memory)
    {
        bytes memory valueRlpBytes = MerklePatriciaProofVerifier.extractProofValue(
            _storageRootHash,
            abi.encodePacked(_slotHash),
            _proof
        );

        SlotValue memory value;

        if (valueRlpBytes.length != 0) {
            value.exists = true;
            value.value = valueRlpBytes.toRlpItem().toUint();
        }

        return value;
    }

}


// License: MIT


interface IPriceHelper {
    function get_dy(
        int128 i,
        int128 j,
        uint256 dx,
        uint256[2] memory xp,
        uint256 A,
        uint256 fee
    ) external pure returns (uint256);
}


interface IStableSwap {
    function fee() external view returns (uint256);
    function A_precise() external view returns (uint256);
}


/**
 * @title
 *   A trustless oracle for the stETH/ETH Curve pool using Merkle Patricia
 *   proofs of Ethereum state.
 *
 * @notice
 *   The oracle currently assumes that the pool's fee and A (amplification
 *   coefficient) values don't change between the time of proof generation
 *   and submission.
 */
contract StableSwapStateOracle {
    using RLPReader for bytes;
    using RLPReader for RLPReader.RLPItem;
    using SafeMath for uint256;

    /**
     * @notice Logs the updated slot values of Curve pool and stETH contracts.
     */
    event SlotValuesUpdated(
        uint256 timestamp,
        uint256 poolEthBalance,
        uint256 poolAdminEthBalance,
        uint256 poolAdminStethBalance,
        uint256 stethPoolShares,
        uint256 stethTotalShares,
        uint256 stethBeaconBalance,
        uint256 stethBufferedEther,
        uint256 stethDepositedValidators,
        uint256 stethBeaconValidators
    );

    /**
     * @notice Logs the updated stETH and ETH pool balances and the calculated stETH/ETH price.
     */
    event PriceUpdated(
        uint256 timestamp,
        uint256 etherBalance,
        uint256 stethBalance,
        uint256 stethPrice
    );

    /**
     * @notice Logs the updated price update threshold percentage advised to offchain clients.
     */
    event PriceUpdateThresholdChanged(uint256 threshold);

    /**
     * @notice
     *   Logs the updated address having the right to change the advised price update threshold.
     */
    event AdminChanged(address admin);


    /// @dev Reporting data that is more fresh than this number of blocks ago is prohibited
    uint256 constant public MIN_BLOCK_DELAY = 15;

    // Constants for offchain proof generation

    address constant public POOL_ADDRESS = 0xDC24316b9AE028F1497c275EB9192a3Ea0f67022;
    address constant public STETH_ADDRESS = 0xae7ab96520DE3A18E5e111B5EaAb095312D7fE84;

    /// @dev keccak256(abi.encodePacked(uint256(1)))
    bytes32 constant public POOL_ADMIN_BALANCES_0_POS = 0xb10e2d527612073b26eecdfd717e6a320cf44b4afac2b0732d9fcbe2b7fa0cf6;

    /// @dev bytes32(uint256(POOL_ADMIN_BALANCES_0_POS) + 1)
    bytes32 constant public POOL_ADMIN_BALANCES_1_POS = 0xb10e2d527612073b26eecdfd717e6a320cf44b4afac2b0732d9fcbe2b7fa0cf7;

    /// @dev keccak256(uint256(0xdc24316b9ae028f1497c275eb9192a3ea0f67022) . uint256(0))
    bytes32 constant public STETH_POOL_SHARES_POS = 0xae68078d7ee25b2b7bcb7d4b9fe9acf61f251fe08ff637df07889375d8385158;

    /// @dev keccak256("lido.StETH.totalShares")
    bytes32 constant public STETH_TOTAL_SHARES_POS = 0xe3b4b636e601189b5f4c6742edf2538ac12bb61ed03e6da26949d69838fa447e;

    /// @dev keccak256("lido.Lido.beaconBalance")
    bytes32 constant public STETH_BEACON_BALANCE_POS = 0xa66d35f054e68143c18f32c990ed5cb972bb68a68f500cd2dd3a16bbf3686483;

    /// @dev keccak256("lido.Lido.bufferedEther")
    bytes32 constant public STETH_BUFFERED_ETHER_POS = 0xed310af23f61f96daefbcd140b306c0bdbf8c178398299741687b90e794772b0;

    /// @dev keccak256("lido.Lido.depositedValidators")
    bytes32 constant public STETH_DEPOSITED_VALIDATORS_POS = 0xe6e35175eb53fc006520a2a9c3e9711a7c00de6ff2c32dd31df8c5a24cac1b5c;

    /// @dev keccak256("lido.Lido.beaconValidators")
    bytes32 constant public STETH_BEACON_VALIDATORS_POS = 0x9f70001d82b6ef54e9d3725b46581c3eb9ee3aa02b941b6aa54d678a9ca35b10;

    // Constants for onchain proof verification

    /// @dev keccak256(abi.encodePacked(POOL_ADDRESS))
    bytes32 constant POOL_ADDRESS_HASH = 0xc70f76036d72b7bb865881e931082ea61bb4f13ec9faeb17f0591b18b6fafbd7;

    /// @dev keccak256(abi.encodePacked(STETH_ADDRESS))
    bytes32 constant STETH_ADDRESS_HASH = 0x6c958a912fe86c83262fbd4973f6bd042cef76551aaf679968f98665979c35e7;

    /// @dev keccak256(abi.encodePacked(POOL_ADMIN_BALANCES_0_POS))
    bytes32 constant POOL_ADMIN_BALANCES_0_HASH = 0xb5d9d894133a730aa651ef62d26b0ffa846233c74177a591a4a896adfda97d22;

    /// @dev keccak256(abi.encodePacked(POOL_ADMIN_BALANCES_1_POS)
    bytes32 constant POOL_ADMIN_BALANCES_1_HASH = 0xea7809e925a8989e20c901c4c1da82f0ba29b26797760d445a0ce4cf3c6fbd31;

    /// @dev keccak256(abi.encodePacked(STETH_POOL_SHARES_POS)
    bytes32 constant STETH_POOL_SHARES_HASH = 0xe841c8fb2710e169d6b63e1130fb8013d57558ced93619655add7aef8c60d4dc;

    /// @dev keccak256(abi.encodePacked(STETH_TOTAL_SHARES_POS)
    bytes32 constant STETH_TOTAL_SHARES_HASH = 0x4068b5716d4c00685289292c9cdc7e059e67159cd101476377efe51ba7ab8e9f;

    /// @dev keccak256(abi.encodePacked(STETH_BEACON_BALANCE_POS)
    bytes32 constant STETH_BEACON_BALANCE_HASH = 0xa6965d4729b36ed8b238f6ba55294196843f8be2850c5f63b6fb6d29181b50f8;

    /// @dev keccak256(abi.encodePacked(STETH_BUFFERED_ETHER_POS)
    bytes32 constant STETH_BUFFERED_ETHER_HASH = 0xa39079072910ef75f32ddc4f40104882abfc19580cc249c694e12b6de868ee1d;

    /// @dev keccak256(abi.encodePacked(STETH_DEPOSITED_VALIDATORS_POS)
    bytes32 constant STETH_DEPOSITED_VALIDATORS_HASH = 0x17216d3ffd8719eeee6d8052f7c1e6269bd92d2390d3e3fc4cde1f026e427fb3;

    /// @dev keccak256(abi.encodePacked(STETH_BEACON_VALIDATORS_POS)
    bytes32 constant STETH_BEACON_VALIDATORS_HASH = 0x6fd60d3960d8a32cbc1a708d6bf41bbce8152e61e72b2236d5e1ecede9c4cc72;

    uint256 constant internal STETH_DEPOSIT_SIZE = 32 ether;

    /**
     * @dev A helper contract for calculating stETH/ETH price from its stETH and ETH balances.
     */
    IPriceHelper internal helper;

    /**
     * @notice The admin has the right to set the suggested price update threshold (see below).
     */
    address public admin;

    /**
     * @notice
     *   The price update threshold percentage advised to oracle clients.
     *   Expressed in basis points: 10000 BP equal to 100%, 100 BP to 1%.
     *
     * @dev
     *   If the current price in the pool differs less than this, the clients are advised to
     *   skip updating the oracle. However, this threshold is not enforced, so clients are
     *   free to update the oracle with any valid price.
     */
    uint256 public priceUpdateThreshold;

    /**
     * @notice The timestamp of the proven pool state/price.
     */
    uint256 public timestamp;

    /**
     * @notice The proven ETH balance of the pool.
     */
    uint256 public etherBalance;

    /**
     * @notice The proven stETH balance of the pool.
     */
    uint256 public stethBalance;

    /**
     * @notice The proven stETH/ETH price in the pool.
     */
    uint256 public stethPrice;


    /**
     * @param _helper Address of the deployed instance of the StableSwapPriceHelper.vy contract.
     * @param _admin The address that has the right to set the suggested price update threshold.
     * @param _priceUpdateThreshold The initial value of the suggested price update threshold.
     *        Expressed in basis points, 10000 BP corresponding to 100%.
     */
    constructor(IPriceHelper _helper, address _admin, uint256 _priceUpdateThreshold) public {
        helper = _helper;
        _setAdmin(_admin);
        _setPriceUpdateThreshold(_priceUpdateThreshold);
    }


    /**
     * @notice Passes the right to set the suggested price update threshold to a new address.
     */
    function setAdmin(address _admin) external {
        require(msg.sender == admin);
        _setAdmin(_admin);
    }


    /**
     * @notice Sets the suggested price update threshold.
     *
     * @param _priceUpdateThreshold The suggested price update threshold.
     *        Expressed in basis points, 10000 BP corresponding to 100%.
     */
    function setPriceUpdateThreshold(uint256 _priceUpdateThreshold) external {
        require(msg.sender == admin);
        _setPriceUpdateThreshold(_priceUpdateThreshold);
    }


    /**
     * @notice Retuens a set of values used by the clients for proof generation.
     */
    function getProofParams() external view returns (
        address poolAddress,
        address stethAddress,
        bytes32 poolAdminEtherBalancePos,
        bytes32 poolAdminCoinBalancePos,
        bytes32 stethPoolSharesPos,
        bytes32 stethTotalSharesPos,
        bytes32 stethBeaconBalancePos,
        bytes32 stethBufferedEtherPos,
        bytes32 stethDepositedValidatorsPos,
        bytes32 stethBeaconValidatorsPos,
        uint256 advisedPriceUpdateThreshold
    ) {
        return (
            POOL_ADDRESS,
            STETH_ADDRESS,
            POOL_ADMIN_BALANCES_0_POS,
            POOL_ADMIN_BALANCES_1_POS,
            STETH_POOL_SHARES_POS,
            STETH_TOTAL_SHARES_POS,
            STETH_BEACON_BALANCE_POS,
            STETH_BUFFERED_ETHER_POS,
            STETH_DEPOSITED_VALIDATORS_POS,
            STETH_BEACON_VALIDATORS_POS,
            priceUpdateThreshold
        );
    }


    /**
     * @return _timestamp The timestamp of the proven pool state/price.
     * @return _etherBalance The proven ETH balance of the pool.
     * @return _stethBalance The proven stETH balance of the pool.
     * @return _stethPrice The proven stETH/ETH price in the pool.
     */
    function getState() external view returns (
        uint256 _timestamp,
        uint256 _etherBalance,
        uint256 _stethBalance,
        uint256 _stethPrice
    ) {
        return (timestamp, etherBalance, stethBalance, stethPrice);
    }


    /**
     * @notice Used by the offchain clients to submit the proof.
     *
     * @dev Reverts unless:
     *   - the block the submitted data corresponds to is in the chain;
     *   - the block is at least `MIN_BLOCK_DELAY` blocks old;
     *   - all submitted proofs are valid.
     *
     * @param _blockHeaderRlpBytes RLP-encoded block header.
     *
     * @param _proofRlpBytes RLP-encoded list of Merkle Patricia proofs:
     *    1. proof of the Curve pool contract account;
     *    2. proof of the stETH contract account;
     *    3. proof of the `admin_balances[0]` slot of the Curve pool contract;
     *    4. proof of the `admin_balances[1]` slot of the Curve pool contract;
     *    5. proof of the `shares[0xDC24316b9AE028F1497c275EB9192a3Ea0f67022]` slot of stETH contract;
     *    6. proof of the `keccak256("lido.StETH.totalShares")` slot of stETH contract;
     *    7. proof of the `keccak256("lido.Lido.beaconBalance")` slot of stETH contract;
     *    8. proof of the `keccak256("lido.Lido.bufferedEther")` slot of stETH contract;
     *    9. proof of the `keccak256("lido.Lido.depositedValidators")` slot of stETH contract;
     *   10. proof of the `keccak256("lido.Lido.beaconValidators")` slot of stETH contract.
     */
    function submitState(bytes memory _blockHeaderRlpBytes, bytes memory _proofRlpBytes)
        external
    {
        Verifier.BlockHeader memory blockHeader = Verifier.verifyBlockHeader(_blockHeaderRlpBytes);

        {
            uint256 currentBlock = block.number;
            // ensure block finality
            require(
                currentBlock > blockHeader.number &&
                currentBlock - blockHeader.number >= MIN_BLOCK_DELAY,
                "block too fresh"
            );
        }

        require(blockHeader.timestamp > timestamp, "stale data");

        RLPReader.RLPItem[] memory proofs = _proofRlpBytes.toRlpItem().toList();
        require(proofs.length == 10, "total proofs");

        Verifier.Account memory accountPool = Verifier.extractAccountFromProof(
            POOL_ADDRESS_HASH,
            blockHeader.stateRootHash,
            proofs[0].toList()
        );

        require(accountPool.exists, "accountPool");

        Verifier.Account memory accountSteth = Verifier.extractAccountFromProof(
            STETH_ADDRESS_HASH,
            blockHeader.stateRootHash,
            proofs[1].toList()
        );

        require(accountSteth.exists, "accountSteth");

        Verifier.SlotValue memory slotPoolAdminBalances0 = Verifier.extractSlotValueFromProof(
            POOL_ADMIN_BALANCES_0_HASH,
            accountPool.storageRoot,
            proofs[2].toList()
        );

        require(slotPoolAdminBalances0.exists, "adminBalances0");

        Verifier.SlotValue memory slotPoolAdminBalances1 = Verifier.extractSlotValueFromProof(
            POOL_ADMIN_BALANCES_1_HASH,
            accountPool.storageRoot,
            proofs[3].toList()
        );

        require(slotPoolAdminBalances1.exists, "adminBalances1");

        Verifier.SlotValue memory slotStethPoolShares = Verifier.extractSlotValueFromProof(
            STETH_POOL_SHARES_HASH,
            accountSteth.storageRoot,
            proofs[4].toList()
        );

        require(slotStethPoolShares.exists, "poolShares");

        Verifier.SlotValue memory slotStethTotalShares = Verifier.extractSlotValueFromProof(
            STETH_TOTAL_SHARES_HASH,
            accountSteth.storageRoot,
            proofs[5].toList()
        );

        require(slotStethTotalShares.exists, "totalShares");

        Verifier.SlotValue memory slotStethBeaconBalance = Verifier.extractSlotValueFromProof(
            STETH_BEACON_BALANCE_HASH,
            accountSteth.storageRoot,
            proofs[6].toList()
        );

        require(slotStethBeaconBalance.exists, "beaconBalance");

        Verifier.SlotValue memory slotStethBufferedEther = Verifier.extractSlotValueFromProof(
            STETH_BUFFERED_ETHER_HASH,
            accountSteth.storageRoot,
            proofs[7].toList()
        );

        require(slotStethBufferedEther.exists, "bufferedEther");

        Verifier.SlotValue memory slotStethDepositedValidators = Verifier.extractSlotValueFromProof(
            STETH_DEPOSITED_VALIDATORS_HASH,
            accountSteth.storageRoot,
            proofs[8].toList()
        );

        require(slotStethDepositedValidators.exists, "depositedValidators");

        Verifier.SlotValue memory slotStethBeaconValidators = Verifier.extractSlotValueFromProof(
            STETH_BEACON_VALIDATORS_HASH,
            accountSteth.storageRoot,
            proofs[9].toList()
        );

        require(slotStethBeaconValidators.exists, "beaconValidators");

        emit SlotValuesUpdated(
            blockHeader.timestamp,
            accountPool.balance,
            slotPoolAdminBalances0.value,
            slotPoolAdminBalances1.value,
            slotStethPoolShares.value,
            slotStethTotalShares.value,
            slotStethBeaconBalance.value,
            slotStethBufferedEther.value,
            slotStethDepositedValidators.value,
            slotStethBeaconValidators.value
        );

        uint256 newEtherBalance = accountPool.balance.sub(slotPoolAdminBalances0.value);
        uint256 newStethBalance = _getStethBalanceByShares(
            slotStethPoolShares.value,
            slotStethTotalShares.value,
            slotStethBeaconBalance.value,
            slotStethBufferedEther.value,
            slotStethDepositedValidators.value,
            slotStethBeaconValidators.value
        ).sub(slotPoolAdminBalances1.value);

        uint256 newStethPrice = _calcPrice(newEtherBalance, newStethBalance);

        timestamp = blockHeader.timestamp;
        etherBalance = newEtherBalance;
        stethBalance = newStethBalance;
        stethPrice = newStethPrice;

        emit PriceUpdated(blockHeader.timestamp, newEtherBalance, newStethBalance, newStethPrice);
    }


    /**
     * @dev Given the values of stETH smart contract slots, calculates the amount of stETH owned
     *      by the Curve pool by reproducing calculations performed in the stETH contract.
     */
    function _getStethBalanceByShares(
        uint256 _shares,
        uint256 _totalShares,
        uint256 _beaconBalance,
        uint256 _bufferedEther,
        uint256 _depositedValidators,
        uint256 _beaconValidators
    )
        internal pure returns (uint256)
    {
        // https://github.com/lidofinance/lido-dao/blob/v1.0.0/contracts/0.4.24/StETH.sol#L283
        // https://github.com/lidofinance/lido-dao/blob/v1.0.0/contracts/0.4.24/Lido.sol#L719
        // https://github.com/lidofinance/lido-dao/blob/v1.0.0/contracts/0.4.24/Lido.sol#L706
        if (_totalShares == 0) {
            return 0;
        }
        uint256 transientBalance = _depositedValidators.sub(_beaconValidators).mul(STETH_DEPOSIT_SIZE);
        uint256 totalPooledEther = _bufferedEther.add(_beaconBalance).add(transientBalance);
        return _shares.mul(totalPooledEther).div(_totalShares);
    }


    /**
     * @dev Given the ETH and stETH balances of the Curve pool, calculates the corresponding
     *      stETH/ETH price by reproducing calculations performed in the pool contract.
     */
    function _calcPrice(uint256 _etherBalance, uint256 _stethBalance) internal view returns (uint256) {
        uint256 A = IStableSwap(POOL_ADDRESS).A_precise();
        uint256 fee = IStableSwap(POOL_ADDRESS).fee();
        return helper.get_dy(1, 0, 10**18, [_etherBalance, _stethBalance], A, fee);
    }


    function _setPriceUpdateThreshold(uint256 _priceUpdateThreshold) internal {
        require(_priceUpdateThreshold <= 10000);
        priceUpdateThreshold = _priceUpdateThreshold;
        emit PriceUpdateThresholdChanged(_priceUpdateThreshold);
    }


    function _setAdmin(address _admin) internal {
        require(_admin != address(0));
        require(_admin != admin);
        admin = _admin;
        emit AdminChanged(_admin);
    }
}

Contract Security Audit

Contract ABI

[{"inputs":[{"internalType":"contract IPriceHelper","name":"_helper","type":"address"},{"internalType":"address","name":"_admin","type":"address"},{"internalType":"uint256","name":"_priceUpdateThreshold","type":"uint256"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"admin","type":"address"}],"name":"AdminChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"threshold","type":"uint256"}],"name":"PriceUpdateThresholdChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"timestamp","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"etherBalance","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"stethBalance","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"stethPrice","type":"uint256"}],"name":"PriceUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"timestamp","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"poolEthBalance","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"poolAdminEthBalance","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"poolAdminStethBalance","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"stethPoolShares","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"stethTotalShares","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"stethBeaconBalance","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"stethBufferedEther","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"stethDepositedValidators","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"stethBeaconValidators","type":"uint256"}],"name":"SlotValuesUpdated","type":"event"},{"inputs":[],"name":"MIN_BLOCK_DELAY","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"POOL_ADDRESS","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"POOL_ADMIN_BALANCES_0_POS","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"POOL_ADMIN_BALANCES_1_POS","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"STETH_ADDRESS","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"STETH_BEACON_BALANCE_POS","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"STETH_BEACON_VALIDATORS_POS","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"STETH_BUFFERED_ETHER_POS","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"STETH_DEPOSITED_VALIDATORS_POS","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"STETH_POOL_SHARES_POS","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"STETH_TOTAL_SHARES_POS","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"admin","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"etherBalance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getProofParams","outputs":[{"internalType":"address","name":"poolAddress","type":"address"},{"internalType":"address","name":"stethAddress","type":"address"},{"internalType":"bytes32","name":"poolAdminEtherBalancePos","type":"bytes32"},{"internalType":"bytes32","name":"poolAdminCoinBalancePos","type":"bytes32"},{"internalType":"bytes32","name":"stethPoolSharesPos","type":"bytes32"},{"internalType":"bytes32","name":"stethTotalSharesPos","type":"bytes32"},{"internalType":"bytes32","name":"stethBeaconBalancePos","type":"bytes32"},{"internalType":"bytes32","name":"stethBufferedEtherPos","type":"bytes32"},{"internalType":"bytes32","name":"stethDepositedValidatorsPos","type":"bytes32"},{"internalType":"bytes32","name":"stethBeaconValidatorsPos","type":"bytes32"},{"internalType":"uint256","name":"advisedPriceUpdateThreshold","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getState","outputs":[{"internalType":"uint256","name":"_timestamp","type":"uint256"},{"internalType":"uint256","name":"_etherBalance","type":"uint256"},{"internalType":"uint256","name":"_stethBalance","type":"uint256"},{"internalType":"uint256","name":"_stethPrice","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"priceUpdateThreshold","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_admin","type":"address"}],"name":"setAdmin","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_priceUpdateThreshold","type":"uint256"}],"name":"setPriceUpdateThreshold","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"stethBalance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"stethPrice","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes","name":"_blockHeaderRlpBytes","type":"bytes"},{"internalType":"bytes","name":"_proofRlpBytes","type":"bytes"}],"name":"submitState","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"timestamp","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"}]

60806040523480156200001157600080fd5b506040516200228c3803806200228c833981810160405260608110156200003757600080fd5b5080516020820151604090920151600080546001600160a01b0319166001600160a01b0384161790559091906200006e8262000082565b620000798162000106565b50505062000151565b6001600160a01b0381166200009657600080fd5b6001546001600160a01b0382811691161415620000b257600080fd5b600180546001600160a01b0383166001600160a01b0319909116811790915560408051918252517f7ce7ec0b50378fb6c0186ffb5f48325f6593fcb4ca4386f21861af3129188f5c9181900360200190a150565b6127108111156200011657600080fd5b60028190556040805182815290517fcc12cb94e5dfbb0c4c3e36e95f4c0facb68fa7d4d9c7b64f6fc62f66cce7790c9181900360200190a150565b61212b80620001616000396000f3fe608060405234801561001057600080fd5b50600436106101415760003560e01c806393676829116100b8578063c2465d801161007c578063c2465d801461035f578063e4fc333114610367578063e5df87ca14610384578063ec79aabf146103ee578063f851a440146103f6578063fe94df88146103fe57610141565b80639367682914610337578063a8284f2b1461033f578063ad66e52a14610347578063b80777ea1461034f578063bda093831461035757610141565b8063327313571161010a57806332731357146102e95780633a34c83f146102f15780633ebfccfe146102f957806358f0a631146103015780635ecf410214610309578063704b6c021461031157610141565b8062451d8b1461014657806301527c601461016a578063117559e714610299578063126f5c5e146102b35780631865c57d146102bb575b600080fd5b61014e610406565b604080516001600160a01b039092168252519081900360200190f35b6102976004803603604081101561018057600080fd5b81019060208101813564010000000081111561019b57600080fd5b8201836020820111156101ad57600080fd5b803590602001918460018302840111640100000000831117156101cf57600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929594936020810193503591505064010000000081111561022257600080fd5b82018360208201111561023457600080fd5b8035906020019184600183028401116401000000008311171561025657600080fd5b91908080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525092955061041e945050505050565b005b6102a1610c43565b60408051918252519081900360200190f35b6102a1610c48565b6102c3610c4e565b604080519485526020850193909352838301919091526060830152519081900360800190f35b6102a1610c60565b6102a1610c84565b6102a1610c8a565b6102a1610cae565b6102a1610cd2565b6102976004803603602081101561032757600080fd5b50356001600160a01b0316610cf6565b6102a1610d19565b6102a1610d3d565b6102a1610d61565b6102a1610d67565b6102a1610d6d565b6102a1610d73565b6102976004803603602081101561037d57600080fd5b5035610d97565b61038c610db7565b604080516001600160a01b039c8d1681529a909b1660208b0152898b01989098526060890196909652608088019490945260a087019290925260c086015260e08501526101008401526101208301526101408201529051908190036101600190f35b6102a1610ef9565b61014e610f1d565b61014e610f2c565b73ae7ab96520de3a18e5e111b5eaab095312d7fe8481565b61042661204e565b61042f83610f44565b604081015190915043908111801561044e5750600f8260400151820310155b610491576040805162461bcd60e51b815260206004820152600f60248201526e0c4d8dec6d640e8dede40cce4cae6d608b1b604482015290519081900360640190fd5b506003548160600151116104d9576040805162461bcd60e51b815260206004820152600a6024820152697374616c65206461746160b01b604482015290519081900360640190fd5b60606104ec6104e784610fb7565b610fdc565b90508051600a14610533576040805162461bcd60e51b815260206004820152600c60248201526b746f74616c2070726f6f667360a01b604482015290519081900360640190fd5b61053b612075565b6105897fc70f76036d72b7bb865881e931082ea61bb4f13ec9faeb17f0591b18b6fafbd760001b84602001516105848560008151811061057757fe5b6020026020010151610fdc565b6110c4565b80519091506105cd576040805162461bcd60e51b815260206004820152600b60248201526a1858d8dbdd5b9d141bdbdb60aa1b604482015290519081900360640190fd5b6105d5612075565b6106117f6c958a912fe86c83262fbd4973f6bd042cef76551aaf679968f98665979c35e760001b85602001516105848660018151811061057757fe5b8051909150610656576040805162461bcd60e51b815260206004820152600c60248201526b0c2c6c6deeadce8a6e8cae8d60a31b604482015290519081900360640190fd5b61065e6120a3565b61069f7fb5d9d894133a730aa651ef62d26b0ffa846233c74177a591a4a896adfda97d2260001b846060015161069a8760028151811061057757fe5b6111aa565b80519091506106e6576040805162461bcd60e51b815260206004820152600e60248201526d061646d696e42616c616e636573360941b604482015290519081900360640190fd5b6106ee6120a3565b61072a7fea7809e925a8989e20c901c4c1da82f0ba29b26797760d445a0ce4cf3c6fbd3160001b856060015161069a8860038151811061057757fe5b8051909150610771576040805162461bcd60e51b815260206004820152600e60248201526d61646d696e42616c616e6365733160901b604482015290519081900360640190fd5b6107796120a3565b6107b57fe841c8fb2710e169d6b63e1130fb8013d57558ced93619655add7aef8c60d4dc60001b856060015161069a8960048151811061057757fe5b80519091506107f8576040805162461bcd60e51b815260206004820152600a602482015269706f6f6c53686172657360b01b604482015290519081900360640190fd5b6108006120a3565b61083c7f4068b5716d4c00685289292c9cdc7e059e67159cd101476377efe51ba7ab8e9f60001b866060015161069a8a60058151811061057757fe5b8051909150610880576040805162461bcd60e51b815260206004820152600b60248201526a746f74616c53686172657360a81b604482015290519081900360640190fd5b6108886120a3565b6108c47fa6965d4729b36ed8b238f6ba55294196843f8be2850c5f63b6fb6d29181b50f860001b876060015161069a8b60068151811061057757fe5b805190915061090a576040805162461bcd60e51b815260206004820152600d60248201526c626561636f6e42616c616e636560981b604482015290519081900360640190fd5b6109126120a3565b61094e7fa39079072910ef75f32ddc4f40104882abfc19580cc249c694e12b6de868ee1d60001b886060015161069a8c60078151811061057757fe5b8051909150610994576040805162461bcd60e51b815260206004820152600d60248201526c313ab33332b932b222ba3432b960991b604482015290519081900360640190fd5b61099c6120a3565b6109d87f17216d3ffd8719eeee6d8052f7c1e6269bd92d2390d3e3fc4cde1f026e427fb360001b896060015161069a8d60088151811061057757fe5b8051909150610a24576040805162461bcd60e51b81526020600482015260136024820152726465706f736974656456616c696461746f727360681b604482015290519081900360640190fd5b610a2c6120a3565b610a687f6fd60d3960d8a32cbc1a708d6bf41bbce8152e61e72b2236d5e1ecede9c4cc7260001b8a6060015161069a8e60098151811061057757fe5b8051909150610ab1576040805162461bcd60e51b815260206004820152601060248201526f626561636f6e56616c696461746f727360801b604482015290519081900360640190fd5b7fb6b6c016579d82594391e31e1937d6475ba7d95dad21cc2ce3596b0d9abcbad18c606001518b604001518a602001518a602001518a602001518a602001518a602001518a602001518a602001518a60200151604051808b81526020018a81526020018981526020018881526020018781526020018681526020018581526020018481526020018381526020018281526020019a505050505050505050505060405180910390a16000610b7589602001518c6040015161121390919063ffffffff16565b90506000610bad8960200151610ba78a602001518a602001518a602001518a602001518a602001518a60200151611275565b90611213565b90506000610bbb83836112e0565b90508e606001516003819055508260048190555081600581905550806006819055507fc6d3da45896ce1bca9d198309a2dbeea3c73a991748f8d88d796ffa06029de938f606001518484846040518085815260200184815260200183815260200182815260200194505050505060405180910390a15050505050505050505050505050505050565b600f81565b60055481565b60035460045460055460065490919293565b7fe6e35175eb53fc006520a2a9c3e9711a7c00de6ff2c32dd31df8c5a24cac1b5c81565b60025481565b7fb10e2d527612073b26eecdfd717e6a320cf44b4afac2b0732d9fcbe2b7fa0cf781565b7f9f70001d82b6ef54e9d3725b46581c3eb9ee3aa02b941b6aa54d678a9ca35b1081565b7fed310af23f61f96daefbcd140b306c0bdbf8c178398299741687b90e794772b081565b6001546001600160a01b03163314610d0d57600080fd5b610d16816114c9565b50565b7fb10e2d527612073b26eecdfd717e6a320cf44b4afac2b0732d9fcbe2b7fa0cf681565b7fae68078d7ee25b2b7bcb7d4b9fe9acf61f251fe08ff637df07889375d838515881565b60045481565b60035481565b60065481565b7fa66d35f054e68143c18f32c990ed5cb972bb68a68f500cd2dd3a16bbf368648381565b6001546001600160a01b03163314610dae57600080fd5b610d168161154b565b60025473dc24316b9ae028f1497c275eb9192a3ea0f670229173ae7ab96520de3a18e5e111b5eaab095312d7fe84917fb10e2d527612073b26eecdfd717e6a320cf44b4afac2b0732d9fcbe2b7fa0cf6917fb10e2d527612073b26eecdfd717e6a320cf44b4afac2b0732d9fcbe2b7fa0cf7917fae68078d7ee25b2b7bcb7d4b9fe9acf61f251fe08ff637df07889375d8385158917fe3b4b636e601189b5f4c6742edf2538ac12bb61ed03e6da26949d69838fa447e917fa66d35f054e68143c18f32c990ed5cb972bb68a68f500cd2dd3a16bbf3686483917fed310af23f61f96daefbcd140b306c0bdbf8c178398299741687b90e794772b0917fe6e35175eb53fc006520a2a9c3e9711a7c00de6ff2c32dd31df8c5a24cac1b5c917f9f70001d82b6ef54e9d3725b46581c3eb9ee3aa02b941b6aa54d678a9ca35b109190565b7fe3b4b636e601189b5f4c6742edf2538ac12bb61ed03e6da26949d69838fa447e81565b6001546001600160a01b031681565b73dc24316b9ae028f1497c275eb9192a3ea0f6702281565b610f4c61204e565b610f5461204e565b610f5d83611595565b604081015181519192504014610faf576040805162461bcd60e51b81526020600482015260126024820152710c4d8dec6d6d0c2e6d040dad2e6dac2e8c6d60731b604482015290519081900360640190fd5b90505b919050565b610fbf6120ba565b506040805180820190915281518152602082810190820152919050565b6060610fe78261160b565b610ff057600080fd5b6000610ffb83611645565b905060608167ffffffffffffffff8111801561101657600080fd5b5060405190808252806020026020018201604052801561105057816020015b61103d6120ba565b8152602001906001900390816110355790505b5090506000611062856020015161169d565b60208601510190506000805b848110156110b95761107f83611700565b91506040518060400160405280838152602001848152508482815181106110a257fe5b60209081029190910101529181019160010161106e565b509195945050505050565b6110cc612075565b60606110f884866040516020018082815260200191505060405160208183030381529060405285611799565b9050611102612075565b81516111115791506111a39050565b606061111f6104e784610fb7565b9050805160041461112f57600080fd5b60018252805161115190829060009061114457fe5b6020026020010151611b1a565b60208301528051611169908290600190811061114457fe5b60408301528051611181908290600290811061114457fe5b60608301528051611199908290600390811061114457fe5b6080830152509150505b9392505050565b6111b26120a3565b60606111de84866040516020018082815260200191505060405160208183030381529060405285611799565b90506111e86120a3565b81511561120a57600181526112046111ff83610fb7565b611b1a565b60208201525b95945050505050565b60008282111561126a576040805162461bcd60e51b815260206004820152601e60248201527f536166654d6174683a207375627472616374696f6e206f766572666c6f770000604482015290519081900360640190fd5b508082035b92915050565b600085611284575060006112d6565b60006112a36801bc16d674ec80000061129d8686611213565b90611b68565b905060006112bb826112b5888a611bc1565b90611bc1565b90506112d1886112cb8b84611b68565b90611c1b565b925050505b9695505050505050565b60008073dc24316b9ae028f1497c275eb9192a3ea0f670226001600160a01b03166376a2f0f06040518163ffffffff1660e01b815260040160206040518083038186803b15801561133057600080fd5b505afa158015611344573d6000803e3d6000fd5b505050506040513d602081101561135a57600080fd5b50516040805163ddca3f4360e01b8152905191925060009173dc24316b9ae028f1497c275eb9192a3ea0f670229163ddca3f43916004808301926020929190829003018186803b1580156113ad57600080fd5b505afa1580156113c1573d6000803e3d6000fd5b505050506040513d60208110156113d757600080fd5b505160008054604080518082018252898152602081018990528151634659f74760e11b815260016004820181815260248301879052670de0b6b3a7640000604484018190529798506001600160a01b0390951696638cb3ee8e96919591949093928a928a9290916064019085908083838b5b83811015611461578181015183820152602001611449565b50505050905001838152602001828152602001965050505050505060206040518083038186803b15801561149457600080fd5b505afa1580156114a8573d6000803e3d6000fd5b505050506040513d60208110156114be57600080fd5b505195945050505050565b6001600160a01b0381166114dc57600080fd5b6001546001600160a01b03828116911614156114f757600080fd5b600180546001600160a01b0383166001600160a01b0319909116811790915560408051918252517f7ce7ec0b50378fb6c0186ffb5f48325f6593fcb4ca4386f21861af3129188f5c9181900360200190a150565b61271081111561155a57600080fd5b60028190556040805182815290517fcc12cb94e5dfbb0c4c3e36e95f4c0facb68fa7d4d9c7b64f6fc62f66cce7790c9181900360200190a150565b61159d61204e565b6115a561204e565b60606115b36104e785610fb7565b90506115c58160038151811061114457fe5b602083015280516115dd908290600890811061114457fe5b604083015280516115f5908290600b90811061114457fe5b6060830152508251602084012081529050919050565b805160009061161c57506000610fb2565b6020820151805160001a9060c082101561163b57600092505050610fb2565b5060019392505050565b805160009061165657506000610fb2565b600080611666846020015161169d565b602085015185519181019250015b808210156116945761168582611700565b60019093019290910190611674565b50909392505050565b8051600090811a60808110156116b7576000915050610fb2565b60b88110806116d2575060c081108015906116d2575060f881105b156116e1576001915050610fb2565b60c08110156116f55760b519019050610fb2565b60f519019050610fb2565b80516000908190811a608081101561171b5760019150611792565b60b881101561173057607e1981019150611792565b60c081101561175d5760b78103600185019450806020036101000a85510460018201810193505050611792565b60f88110156117725760be1981019150611792565b60f78103600185019450806020036101000a855104600182018101935050505b5092915050565b6060806117a7846000611c82565b90506000806060806117b76120ba565b8751611806577f56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b4218a146117e957600080fd5b505060408051600081526020810190915294506111a39350505050565b60005b8851811015611b0c578015801561183b575061183789828151811061182a57fe5b6020026020010151611dc1565b8b14155b1561184557600080fd5b801580159061186f575061186b89828151811061185e57fe5b6020026020010151611dcd565b8514155b1561187957600080fd5b61188889828151811061057757fe5b92508251600214156119fb57600060606118bd6118b8866000815181106118ab57fe5b6020026020010151611e22565b611e9f565b909250905060006118cf898b84611f35565b9050808901985081518110156119315760018c51038410156118f057600080fd5b6000805b506040519080825280601f01601f19166020018201604052801561191f576020820181803683370190505b509a50505050505050505050506111a3565b821561198a5760018c510384101561194857600080fd5b8951891015611959576000806118f4565b8560018151811061196657fe5b6020026020010151945061197985611e22565b9a50505050505050505050506111a3565b60018c510384141561199b57600080fd5b6119b8866001815181106119ab57fe5b602002602001015161160b565b6119e0576119d9866001815181106119cc57fe5b6020026020010151611fa2565b97506119f3565b6119f08660018151811061182a57fe5b97505b505050611b04565b825160111415611b045786518614611ad6576000878781518110611a1b57fe5b01602001516001979097019660f81c905060108110611a3957600080fd5b611a58848260ff1681518110611a4b57fe5b6020026020010151611fba565b15611a8c5760018a51038214611a6d57600080fd5b505060408051600081526020810190915296506111a395505050505050565b611a9e848260ff16815181106119ab57fe5b611abb57611ab4848260ff16815181106119cc57fe5b9550611ad0565b611acd848260ff168151811061182a57fe5b95505b50611b04565b60018951038114611ae657600080fd5b611af6836010815181106118ab57fe5b9750505050505050506111a3565b600101611809565b505050505050509392505050565b805160009015801590611b2f57508151602110155b611b3857600080fd5b600080611b4484611fdd565b815191935091506020821015611b605760208290036101000a90045b949350505050565b600082611b775750600061126f565b82820282848281611b8457fe5b04146111a35760405162461bcd60e51b81526004018080602001828103825260218152602001806120d56021913960400191505060405180910390fd5b6000828201838110156111a3576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b6000808211611c71576040805162461bcd60e51b815260206004820152601a60248201527f536166654d6174683a206469766973696f6e206279207a65726f000000000000604482015290519081900360640190fd5b818381611c7a57fe5b049392505050565b60606000835111611c9257600080fd5b825160020280831115611ca457600080fd5b8290038067ffffffffffffffff81118015611cbe57600080fd5b506040519080825280601f01601f191660200182016040528015611ce9576020820181803683370190505b5091506000835b828501811015611dae5760028106611d54576004866002830481518110611d1357fe5b602001015160f81c60f81b60f81c60ff16901c600f1660f81b848381518110611d3857fe5b60200101906001600160f81b031916908160001a905350611da2565b6000866002830481518110611d6557fe5b602001015160f81c60f81b60f81c60ff16901c600f1660f81b848381518110611d8a57fe5b60200101906001600160f81b031916908160001a9053505b60019182019101611cf0565b5082518114611db957fe5b505092915050565b60208101519051902090565b6000602082600001511015611dec57611de582611dc1565b9050610fb2565b611df582611dc1565b60405160200180828152602001915050604051602081830303815290604052805190602001209050610fb2565b8051606090611e3057600080fd5b600080611e3c84611fdd565b9150915060608167ffffffffffffffff81118015611e5957600080fd5b506040519080825280601f01601f191660200182016040528015611e84576020820181803683370190505b50905060208101611e96848285612003565b50949350505050565b600060606000835111611eb157600080fd5b6000600484600081518110611ec257fe5b60209101015160f81c901c600f169050600081611ee55750600092506002611f1f565b8160011415611efa5750600092506001611f1f565b8160021415611f0f5750600192506002611f1f565b8160031415610141575060019250825b83611f2a8683611c82565b935093505050915091565b6000805b8351858201108015611f4b5750825181105b15611b6057828181518110611f5c57fe5b602001015160f81c60f81b6001600160f81b0319168486830181518110611f7f57fe5b01602001516001600160f81b03191614611f9a5790506111a3565b600101611f39565b6000806000611fb084611fdd565b9020949350505050565b8051600090600114611fce57506000610fb2565b50602001515160001a60801490565b6000806000611fef846020015161169d565b602085015194519481019594039392505050565b8061200d57612049565b5b6020811061202d578251825260209283019290910190601f190161200e565b8251825160208390036101000a60001901801990921691161782525b505050565b60408051608081018252600080825260208201819052918101829052606081019190915290565b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915290565b604080518082019091526000808252602082015290565b60405180604001604052806000815260200160008152509056fe536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f77a2646970667358221220095da2537f60d3d5845a4a76859503b83425e5f1d2b667b113624fbfc887af0364736f6c634300060c0033000000000000000000000000fef762dfdc87f79879aaef221a6a5d302833fe27000000000000000000000000e19fc582dd93fa876cf4061eb5456f310144f57b00000000000000000000000000000000000000000000000000000000000001f4

Deployed Bytecode

0x608060405234801561001057600080fd5b50600436106101415760003560e01c806393676829116100b8578063c2465d801161007c578063c2465d801461035f578063e4fc333114610367578063e5df87ca14610384578063ec79aabf146103ee578063f851a440146103f6578063fe94df88146103fe57610141565b80639367682914610337578063a8284f2b1461033f578063ad66e52a14610347578063b80777ea1461034f578063bda093831461035757610141565b8063327313571161010a57806332731357146102e95780633a34c83f146102f15780633ebfccfe146102f957806358f0a631146103015780635ecf410214610309578063704b6c021461031157610141565b8062451d8b1461014657806301527c601461016a578063117559e714610299578063126f5c5e146102b35780631865c57d146102bb575b600080fd5b61014e610406565b604080516001600160a01b039092168252519081900360200190f35b6102976004803603604081101561018057600080fd5b81019060208101813564010000000081111561019b57600080fd5b8201836020820111156101ad57600080fd5b803590602001918460018302840111640100000000831117156101cf57600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929594936020810193503591505064010000000081111561022257600080fd5b82018360208201111561023457600080fd5b8035906020019184600183028401116401000000008311171561025657600080fd5b91908080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525092955061041e945050505050565b005b6102a1610c43565b60408051918252519081900360200190f35b6102a1610c48565b6102c3610c4e565b604080519485526020850193909352838301919091526060830152519081900360800190f35b6102a1610c60565b6102a1610c84565b6102a1610c8a565b6102a1610cae565b6102a1610cd2565b6102976004803603602081101561032757600080fd5b50356001600160a01b0316610cf6565b6102a1610d19565b6102a1610d3d565b6102a1610d61565b6102a1610d67565b6102a1610d6d565b6102a1610d73565b6102976004803603602081101561037d57600080fd5b5035610d97565b61038c610db7565b604080516001600160a01b039c8d1681529a909b1660208b0152898b01989098526060890196909652608088019490945260a087019290925260c086015260e08501526101008401526101208301526101408201529051908190036101600190f35b6102a1610ef9565b61014e610f1d565b61014e610f2c565b73ae7ab96520de3a18e5e111b5eaab095312d7fe8481565b61042661204e565b61042f83610f44565b604081015190915043908111801561044e5750600f8260400151820310155b610491576040805162461bcd60e51b815260206004820152600f60248201526e0c4d8dec6d640e8dede40cce4cae6d608b1b604482015290519081900360640190fd5b506003548160600151116104d9576040805162461bcd60e51b815260206004820152600a6024820152697374616c65206461746160b01b604482015290519081900360640190fd5b60606104ec6104e784610fb7565b610fdc565b90508051600a14610533576040805162461bcd60e51b815260206004820152600c60248201526b746f74616c2070726f6f667360a01b604482015290519081900360640190fd5b61053b612075565b6105897fc70f76036d72b7bb865881e931082ea61bb4f13ec9faeb17f0591b18b6fafbd760001b84602001516105848560008151811061057757fe5b6020026020010151610fdc565b6110c4565b80519091506105cd576040805162461bcd60e51b815260206004820152600b60248201526a1858d8dbdd5b9d141bdbdb60aa1b604482015290519081900360640190fd5b6105d5612075565b6106117f6c958a912fe86c83262fbd4973f6bd042cef76551aaf679968f98665979c35e760001b85602001516105848660018151811061057757fe5b8051909150610656576040805162461bcd60e51b815260206004820152600c60248201526b0c2c6c6deeadce8a6e8cae8d60a31b604482015290519081900360640190fd5b61065e6120a3565b61069f7fb5d9d894133a730aa651ef62d26b0ffa846233c74177a591a4a896adfda97d2260001b846060015161069a8760028151811061057757fe5b6111aa565b80519091506106e6576040805162461bcd60e51b815260206004820152600e60248201526d061646d696e42616c616e636573360941b604482015290519081900360640190fd5b6106ee6120a3565b61072a7fea7809e925a8989e20c901c4c1da82f0ba29b26797760d445a0ce4cf3c6fbd3160001b856060015161069a8860038151811061057757fe5b8051909150610771576040805162461bcd60e51b815260206004820152600e60248201526d61646d696e42616c616e6365733160901b604482015290519081900360640190fd5b6107796120a3565b6107b57fe841c8fb2710e169d6b63e1130fb8013d57558ced93619655add7aef8c60d4dc60001b856060015161069a8960048151811061057757fe5b80519091506107f8576040805162461bcd60e51b815260206004820152600a602482015269706f6f6c53686172657360b01b604482015290519081900360640190fd5b6108006120a3565b61083c7f4068b5716d4c00685289292c9cdc7e059e67159cd101476377efe51ba7ab8e9f60001b866060015161069a8a60058151811061057757fe5b8051909150610880576040805162461bcd60e51b815260206004820152600b60248201526a746f74616c53686172657360a81b604482015290519081900360640190fd5b6108886120a3565b6108c47fa6965d4729b36ed8b238f6ba55294196843f8be2850c5f63b6fb6d29181b50f860001b876060015161069a8b60068151811061057757fe5b805190915061090a576040805162461bcd60e51b815260206004820152600d60248201526c626561636f6e42616c616e636560981b604482015290519081900360640190fd5b6109126120a3565b61094e7fa39079072910ef75f32ddc4f40104882abfc19580cc249c694e12b6de868ee1d60001b886060015161069a8c60078151811061057757fe5b8051909150610994576040805162461bcd60e51b815260206004820152600d60248201526c313ab33332b932b222ba3432b960991b604482015290519081900360640190fd5b61099c6120a3565b6109d87f17216d3ffd8719eeee6d8052f7c1e6269bd92d2390d3e3fc4cde1f026e427fb360001b896060015161069a8d60088151811061057757fe5b8051909150610a24576040805162461bcd60e51b81526020600482015260136024820152726465706f736974656456616c696461746f727360681b604482015290519081900360640190fd5b610a2c6120a3565b610a687f6fd60d3960d8a32cbc1a708d6bf41bbce8152e61e72b2236d5e1ecede9c4cc7260001b8a6060015161069a8e60098151811061057757fe5b8051909150610ab1576040805162461bcd60e51b815260206004820152601060248201526f626561636f6e56616c696461746f727360801b604482015290519081900360640190fd5b7fb6b6c016579d82594391e31e1937d6475ba7d95dad21cc2ce3596b0d9abcbad18c606001518b604001518a602001518a602001518a602001518a602001518a602001518a602001518a602001518a60200151604051808b81526020018a81526020018981526020018881526020018781526020018681526020018581526020018481526020018381526020018281526020019a505050505050505050505060405180910390a16000610b7589602001518c6040015161121390919063ffffffff16565b90506000610bad8960200151610ba78a602001518a602001518a602001518a602001518a602001518a60200151611275565b90611213565b90506000610bbb83836112e0565b90508e606001516003819055508260048190555081600581905550806006819055507fc6d3da45896ce1bca9d198309a2dbeea3c73a991748f8d88d796ffa06029de938f606001518484846040518085815260200184815260200183815260200182815260200194505050505060405180910390a15050505050505050505050505050505050565b600f81565b60055481565b60035460045460055460065490919293565b7fe6e35175eb53fc006520a2a9c3e9711a7c00de6ff2c32dd31df8c5a24cac1b5c81565b60025481565b7fb10e2d527612073b26eecdfd717e6a320cf44b4afac2b0732d9fcbe2b7fa0cf781565b7f9f70001d82b6ef54e9d3725b46581c3eb9ee3aa02b941b6aa54d678a9ca35b1081565b7fed310af23f61f96daefbcd140b306c0bdbf8c178398299741687b90e794772b081565b6001546001600160a01b03163314610d0d57600080fd5b610d16816114c9565b50565b7fb10e2d527612073b26eecdfd717e6a320cf44b4afac2b0732d9fcbe2b7fa0cf681565b7fae68078d7ee25b2b7bcb7d4b9fe9acf61f251fe08ff637df07889375d838515881565b60045481565b60035481565b60065481565b7fa66d35f054e68143c18f32c990ed5cb972bb68a68f500cd2dd3a16bbf368648381565b6001546001600160a01b03163314610dae57600080fd5b610d168161154b565b60025473dc24316b9ae028f1497c275eb9192a3ea0f670229173ae7ab96520de3a18e5e111b5eaab095312d7fe84917fb10e2d527612073b26eecdfd717e6a320cf44b4afac2b0732d9fcbe2b7fa0cf6917fb10e2d527612073b26eecdfd717e6a320cf44b4afac2b0732d9fcbe2b7fa0cf7917fae68078d7ee25b2b7bcb7d4b9fe9acf61f251fe08ff637df07889375d8385158917fe3b4b636e601189b5f4c6742edf2538ac12bb61ed03e6da26949d69838fa447e917fa66d35f054e68143c18f32c990ed5cb972bb68a68f500cd2dd3a16bbf3686483917fed310af23f61f96daefbcd140b306c0bdbf8c178398299741687b90e794772b0917fe6e35175eb53fc006520a2a9c3e9711a7c00de6ff2c32dd31df8c5a24cac1b5c917f9f70001d82b6ef54e9d3725b46581c3eb9ee3aa02b941b6aa54d678a9ca35b109190565b7fe3b4b636e601189b5f4c6742edf2538ac12bb61ed03e6da26949d69838fa447e81565b6001546001600160a01b031681565b73dc24316b9ae028f1497c275eb9192a3ea0f6702281565b610f4c61204e565b610f5461204e565b610f5d83611595565b604081015181519192504014610faf576040805162461bcd60e51b81526020600482015260126024820152710c4d8dec6d6d0c2e6d040dad2e6dac2e8c6d60731b604482015290519081900360640190fd5b90505b919050565b610fbf6120ba565b506040805180820190915281518152602082810190820152919050565b6060610fe78261160b565b610ff057600080fd5b6000610ffb83611645565b905060608167ffffffffffffffff8111801561101657600080fd5b5060405190808252806020026020018201604052801561105057816020015b61103d6120ba565b8152602001906001900390816110355790505b5090506000611062856020015161169d565b60208601510190506000805b848110156110b95761107f83611700565b91506040518060400160405280838152602001848152508482815181106110a257fe5b60209081029190910101529181019160010161106e565b509195945050505050565b6110cc612075565b60606110f884866040516020018082815260200191505060405160208183030381529060405285611799565b9050611102612075565b81516111115791506111a39050565b606061111f6104e784610fb7565b9050805160041461112f57600080fd5b60018252805161115190829060009061114457fe5b6020026020010151611b1a565b60208301528051611169908290600190811061114457fe5b60408301528051611181908290600290811061114457fe5b60608301528051611199908290600390811061114457fe5b6080830152509150505b9392505050565b6111b26120a3565b60606111de84866040516020018082815260200191505060405160208183030381529060405285611799565b90506111e86120a3565b81511561120a57600181526112046111ff83610fb7565b611b1a565b60208201525b95945050505050565b60008282111561126a576040805162461bcd60e51b815260206004820152601e60248201527f536166654d6174683a207375627472616374696f6e206f766572666c6f770000604482015290519081900360640190fd5b508082035b92915050565b600085611284575060006112d6565b60006112a36801bc16d674ec80000061129d8686611213565b90611b68565b905060006112bb826112b5888a611bc1565b90611bc1565b90506112d1886112cb8b84611b68565b90611c1b565b925050505b9695505050505050565b60008073dc24316b9ae028f1497c275eb9192a3ea0f670226001600160a01b03166376a2f0f06040518163ffffffff1660e01b815260040160206040518083038186803b15801561133057600080fd5b505afa158015611344573d6000803e3d6000fd5b505050506040513d602081101561135a57600080fd5b50516040805163ddca3f4360e01b8152905191925060009173dc24316b9ae028f1497c275eb9192a3ea0f670229163ddca3f43916004808301926020929190829003018186803b1580156113ad57600080fd5b505afa1580156113c1573d6000803e3d6000fd5b505050506040513d60208110156113d757600080fd5b505160008054604080518082018252898152602081018990528151634659f74760e11b815260016004820181815260248301879052670de0b6b3a7640000604484018190529798506001600160a01b0390951696638cb3ee8e96919591949093928a928a9290916064019085908083838b5b83811015611461578181015183820152602001611449565b50505050905001838152602001828152602001965050505050505060206040518083038186803b15801561149457600080fd5b505afa1580156114a8573d6000803e3d6000fd5b505050506040513d60208110156114be57600080fd5b505195945050505050565b6001600160a01b0381166114dc57600080fd5b6001546001600160a01b03828116911614156114f757600080fd5b600180546001600160a01b0383166001600160a01b0319909116811790915560408051918252517f7ce7ec0b50378fb6c0186ffb5f48325f6593fcb4ca4386f21861af3129188f5c9181900360200190a150565b61271081111561155a57600080fd5b60028190556040805182815290517fcc12cb94e5dfbb0c4c3e36e95f4c0facb68fa7d4d9c7b64f6fc62f66cce7790c9181900360200190a150565b61159d61204e565b6115a561204e565b60606115b36104e785610fb7565b90506115c58160038151811061114457fe5b602083015280516115dd908290600890811061114457fe5b604083015280516115f5908290600b90811061114457fe5b6060830152508251602084012081529050919050565b805160009061161c57506000610fb2565b6020820151805160001a9060c082101561163b57600092505050610fb2565b5060019392505050565b805160009061165657506000610fb2565b600080611666846020015161169d565b602085015185519181019250015b808210156116945761168582611700565b60019093019290910190611674565b50909392505050565b8051600090811a60808110156116b7576000915050610fb2565b60b88110806116d2575060c081108015906116d2575060f881105b156116e1576001915050610fb2565b60c08110156116f55760b519019050610fb2565b60f519019050610fb2565b80516000908190811a608081101561171b5760019150611792565b60b881101561173057607e1981019150611792565b60c081101561175d5760b78103600185019450806020036101000a85510460018201810193505050611792565b60f88110156117725760be1981019150611792565b60f78103600185019450806020036101000a855104600182018101935050505b5092915050565b6060806117a7846000611c82565b90506000806060806117b76120ba565b8751611806577f56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b4218a146117e957600080fd5b505060408051600081526020810190915294506111a39350505050565b60005b8851811015611b0c578015801561183b575061183789828151811061182a57fe5b6020026020010151611dc1565b8b14155b1561184557600080fd5b801580159061186f575061186b89828151811061185e57fe5b6020026020010151611dcd565b8514155b1561187957600080fd5b61188889828151811061057757fe5b92508251600214156119fb57600060606118bd6118b8866000815181106118ab57fe5b6020026020010151611e22565b611e9f565b909250905060006118cf898b84611f35565b9050808901985081518110156119315760018c51038410156118f057600080fd5b6000805b506040519080825280601f01601f19166020018201604052801561191f576020820181803683370190505b509a50505050505050505050506111a3565b821561198a5760018c510384101561194857600080fd5b8951891015611959576000806118f4565b8560018151811061196657fe5b6020026020010151945061197985611e22565b9a50505050505050505050506111a3565b60018c510384141561199b57600080fd5b6119b8866001815181106119ab57fe5b602002602001015161160b565b6119e0576119d9866001815181106119cc57fe5b6020026020010151611fa2565b97506119f3565b6119f08660018151811061182a57fe5b97505b505050611b04565b825160111415611b045786518614611ad6576000878781518110611a1b57fe5b01602001516001979097019660f81c905060108110611a3957600080fd5b611a58848260ff1681518110611a4b57fe5b6020026020010151611fba565b15611a8c5760018a51038214611a6d57600080fd5b505060408051600081526020810190915296506111a395505050505050565b611a9e848260ff16815181106119ab57fe5b611abb57611ab4848260ff16815181106119cc57fe5b9550611ad0565b611acd848260ff168151811061182a57fe5b95505b50611b04565b60018951038114611ae657600080fd5b611af6836010815181106118ab57fe5b9750505050505050506111a3565b600101611809565b505050505050509392505050565b805160009015801590611b2f57508151602110155b611b3857600080fd5b600080611b4484611fdd565b815191935091506020821015611b605760208290036101000a90045b949350505050565b600082611b775750600061126f565b82820282848281611b8457fe5b04146111a35760405162461bcd60e51b81526004018080602001828103825260218152602001806120d56021913960400191505060405180910390fd5b6000828201838110156111a3576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b6000808211611c71576040805162461bcd60e51b815260206004820152601a60248201527f536166654d6174683a206469766973696f6e206279207a65726f000000000000604482015290519081900360640190fd5b818381611c7a57fe5b049392505050565b60606000835111611c9257600080fd5b825160020280831115611ca457600080fd5b8290038067ffffffffffffffff81118015611cbe57600080fd5b506040519080825280601f01601f191660200182016040528015611ce9576020820181803683370190505b5091506000835b828501811015611dae5760028106611d54576004866002830481518110611d1357fe5b602001015160f81c60f81b60f81c60ff16901c600f1660f81b848381518110611d3857fe5b60200101906001600160f81b031916908160001a905350611da2565b6000866002830481518110611d6557fe5b602001015160f81c60f81b60f81c60ff16901c600f1660f81b848381518110611d8a57fe5b60200101906001600160f81b031916908160001a9053505b60019182019101611cf0565b5082518114611db957fe5b505092915050565b60208101519051902090565b6000602082600001511015611dec57611de582611dc1565b9050610fb2565b611df582611dc1565b60405160200180828152602001915050604051602081830303815290604052805190602001209050610fb2565b8051606090611e3057600080fd5b600080611e3c84611fdd565b9150915060608167ffffffffffffffff81118015611e5957600080fd5b506040519080825280601f01601f191660200182016040528015611e84576020820181803683370190505b50905060208101611e96848285612003565b50949350505050565b600060606000835111611eb157600080fd5b6000600484600081518110611ec257fe5b60209101015160f81c901c600f169050600081611ee55750600092506002611f1f565b8160011415611efa5750600092506001611f1f565b8160021415611f0f5750600192506002611f1f565b8160031415610141575060019250825b83611f2a8683611c82565b935093505050915091565b6000805b8351858201108015611f4b5750825181105b15611b6057828181518110611f5c57fe5b602001015160f81c60f81b6001600160f81b0319168486830181518110611f7f57fe5b01602001516001600160f81b03191614611f9a5790506111a3565b600101611f39565b6000806000611fb084611fdd565b9020949350505050565b8051600090600114611fce57506000610fb2565b50602001515160001a60801490565b6000806000611fef846020015161169d565b602085015194519481019594039392505050565b8061200d57612049565b5b6020811061202d578251825260209283019290910190601f190161200e565b8251825160208390036101000a60001901801990921691161782525b505050565b60408051608081018252600080825260208201819052918101829052606081019190915290565b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915290565b604080518082019091526000808252602082015290565b60405180604001604052806000815260200160008152509056fe536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f77a2646970667358221220095da2537f60d3d5845a4a76859503b83425e5f1d2b667b113624fbfc887af0364736f6c634300060c0033

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

000000000000000000000000fef762dfdc87f79879aaef221a6a5d302833fe27000000000000000000000000e19fc582dd93fa876cf4061eb5456f310144f57b00000000000000000000000000000000000000000000000000000000000001f4

-----Decoded View---------------
Arg [0] : _helper (address): 0xfef762DFdc87f79879aaef221a6a5D302833FE27
Arg [1] : _admin (address): 0xe19fc582dd93FA876CF4061Eb5456F310144F57b
Arg [2] : _priceUpdateThreshold (uint256): 500

-----Encoded View---------------
3 Constructor Arguments found :
Arg [0] : 000000000000000000000000fef762dfdc87f79879aaef221a6a5d302833fe27
Arg [1] : 000000000000000000000000e19fc582dd93fa876cf4061eb5456f310144f57b
Arg [2] : 00000000000000000000000000000000000000000000000000000000000001f4


Deployed Bytecode Sourcemap

27671:17424:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;29225:82;;;:::i;:::-;;;;-1:-1:-1;;;;;29225:82:0;;;;;;;;;;;;;;38135:4849;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;38135:4849:0;;;;;;;;-1:-1:-1;38135:4849:0;;-1:-1:-1;;38135:4849:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;38135:4849:0;;-1:-1:-1;38135:4849:0;;-1:-1:-1;;;;;38135:4849:0:i;:::-;;29034:44;;;:::i;:::-;;;;;;;;;;;;;;;;33840:27;;;:::i;36592:250::-;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;30484:123;;;:::i;33505:35::-;;;:::i;29559:118::-;;;:::i;30670:120::-;;;:::i;30301:117::-;;;:::i;34702:118::-;;;;;;;;;;;;;;;;-1:-1:-1;34702:118:0;-1:-1:-1;;;;;34702:118:0;;:::i;29370:::-;;;:::i;29776:114::-;;;:::i;33732:27::-;;;:::i;33629:24::-;;;:::i;33950:25::-;;;:::i;30124:117::-;;;:::i;35064:178::-;;;;;;;;;;;;;;;;-1:-1:-1;35064:178:0;;:::i;35352:937::-;;;:::i;:::-;;;;-1:-1:-1;;;;;35352:937:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;29949:115;;;:::i;33027:20::-;;;:::i;29137:81::-;;;:::i;29225:82::-;29265:42;29225:82;:::o;38135:4849::-;38254:39;;:::i;:::-;38296:48;38323:20;38296:26;:48::i;:::-;38501:18;;;;38254:90;;-1:-1:-1;38395:12:0;;38486:33;;:106;;;;;29076:2;38555:11;:18;;;38540:12;:33;:52;;38486:106;38460:183;;;;;-1:-1:-1;;;38460:183:0;;;;;;;;;;;;-1:-1:-1;;;38460:183:0;;;;;;;;;;;;;;;38135:4849;38699:9;;38675:11;:21;;;:33;38667:56;;;;;-1:-1:-1;;;38667:56:0;;;;;;;;;;;;-1:-1:-1;;;38667:56:0;;;;;;;;;;;;;;;38736:33;38772:35;:26;:14;:24;:26::i;:::-;:33;:35::i;:::-;38736:71;;38826:6;:13;38843:2;38826:19;38818:44;;;;;-1:-1:-1;;;38818:44:0;;;;;;;;;;;;-1:-1:-1;;;38818:44:0;;;;;;;;;;;;;;;38875:35;;:::i;:::-;38913:148;30943:66;38960:17;;38992:11;:25;;;39032:18;:6;39039:1;39032:9;;;;;;;;;;;;;;:16;:18::i;:::-;38913:32;:148::i;:::-;39082:18;;38875:186;;-1:-1:-1;39074:42:0;;;;;-1:-1:-1;;;39074:42:0;;;;;;;;;;;;-1:-1:-1;;;39074:42:0;;;;;;;;;;;;;;;39129:36;;:::i;:::-;39168:149;31113:66;39215:18;;39248:11;:25;;;39288:18;:6;39295:1;39288:9;;;;;;;39168:149;39338:19;;39129:188;;-1:-1:-1;39330:44:0;;;;;-1:-1:-1;;;39330:44:0;;;;;;;;;;;;-1:-1:-1;;;39330:44:0;;;;;;;;;;;;;;;39387:48;;:::i;:::-;39438:157;31303:66;39487:26;;39528:11;:23;;;39566:18;:6;39573:1;39566:9;;;;;;;:18;39438:34;:157::i;:::-;39616:29;;39387:208;;-1:-1:-1;39608:56:0;;;;;-1:-1:-1;;;39608:56:0;;;;;;;;;;;;-1:-1:-1;;;39608:56:0;;;;;;;;;;;;;;;39677:48;;:::i;:::-;39728:157;31492:66;39777:26;;39818:11;:23;;;39856:18;:6;39863:1;39856:9;;;;;;;39728:157;39906:29;;39677:208;;-1:-1:-1;39898:56:0;;;;;-1:-1:-1;;;39898:56:0;;;;;;;;;;;;-1:-1:-1;;;39898:56:0;;;;;;;;;;;;;;;39967:45;;:::i;:::-;40015:154;31673:66;40064:22;;40101:12;:24;;;40140:18;:6;40147:1;40140:9;;;;;;;40015:154;40190:26;;39967:202;;-1:-1:-1;40182:49:0;;;;;-1:-1:-1;;;40182:49:0;;;;;;;;;;;;-1:-1:-1;;;40182:49:0;;;;;;;;;;;;;;;40244:46;;:::i;:::-;40293:155;31856:66;40342:23;;40380:12;:24;;;40419:18;:6;40426:1;40419:9;;;;;;;40293:155;40469:27;;40244:204;;-1:-1:-1;40461:51:0;;;;;-1:-1:-1;;;40461:51:0;;;;;;;;;;;;-1:-1:-1;;;40461:51:0;;;;;;;;;;;;;;;40525:48;;:::i;:::-;40576:157;32043:66;40625:25;;40665:12;:24;;;40704:18;:6;40711:1;40704:9;;;;;;;40576:157;40754:29;;40525:208;;-1:-1:-1;40746:55:0;;;;;-1:-1:-1;;;40746:55:0;;;;;;;;;;;;-1:-1:-1;;;40746:55:0;;;;;;;;;;;;;;;40814:48;;:::i;:::-;40865:157;32230:66;40914:25;;40954:12;:24;;;40993:18;:6;41000:1;40993:9;;;;;;;40865:157;41043:29;;40814:208;;-1:-1:-1;41035:55:0;;;;;-1:-1:-1;;;41035:55:0;;;;;;;;;;;;-1:-1:-1;;;41035:55:0;;;;;;;;;;;;;;;41103:54;;:::i;:::-;41160:163;32429:66;41209:31;;41255:12;:24;;;41294:18;:6;41301:1;41294:9;;;;;;;41160:163;41344:35;;41103:220;;-1:-1:-1;41336:67:0;;;;;-1:-1:-1;;;41336:67:0;;;;;;;;;;;;-1:-1:-1;;;41336:67:0;;;;;;;;;;;;;;;41416:51;;:::i;:::-;41470:160;32622:66;41519:28;;41562:12;:24;;;41601:18;:6;41608:1;41601:9;;;;;;;41470:160;41651:32;;41416:214;;-1:-1:-1;41643:61:0;;;;;-1:-1:-1;;;41643:61:0;;;;;;;;;;;;-1:-1:-1;;;41643:61:0;;;;;;;;;;;;;;;41722:446;41754:11;:21;;;41790:11;:19;;;41824:22;:28;;;41867:22;:28;;;41910:19;:25;;;41950:20;:26;;;41991:22;:28;;;42034:22;:28;;;42077;:34;;;42126:25;:31;;;41722:446;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;42181:23;42207:53;42231:22;:28;;;42207:11;:19;;;:23;;:53;;;;:::i;:::-;42181:79;;42271:23;42297:331;42599:22;:28;;;42297:297;42336:19;:25;;;42376:20;:26;;;42417:22;:28;;;42460:22;:28;;;42503;:34;;;42552:25;:31;;;42297:24;:297::i;:::-;:301;;:331::i;:::-;42271:357;;42641:21;42665:44;42676:15;42693;42665:10;:44::i;:::-;42641:68;;42734:11;:21;;;42722:9;:33;;;;42781:15;42766:12;:30;;;;42822:15;42807:12;:30;;;;42861:13;42848:10;:26;;;;42892:84;42905:11;:21;;;42928:15;42945;42962:13;42892:84;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;38135:4849;;;;;;;;;;;;;;;;;:::o;29034:44::-;29076:2;29034:44;:::o;33840:27::-;;;;:::o;36592:250::-;36784:9;;36795:12;;36809;;36823:10;;36592:250;;;;:::o;30484:123::-;30541:66;30484:123;:::o;33505:35::-;;;;:::o;29559:118::-;29611:66;29559:118;:::o;30670:120::-;30724:66;30670:120;:::o;30301:117::-;30352:66;30301:117;:::o;34702:118::-;34778:5;;-1:-1:-1;;;;;34778:5:0;34764:10;:19;34756:28;;;;;;34795:17;34805:6;34795:9;:17::i;:::-;34702:118;:::o;29370:::-;29422:66;29370:118;:::o;29776:114::-;29824:66;29776:114;:::o;33732:27::-;;;;:::o;33629:24::-;;;;:::o;33950:25::-;;;;:::o;30124:117::-;30175:66;30124:117;:::o;35064:178::-;35170:5;;-1:-1:-1;;;;;35170:5:0;35156:10;:19;35148:28;;;;;;35187:47;35212:21;35187:24;:47::i;35352:937::-;36250:20;;29176:42;;29265;;29422:66;;29611;;29824;;29998;;30175;;30352;;30541;;30724;;36250:20;35352:937::o;29949:115::-;29998:66;29949:115;:::o;33027:20::-;;;-1:-1:-1;;;;;33027:20:0;;:::o;29137:81::-;29176:42;29137:81;:::o;23757:363::-;23846:18;;:::i;:::-;23882:25;;:::i;:::-;23910:33;23927:15;23910:16;:33::i;:::-;24051:13;;;;24026:11;;23882:61;;-1:-1:-1;24041:24:0;24026:39;24018:70;;;;;-1:-1:-1;;;24018:70:0;;;;;;;;;;;;-1:-1:-1;;;24018:70:0;;;;;;;;;;;;;;;24106:6;-1:-1:-1;23757:363:0;;;;:::o;3812:225::-;3873:14;;:::i;:::-;-1:-1:-1;4001:28:0;;;;;;;;;4009:11;;4001:28;;3966:4;3956:15;;;4001:28;;;;3812:225;;;:::o;5255:522::-;5315:16;5352:12;5359:4;5352:6;:12::i;:::-;5344:21;;;;;;5378:10;5391:14;5400:4;5391:8;:14::i;:::-;5378:27;;5416:23;5456:5;5442:20;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;5416:46;;5475:11;5503:27;5518:4;:11;;;5503:14;:27::i;:::-;5489:11;;;;:41;;-1:-1:-1;5541:12:0;;5564:180;5585:5;5581:1;:9;5564:180;;;5622:19;5634:6;5622:11;:19::i;:::-;5612:29;;5668:24;;;;;;;;5676:7;5668:24;;;;5685:6;5668:24;;;5656:6;5663:1;5656:9;;;;;;;;;;;;;;;;;:36;5716:16;;;;5592:3;;5564:180;;;-1:-1:-1;5763:6:0;;5255:522;-1:-1:-1;;;;;5255:522:0:o;25102:971::-;25322:14;;:::i;:::-;25354:25;25382:151;25442:14;25488:12;25471:30;;;;;;;;;;;;;;;;;;;;;;;;;25516:6;25382:45;:151::i;:::-;25354:179;;25546:22;;:::i;:::-;25585:19;;25581:71;;25633:7;-1:-1:-1;25626:14:0;;-1:-1:-1;25626:14:0;25581:71;25664:37;25704:33;:24;:12;:22;:24::i;:33::-;25664:73;;25756:10;:17;25777:1;25756:22;25748:31;;;;;;25809:4;25792:21;;25840:13;;:22;;:10;;25792:14;;25840:13;;;;;;;;;;:20;:22::i;:::-;25824:13;;;:38;25891:13;;:22;;:10;;25902:1;;25891:13;;;;;:22;25873:15;;;:40;25954:13;;:22;;:10;;25965:1;;25954:13;;;;;:22;25924:19;;;:53;26015:13;;:22;;:10;;26026:1;;26015:13;;;;;:22;25988:16;;;:50;-1:-1:-1;25988:7:0;-1:-1:-1;;25102:971:0;;;;;;:::o;26336:614::-;26517:16;;:::i;:::-;26551:26;26580:150;26640:16;26688:9;26671:27;;;;;;;;;;;;;;;;;;;;;;;;;26713:6;26580:45;:150::i;:::-;26551:179;;26743:22;;:::i;:::-;26782:20;;:25;26778:140;;26839:4;26824:19;;26872:34;:25;:13;:23;:25::i;:::-;:32;:34::i;:::-;26858:11;;;:48;26778:140;26937:5;26336:614;-1:-1:-1;;;;;26336:614:0:o;1037:158::-;1095:7;1128:1;1123;:6;;1115:49;;;;;-1:-1:-1;;;1115:49:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;1182:5:0;;;1037:158;;;;;:::o;43202:911::-;43473:7;43788:17;43784:58;;-1:-1:-1;43829:1:0;43822:8;;43784:58;43852:24;43879:67;32744:8;43879:43;:20;43904:17;43879:24;:43::i;:::-;:47;;:67::i;:::-;43852:94;-1:-1:-1;43957:24:0;43984:56;43852:94;43984:34;:14;44003;43984:18;:34::i;:::-;:38;;:56::i;:::-;43957:83;-1:-1:-1;44058:47:0;44092:12;44058:29;:7;43957:83;44058:11;:29::i;:::-;:33;;:47::i;:::-;44051:54;;;;43202:911;;;;;;;;;:::o;44324:307::-;44413:7;44433:9;29176:42;-1:-1:-1;;;;;44445:35:0;;:37;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;44445:37:0;44507:31;;;-1:-1:-1;;;44507:31:0;;;;44445:37;;-1:-1:-1;44493:11:0;;29176:42;;44507:29;;:31;;;;;44445:37;;44507:31;;;;;;;29176:42;44507:31;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;44507:31:0;44556:6;;;:67;;;;;;;;;;;44507:31;44556:67;;;;;;;-1:-1:-1;;;44556:67:0;;:6;:67;;;;;;;;;;;;44576:6;44556:67;;;;;;44507:31;;-1:-1:-1;;;;;;44556:6:0;;;;:13;;:6;;;;44576;;44556:67;44616:1;;44507:31;;44556:67;;;;;;;;;;:6;:67;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;44556:67:0;;44324:307;-1:-1:-1;;;;;44324:307:0:o;44904:188::-;-1:-1:-1;;;;;44967:20:0;;44959:29;;;;;;45017:5;;-1:-1:-1;;;;;45007:15:0;;;45017:5;;45007:15;;44999:24;;;;;;45034:5;:14;;-1:-1:-1;;;;;45034:14:0;;-1:-1:-1;;;;;;45034:14:0;;;;;;;;45064:20;;;;;;;;;;;;;;;;44904:188;:::o;44641:253::-;44759:5;44734:21;:30;;44726:39;;;;;;44776:20;:44;;;44836:50;;;;;;;;;;;;;;;;;44641:253;:::o;24254:558::-;24342:18;;:::i;:::-;24378:25;;:::i;:::-;24414:39;24456:36;:27;:15;:25;:27::i;:36::-;24414:78;;24536:46;:12;23090:1;24536:37;;;;;;;:46;24505:20;;;:78;24610:33;;:42;;:12;;23137:1;;24610:33;;;;;:42;24594:13;;;:58;24682:36;;:45;;:12;;23187:2;;24682:36;;;;;:45;24663:16;;;:64;-1:-1:-1;24752:26:0;;;;;;24738:40;;24663:6;-1:-1:-1;24254:558:0;;;:::o;5884:342::-;5965:8;;5944:4;;5961:31;;-1:-1:-1;5987:5:0;5980:12;;5961:31;6041:11;;;;6104:13;;6005:11;6096:22;;2603:4;6145:24;;6141:55;;;6191:5;6184:12;;;;;;6141:55;-1:-1:-1;6214:4:0;;5884:342;-1:-1:-1;;;5884:342:0:o;9748:422::-;9830:8;;9809:4;;9826:27;;-1:-1:-1;9852:1:0;9845:8;;9826:27;9866:10;9891:12;9920:27;9935:4;:11;;;9920:14;:27::i;:::-;9906:11;;;;9986:8;;9906:41;;;;-1:-1:-1;9972:22:0;10005:133;10022:6;10012:7;:16;10005:133;;;10064:20;10076:7;10064:11;:20::i;:::-;10119:7;;;;;10054:30;;;;10005:133;;;-1:-1:-1;10157:5:0;;9748:422;-1:-1:-1;;;9748:422:0:o;11579:551::-;11717:13;;11638:4;;11709:22;;2509:4;11758:26;;11754:368;;;11806:1;11799:8;;;;;11754:368;2556:4;11827:25;;;:83;;-1:-1:-1;2603:4:0;11857:25;;;;;:52;;-1:-1:-1;2650:4:0;11886:23;;11857:52;11823:299;;;11932:1;11925:8;;;;;11823:299;2603:4;11953:24;;11949:173;;;-1:-1:-1;;12018:35:0;;-1:-1:-1;12011:42:0;;11949:173;-1:-1:-1;;12089:33:0;;-1:-1:-1;12082:40:0;;10222:1302;10380:13;;10278:4;;;;10372:22;;2509:4;10421:26;;10417:1073;;;10472:1;10462:11;;10417:1073;;;2556:4;10495:25;;10491:999;;;-1:-1:-1;;10545:30:0;;;-1:-1:-1;10491:999:0;;;2603:4;10597:24;;10593:897;;;10692:4;10685:5;10681:16;10772:1;10764:6;10760:14;10750:24;;10914:7;10910:2;10906:16;10901:3;10897:26;10888:6;10882:13;10878:46;11012:1;11003:7;10999:15;10990:7;10986:29;10975:40;;;;10647:383;;;2650:4;11062:23;;11058:432;;;-1:-1:-1;;11112:28:0;;;-1:-1:-1;11058:432:0;;;11238:4;11231:5;11227:16;11283:1;11275:6;11271:14;11261:24;;11356:7;11352:2;11348:16;11343:3;11339:26;11330:6;11324:13;11320:46;11461:1;11452:7;11448:15;11439:7;11435:29;11424:40;;;;11193:286;-1:-1:-1;11509:7:0;10222:1302;-1:-1:-1;;10222:1302:0:o;14065:5625::-;14220:18;14251:19;14273:23;14288:4;14294:1;14273:14;:23::i;:::-;14251:45;;14307:20;14344;14375;14406:31;14450:33;;:::i;:::-;14500:12;;14496:227;;14610:66;14598:78;;14590:87;;;;;;-1:-1:-1;;14699:12:0;;;14709:1;14699:12;;;;;;;;;-1:-1:-1;14692:19:0;;-1:-1:-1;;;;14692:19:0;14496:227;14794:9;14789:4894;14813:5;:12;14809:1;:16;14789:4894;;;15095:6;;:50;;;;;15117:28;:5;15123:1;15117:8;;;;;;;;;;;;;;:26;:28::i;:::-;15105:8;:40;;15095:50;15091:99;;;15166:8;;;15091:99;15307:6;;;;;:48;;;15333:22;15346:5;15352:1;15346:8;;;;;;;;;;;;;;15333:12;:22::i;:::-;15317:12;:38;;15307:48;15303:97;;;15376:8;;;15303:97;15529:17;:5;15535:1;15529:8;;;;;;;:17;15522:24;;15567:4;:11;15582:1;15567:16;15563:4109;;;15649:11;15679:20;15738:47;15767:17;:4;15772:1;15767:7;;;;;;;;;;;;;;:15;:17::i;:::-;15738:28;:47::i;:::-;15718:67;;-1:-1:-1;15718:67:0;-1:-1:-1;15806:20:0;15829:50;15849:12;15863:6;15718:67;15829:19;:50::i;:::-;15806:73;;15914:12;15898:28;;;;15966:7;:14;15951:12;:29;15947:1013;;;16768:1;16753:5;:12;:16;16749:1;:20;16745:152;;;16865:8;;;16745:152;16938:1;;16928:12;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;16928:12:0;;16921:19;;;;;;;;;;;;;;15947:1013;16984:6;16980:1184;;;17075:1;17060:5;:12;:16;17056:1;:20;17052:147;;;17167:8;;;17052:147;17242:6;:13;17227:12;:28;17223:104;;;17301:1;;17291:12;;17223:104;17362:4;17367:1;17362:7;;;;;;;;;;;;;;17351:18;;17399;:8;:16;:18::i;:::-;17392:25;;;;;;;;;;;;;;16980:1184;17540:1;17525:5;:12;:16;17520:1;:21;17516:141;;;17625:8;;;17516:141;17686:16;:4;17691:1;17686:7;;;;;;;;;;;;;;:14;:16::i;:::-;17681:464;;17876:26;:4;17881:1;17876:7;;;;;;;;;;;;;;:24;:26::i;:::-;17861:41;;17681:464;;;18094:27;:4;18099:1;18094:7;;;;;;;:27;18079:42;;17681:464;15563:4109;;;;;;18189:4;:11;18204:2;18189:17;18185:1487;;;18281:6;:13;18265:12;:29;18261:1396;;18410:12;18431:6;18438:12;18431:20;;;;;;;;;;;;18491:1;18475:17;;;;;18431:20;;;-1:-1:-1;18529:2:0;18519:12;;18515:149;;18632:8;;;18515:149;18692:34;18713:4;18718:6;18713:12;;;;;;;;;;;;;;;;18692:20;:34::i;:::-;18688:568;;;18814:1;18799:5;:12;:16;18794:1;:21;18790:160;;18914:8;;;18790:160;-1:-1:-1;;18985:12:0;;;18995:1;18985:12;;;;;;;;;-1:-1:-1;18978:19:0;;-1:-1:-1;;;;;;18978:19:0;18688:568;19032:21;:4;19037:6;19032:12;;;;;;;;;:21;19027:229;;19097:31;:4;19102:6;19097:12;;;;;;;;;:31;19082:46;;19027:229;;;19200:32;:4;19205:6;19200:12;;;;;;;;;:32;19185:47;;19027:229;18261:1396;;;;19474:1;19459:5;:12;:16;19454:1;:21;19450:138;;19556:8;;;19450:138;19619:18;:4;19624:2;19619:8;;;;;;;:18;19612:25;;;;;;;;;;;18261:1396;14827:3;;14789:4894;;;;14065:5625;;;;;;;;;;;:::o;8433:471::-;8518:8;;8493:4;;8518:12;;;;:30;;-1:-1:-1;8534:8:0;;8546:2;-1:-1:-1;8534:14:0;8518:30;8510:39;;;;;;8563:11;8576:8;8588:21;8604:4;8588:15;:21::i;:::-;8678:13;;8562:47;;-1:-1:-1;8562:47:0;-1:-1:-1;8777:2:0;8769:11;;8766:2;;;8835;8831:12;;;8826:3;8822:22;8810:35;;8766:2;8890:6;8433:471;-1:-1:-1;;;;8433:471:0:o;1454:220::-;1512:7;1536:6;1532:20;;-1:-1:-1;1551:1:0;1544:8;;1532:20;1575:5;;;1579:1;1575;:5;:1;1599:5;;;;;:10;1591:56;;;;-1:-1:-1;;;1591:56:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;575:179;633:7;665:5;;;689:6;;;;681:46;;;;;-1:-1:-1;;;681:46:0;;;;;;;;;;;;;;;;;;;;;;;;;;;2152:153;2210:7;2242:1;2238;:5;2230:44;;;;;-1:-1:-1;;;2230:44:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;2296:1;2292;:5;;;;;;;2152:153;-1:-1:-1;;;2152:153:0:o;21715:763::-;21804:20;21862:1;21845:7;:14;:18;21837:27;;;;;;21894:14;;21911:1;21894:18;21931:21;;;;21923:30;;;;;;21964:21;;;;22008:17;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;22008:17:0;-1:-1:-1;21998:27:0;-1:-1:-1;22036:21:0;22091:11;22074:345;22122:6;22108:11;:20;22104:1;:24;22074:345;;;22161:1;22157;:5;22153:222;;22244:1;22227:7;22237:1;22235;:3;22227:12;;;;;;;;;;;;;;;;22221:19;;:24;;;;22249:3;22220:32;22213:40;;22188:7;22196:13;22188:22;;;;;;;;;;;:65;-1:-1:-1;;;;;22188:65:0;;;;;;;;;22153:222;;;22350:1;22333:7;22343:1;22341;:3;22333:12;;;;;;;;;;;;;;;;22327:19;;:24;;;;22355:3;22326:32;22319:40;;22294:7;22302:13;22294:22;;;;;;;;;;;:65;-1:-1:-1;;;;;22294:65:0;;;;;;;;;22153:222;22406:1;22389:18;;;;22130:6;22074:345;;;;22455:7;:14;22438:13;:31;22431:39;;;;21715:763;;;;;;:::o;6394:280::-;6499:11;;;;6535:8;;6613:19;;;6394:280::o;20268:272::-;20343:7;20378:2;20367:4;:8;;;:13;20363:170;;;20404:24;:4;:22;:24::i;:::-;20397:31;;;;20363:170;20495:24;:4;:22;:24::i;:::-;20478:42;;;;;;;;;;;;;;;;;;;;;;;;;20468:53;;;;;;20461:60;;;;9252:383;9346:8;;9313:12;;9338:21;;;;;;9373:11;9386:8;9398:21;9414:4;9398:15;:21::i;:::-;9372:47;;;;9430:19;9462:3;9452:14;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;9452:14:0;-1:-1:-1;9430:36:0;-1:-1:-1;9541:4:0;9537:17;;9577:26;9582:6;9537:17;9599:3;9577:4;:26::i;:::-;-1:-1:-1;9621:6:0;9252:383;-1:-1:-1;;;;9252:383:0:o;20903:802::-;20985:11;20998:20;21056:1;21039:7;:14;:18;21031:27;;;;;;21069:20;21113:1;21098:7;21106:1;21098:10;;;;;;;;;;;;;;;21092:22;;21117:3;21092:28;;-1:-1:-1;21131:19:0;21092:28;21161:473;;-1:-1:-1;21238:5:0;;-1:-1:-1;21213:1:0;21161:473;;;21265:12;21281:1;21265:17;21261:373;;;-1:-1:-1;21338:5:0;;-1:-1:-1;21313:1:0;21261:373;;;21365:12;21381:1;21365:17;21361:273;;;-1:-1:-1;21438:4:0;;-1:-1:-1;21413:1:0;21361:273;;;21464:12;21480:1;21464:17;21460:174;;;-1:-1:-1;21512:1:0;;-1:-1:-1;21512:1:0;21460:174;21652:6;21660:36;21675:7;21684:11;21660:14;:36::i;:::-;21644:53;;;;;;20903:802;;;:::o;22488:329::-;22591:7;;22631:160;22658:2;:9;22647:8;22643:1;:12;:24;:41;;;;;22675:2;:9;22671:1;:13;22643:41;22631:160;;;22730:2;22733:1;22730:5;;;;;;;;;;;;;;;;-1:-1:-1;;;;;22710:25:0;;:2;22717:8;22713:1;:12;22710:16;;;;;;;;;;;;-1:-1:-1;;;;;;22710:16:0;:25;22706:74;;22763:1;-1:-1:-1;22756:8:0;;22706:74;22686:3;;22631:160;;6838:271;6908:7;6929:11;6942:8;6954:21;6970:4;6954:15;:21::i;:::-;7045:22;;;6838:271;-1:-1:-1;;;;6838:271:0:o;20548:345::-;20652:8;;20631:4;;20664:1;20652:13;20648:58;;-1:-1:-1;20689:5:0;20682:12;;20648:58;-1:-1:-1;20751:11:0;;;20810:13;20716:7;20802:22;20857:4;20852:9;;20548:345::o;4706:271::-;4775:4;4781;4798:11;4812:27;4827:4;:11;;;4812:14;:27::i;:::-;4864:11;;;;4906:8;;4864:20;;;;4906:17;;;4706:271;-1:-1:-1;;;4706:271:0:o;12291:717::-;12364:8;12360:21;;12374:7;;12360:21;12441:201;2688:2;12448:16;;12441:201;;12540:10;;12527:24;;2688:2;12582:16;;;;12613:17;;;;-1:-1:-1;;12466:16:0;12441:201;;;12829:10;;12901:11;;2688:2;12755:15;;;12747:3;:24;-1:-1:-1;;12747:28:0;12841:9;;12825:26;;;12897:22;;12968:21;12955:35;;12795:206;;;;:::o;-1:-1:-1:-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;:::-;;;;;;;;;;;;;;;;;;;:::o;:::-;;;;;;;;;;;;;;;;;;;:::o

Swarm Source

ipfs://095da2537f60d3d5845a4a76859503b83425e5f1d2b667b113624fbfc887af03

Block Transaction Difficulty Gas Used Reward
View All Blocks Produced

Block Uncle Number Difficulty Gas Used Reward
View All Uncles
Loading...
Loading
Loading...
Loading
Make sure to use the "Vote Down" button for any spammy posts, and the "Vote Up" for interesting conversations.

Validator Index Block Amount
View All Withdrawals

Txn Hash Block Value Eth2 PubKey Valid
View All Deposits
[ Download: CSV Export  ]

A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.