ETH Price: $2,695.64 (+1.48%)

Contract

0x682364078e26C1626abD2B95109D2019E241F0F6

Overview

ETH Balance

0 ETH

ETH Value

$0.00

Multichain Info

No addresses found
Transaction Hash
Method
Block
From
To

There are no matching entries

1 Internal Transaction found.

Latest 1 internal transaction

Parent Transaction Hash Block From To
166797512024-10-09 9:48:01128 days ago1728467281  Contract Creation0 ETH
Loading...
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
SmtLib

Compiler Version
v0.8.27+commit.40a35a09

Optimization Enabled:
No with 200 runs

Other Settings:
paris EvmVersion
File 1 of 3 : SmtLib.sol
// SPDX-License-Identifier: GPL-3.0
pragma solidity 0.8.27;

import {PoseidonUnit2L, PoseidonUnit3L} from "./Poseidon.sol";
import {ArrayUtils} from "./ArrayUtils.sol";

/// @title A sparse merkle tree implementation, which keeps tree history.
// Note that this SMT implementation can manage duplicated roots in the history,
// which may happen when some leaf change its value and then changes it back to the original value.
// Leaves deletion is not supported, although it should be possible to implement it in the future
// versions of this library, without changing the existing state variables
// In this way all the SMT data may be preserved for the contracts already in production.
library SmtLib {
    /**
     * @dev Max return array length for SMT root history requests
     */
    uint256 public constant ROOT_INFO_LIST_RETURN_LIMIT = 1000;

    /**
     * @dev Max depth hard cap for SMT
     * We can't use depth > 256 because of bits number limitation in the uint256 data type.
     */
    uint256 public constant MAX_DEPTH_HARD_CAP = 256;

    /**
     * @dev Enum of SMT node types
     */
    enum NodeType {
        EMPTY,
        LEAF,
        MIDDLE
    }

    /**
     * @dev Sparse Merkle Tree data
     * Note that we count the SMT depth starting from 0, which is the root level.
     *
     * For example, the following tree has a maxDepth = 2:
     *
     *     O      <- root level (depth = 0)
     *    / \
     *   O   O    <- depth = 1
     *  / \ / \
     * O  O O  O  <- depth = 2
     */
    struct Data {
        mapping(uint256 => Node) nodes;
        RootEntry[] rootEntries;
        mapping(uint256 => uint256[]) rootIndexes; // root => rootEntryIndex[]
        uint256 maxDepth;
        bool initialized;
        // This empty reserved space is put in place to allow future versions
        // of the SMT library to add new Data struct fields without shifting down
        // storage of upgradable contracts that use this struct as a state variable
        // (see https://docs.openzeppelin.com/upgrades-plugins/1.x/writing-upgradeable#storage-gaps)
        uint256[45] __gap;
    }

    /**
     * @dev Struct of the node proof in the SMT.
     * @param root This SMT root.
     * @param existence A flag, which shows if the leaf index exists in the SMT.
     * @param siblings An array of SMT sibling node hashes.
     * @param index An index of the leaf in the SMT.
     * @param value A value of the leaf in the SMT.
     * @param auxExistence A flag, which shows if the auxiliary leaf exists in the SMT.
     * @param auxIndex An index of the auxiliary leaf in the SMT.
     * @param auxValue An value of the auxiliary leaf in the SMT.
     */
    struct Proof {
        uint256 root;
        bool existence;
        uint256[] siblings;
        uint256 index;
        uint256 value;
        bool auxExistence;
        uint256 auxIndex;
        uint256 auxValue;
    }

    /**
     * @dev Struct for SMT root internal storage representation.
     * @param root SMT root.
     * @param createdAtTimestamp A time, when the root was saved to blockchain.
     * @param createdAtBlock A number of block, when the root was saved to blockchain.
     */
    struct RootEntry {
        uint256 root;
        uint256 createdAtTimestamp;
        uint256 createdAtBlock;
    }

    /**
     * @dev Struct for public interfaces to represent SMT root info.
     * @param root This SMT root.
     * @param replacedByRoot A root, which replaced this root.
     * @param createdAtTimestamp A time, when the root was saved to blockchain.
     * @param replacedAtTimestamp A time, when the root was replaced by the next root in blockchain.
     * @param createdAtBlock A number of block, when the root was saved to blockchain.
     * @param replacedAtBlock A number of block, when the root was replaced by the next root in blockchain.
     */
    struct RootEntryInfo {
        uint256 root;
        uint256 replacedByRoot;
        uint256 createdAtTimestamp;
        uint256 replacedAtTimestamp;
        uint256 createdAtBlock;
        uint256 replacedAtBlock;
    }

    /**
     * @dev Struct of SMT node.
     * @param NodeType type of node.
     * @param childLeft left child of node.
     * @param childRight right child of node.
     * @param Index index of node.
     * @param Value value of node.
     */
    struct Node {
        NodeType nodeType;
        uint256 childLeft;
        uint256 childRight;
        uint256 index;
        uint256 value;
    }

    using BinarySearchSmtRoots for Data;
    using ArrayUtils for uint256[];

    /**
     * @dev Reverts if root does not exist in SMT roots history.
     * @param root SMT root.
     */
    modifier onlyExistingRoot(Data storage self, uint256 root) {
        require(rootExists(self, root), "Root does not exist");
        _;
    }

    /**
     * @dev Add a leaf to the SMT
     * @param i Index of a leaf
     * @param v Value of a leaf
     */
    function addLeaf(Data storage self, uint256 i, uint256 v) external onlyInitialized(self) {
        Node memory node = Node({
            nodeType: NodeType.LEAF,
            childLeft: 0,
            childRight: 0,
            index: i,
            value: v
        });

        uint256 prevRoot = getRoot(self);
        uint256 newRoot = _addLeaf(self, node, prevRoot, 0);

        _addEntry(self, newRoot, block.timestamp, block.number);
    }

    /**
     * @dev Get SMT root history length
     * @return SMT history length
     */
    function getRootHistoryLength(Data storage self) external view returns (uint256) {
        return self.rootEntries.length;
    }

    /**
     * @dev Get SMT root history
     * @param startIndex start index of history
     * @param length history length
     * @return array of RootEntryInfo structs
     */
    function getRootHistory(
        Data storage self,
        uint256 startIndex,
        uint256 length
    ) external view returns (RootEntryInfo[] memory) {
        (uint256 start, uint256 end) = ArrayUtils.calculateBounds(
            self.rootEntries.length,
            startIndex,
            length,
            ROOT_INFO_LIST_RETURN_LIMIT
        );

        RootEntryInfo[] memory result = new RootEntryInfo[](end - start);

        for (uint256 i = start; i < end; i++) {
            result[i - start] = _getRootInfoByIndex(self, i);
        }
        return result;
    }

    /**
     * @dev Get the SMT node by hash
     * @param nodeHash Hash of a node
     * @return A node struct
     */
    function getNode(Data storage self, uint256 nodeHash) public view returns (Node memory) {
        return self.nodes[nodeHash];
    }

    /**
     * @dev Get the proof if a node with specific index exists or not exists in the SMT.
     * @param index A node index.
     * @return SMT proof struct.
     */
    function getProof(Data storage self, uint256 index) external view returns (Proof memory) {
        return getProofByRoot(self, index, getRoot(self));
    }

    /**
     * @dev Get the proof if a node with specific index exists or not exists in the SMT for some historical tree state.
     * @param index A node index
     * @param historicalRoot Historical SMT roof to get proof for.
     * @return Proof struct.
     */
    function getProofByRoot(
        Data storage self,
        uint256 index,
        uint256 historicalRoot
    ) public view onlyExistingRoot(self, historicalRoot) returns (Proof memory) {
        uint256[] memory siblings = new uint256[](self.maxDepth);
        // Solidity does not guarantee that memory vars are zeroed out
        for (uint256 i = 0; i < self.maxDepth; i++) {
            siblings[i] = 0;
        }

        Proof memory proof = Proof({
            root: historicalRoot,
            existence: false,
            siblings: siblings,
            index: index,
            value: 0,
            auxExistence: false,
            auxIndex: 0,
            auxValue: 0
        });

        uint256 nextNodeHash = historicalRoot;
        Node memory node;

        for (uint256 i = 0; i <= self.maxDepth; i++) {
            node = getNode(self, nextNodeHash);
            if (node.nodeType == NodeType.EMPTY) {
                break;
            } else if (node.nodeType == NodeType.LEAF) {
                if (node.index == proof.index) {
                    proof.existence = true;
                    proof.value = node.value;
                    break;
                } else {
                    proof.auxExistence = true;
                    proof.auxIndex = node.index;
                    proof.auxValue = node.value;
                    proof.value = node.value;
                    break;
                }
            } else if (node.nodeType == NodeType.MIDDLE) {
                if ((proof.index >> i) & 1 == 1) {
                    nextNodeHash = node.childRight;
                    proof.siblings[i] = node.childLeft;
                } else {
                    nextNodeHash = node.childLeft;
                    proof.siblings[i] = node.childRight;
                }
            } else {
                revert("Invalid node type");
            }
        }
        return proof;
    }

    /**
     * @dev Get the proof if a node with specific index exists or not exists in the SMT by some historical timestamp.
     * @param index Node index.
     * @param timestamp The latest timestamp to get proof for.
     * @return Proof struct.
     */
    function getProofByTime(
        Data storage self,
        uint256 index,
        uint256 timestamp
    ) public view returns (Proof memory) {
        RootEntryInfo memory rootInfo = getRootInfoByTime(self, timestamp);
        return getProofByRoot(self, index, rootInfo.root);
    }

    /**
     * @dev Get the proof if a node with specific index exists or not exists in the SMT by some historical block number.
     * @param index Node index.
     * @param blockNumber The latest block number to get proof for.
     * @return Proof struct.
     */
    function getProofByBlock(
        Data storage self,
        uint256 index,
        uint256 blockNumber
    ) external view returns (Proof memory) {
        RootEntryInfo memory rootInfo = getRootInfoByBlock(self, blockNumber);
        return getProofByRoot(self, index, rootInfo.root);
    }

    function getRoot(Data storage self) public view onlyInitialized(self) returns (uint256) {
        return self.rootEntries[self.rootEntries.length - 1].root;
    }

    /**
     * @dev Get root info by some historical timestamp.
     * @param timestamp The latest timestamp to get the root info for.
     * @return Root info struct
     */
    function getRootInfoByTime(
        Data storage self,
        uint256 timestamp
    ) public view returns (RootEntryInfo memory) {
        require(timestamp <= block.timestamp, "No future timestamps allowed");

        return
            _getRootInfoByTimestampOrBlock(
                self,
                timestamp,
                BinarySearchSmtRoots.SearchType.TIMESTAMP
            );
    }

    /**
     * @dev Get root info by some historical block number.
     * @param blockN The latest block number to get the root info for.
     * @return Root info struct
     */
    function getRootInfoByBlock(
        Data storage self,
        uint256 blockN
    ) public view returns (RootEntryInfo memory) {
        require(blockN <= block.number, "No future blocks allowed");

        return _getRootInfoByTimestampOrBlock(self, blockN, BinarySearchSmtRoots.SearchType.BLOCK);
    }

    /**
     * @dev Returns root info by root
     * @param root root
     * @return Root info struct
     */
    function getRootInfo(
        Data storage self,
        uint256 root
    ) public view onlyExistingRoot(self, root) returns (RootEntryInfo memory) {
        uint256[] storage indexes = self.rootIndexes[root];
        uint256 lastIndex = indexes[indexes.length - 1];
        return _getRootInfoByIndex(self, lastIndex);
    }

    /**
     * @dev Retrieve duplicate root quantity by id and state.
     * If the root repeats more that once, the length may be greater than 1.
     * @param root A root.
     * @return Root root entries quantity.
     */
    function getRootInfoListLengthByRoot(
        Data storage self,
        uint256 root
    ) public view returns (uint256) {
        return self.rootIndexes[root].length;
    }

    /**
     * @dev Retrieve root infos list of duplicated root by id and state.
     * If the root repeats more that once, the length list may be greater than 1.
     * @param root A root.
     * @param startIndex The index to start the list.
     * @param length The length of the list.
     * @return Root Root entries quantity.
     */
    function getRootInfoListByRoot(
        Data storage self,
        uint256 root,
        uint256 startIndex,
        uint256 length
    ) public view onlyExistingRoot(self, root) returns (RootEntryInfo[] memory) {
        uint256[] storage indexes = self.rootIndexes[root];
        (uint256 start, uint256 end) = ArrayUtils.calculateBounds(
            indexes.length,
            startIndex,
            length,
            ROOT_INFO_LIST_RETURN_LIMIT
        );

        RootEntryInfo[] memory result = new RootEntryInfo[](end - start);
        for (uint256 i = start; i < end; i++) {
            result[i - start] = _getRootInfoByIndex(self, indexes[i]);
        }

        return result;
    }

    /**
     * @dev Checks if root exists
     * @param root root
     * return true if root exists
     */
    function rootExists(Data storage self, uint256 root) public view returns (bool) {
        return self.rootIndexes[root].length > 0;
    }

    /**
     * @dev Sets max depth of the SMT
     * @param maxDepth max depth
     */
    function setMaxDepth(Data storage self, uint256 maxDepth) public {
        require(maxDepth > 0, "Max depth must be greater than zero");
        require(maxDepth > self.maxDepth, "Max depth can only be increased");
        require(maxDepth <= MAX_DEPTH_HARD_CAP, "Max depth is greater than hard cap");
        self.maxDepth = maxDepth;
    }

    /**
     * @dev Gets max depth of the SMT
     * return max depth
     */
    function getMaxDepth(Data storage self) external view returns (uint256) {
        return self.maxDepth;
    }

    /**
     * @dev Initialize SMT with max depth and root entry of an empty tree.
     * @param maxDepth Max depth of the SMT.
     */
    function initialize(Data storage self, uint256 maxDepth) external {
        require(!isInitialized(self), "Smt is already initialized");
        setMaxDepth(self, maxDepth);
        _addEntry(self, 0, 0, 0);
        self.initialized = true;
    }

    modifier onlyInitialized(Data storage self) {
        require(isInitialized(self), "Smt is not initialized");
        _;
    }

    function isInitialized(Data storage self) public view returns (bool) {
        return self.initialized;
    }

    function _addLeaf(
        Data storage self,
        Node memory newLeaf,
        uint256 nodeHash,
        uint256 depth
    ) internal returns (uint256) {
        if (depth > self.maxDepth) {
            revert("Max depth reached");
        }

        Node memory node = self.nodes[nodeHash];
        uint256 nextNodeHash;
        uint256 leafHash = 0;

        if (node.nodeType == NodeType.EMPTY) {
            leafHash = _addNode(self, newLeaf);
        } else if (node.nodeType == NodeType.LEAF) {
            leafHash = node.index == newLeaf.index
                ? _addNode(self, newLeaf)
                : _pushLeaf(self, newLeaf, node, depth);
        } else if (node.nodeType == NodeType.MIDDLE) {
            Node memory newNodeMiddle;

            if ((newLeaf.index >> depth) & 1 == 1) {
                nextNodeHash = _addLeaf(self, newLeaf, node.childRight, depth + 1);

                newNodeMiddle = Node({
                    nodeType: NodeType.MIDDLE,
                    childLeft: node.childLeft,
                    childRight: nextNodeHash,
                    index: 0,
                    value: 0
                });
            } else {
                nextNodeHash = _addLeaf(self, newLeaf, node.childLeft, depth + 1);

                newNodeMiddle = Node({
                    nodeType: NodeType.MIDDLE,
                    childLeft: nextNodeHash,
                    childRight: node.childRight,
                    index: 0,
                    value: 0
                });
            }

            leafHash = _addNode(self, newNodeMiddle);
        }

        return leafHash;
    }

    function _pushLeaf(
        Data storage self,
        Node memory newLeaf,
        Node memory oldLeaf,
        uint256 depth
    ) internal returns (uint256) {
        // no reason to continue if we are at max possible depth
        // as, anyway, we exceed the depth going down the tree
        if (depth >= self.maxDepth) {
            revert("Max depth reached");
        }

        Node memory newNodeMiddle;
        bool newLeafBitAtDepth = (newLeaf.index >> depth) & 1 == 1;
        bool oldLeafBitAtDepth = (oldLeaf.index >> depth) & 1 == 1;

        // Check if we need to go deeper if diverge at the depth's bit
        if (newLeafBitAtDepth == oldLeafBitAtDepth) {
            uint256 nextNodeHash = _pushLeaf(self, newLeaf, oldLeaf, depth + 1);

            if (newLeafBitAtDepth) {
                // go right
                newNodeMiddle = Node(NodeType.MIDDLE, 0, nextNodeHash, 0, 0);
            } else {
                // go left
                newNodeMiddle = Node(NodeType.MIDDLE, nextNodeHash, 0, 0, 0);
            }
            return _addNode(self, newNodeMiddle);
        }

        if (newLeafBitAtDepth) {
            newNodeMiddle = Node({
                nodeType: NodeType.MIDDLE,
                childLeft: _getNodeHash(oldLeaf),
                childRight: _getNodeHash(newLeaf),
                index: 0,
                value: 0
            });
        } else {
            newNodeMiddle = Node({
                nodeType: NodeType.MIDDLE,
                childLeft: _getNodeHash(newLeaf),
                childRight: _getNodeHash(oldLeaf),
                index: 0,
                value: 0
            });
        }

        _addNode(self, newLeaf);
        return _addNode(self, newNodeMiddle);
    }

    function _addNode(Data storage self, Node memory node) internal returns (uint256) {
        uint256 nodeHash = _getNodeHash(node);
        // We don't have any guarantees if the hash function attached is good enough.
        // So, if the node hash already exists, we need to check
        // if the node in the tree exactly matches the one we are trying to add.
        if (self.nodes[nodeHash].nodeType != NodeType.EMPTY) {
            assert(self.nodes[nodeHash].nodeType == node.nodeType);
            assert(self.nodes[nodeHash].childLeft == node.childLeft);
            assert(self.nodes[nodeHash].childRight == node.childRight);
            assert(self.nodes[nodeHash].index == node.index);
            assert(self.nodes[nodeHash].value == node.value);
            return nodeHash;
        }

        self.nodes[nodeHash] = node;
        return nodeHash;
    }

    function _getNodeHash(Node memory node) internal pure returns (uint256) {
        uint256 nodeHash = 0;
        if (node.nodeType == NodeType.LEAF) {
            uint256[3] memory params = [node.index, node.value, uint256(1)];
            nodeHash = PoseidonUnit3L.poseidon(params);
        } else if (node.nodeType == NodeType.MIDDLE) {
            nodeHash = PoseidonUnit2L.poseidon([node.childLeft, node.childRight]);
        }
        return nodeHash; // Note: expected to return 0 if NodeType.EMPTY, which is the only option left
    }

    function _getRootInfoByIndex(
        Data storage self,
        uint256 index
    ) internal view returns (RootEntryInfo memory) {
        bool isLastRoot = index == self.rootEntries.length - 1;
        RootEntry storage rootEntry = self.rootEntries[index];

        return
            RootEntryInfo({
                root: rootEntry.root,
                replacedByRoot: isLastRoot ? 0 : self.rootEntries[index + 1].root,
                createdAtTimestamp: rootEntry.createdAtTimestamp,
                replacedAtTimestamp: isLastRoot
                    ? 0
                    : self.rootEntries[index + 1].createdAtTimestamp,
                createdAtBlock: rootEntry.createdAtBlock,
                replacedAtBlock: isLastRoot ? 0 : self.rootEntries[index + 1].createdAtBlock
            });
    }

    function _getRootInfoByTimestampOrBlock(
        Data storage self,
        uint256 timestampOrBlock,
        BinarySearchSmtRoots.SearchType searchType
    ) internal view returns (RootEntryInfo memory) {
        (uint256 index, bool found) = self.binarySearchUint256(timestampOrBlock, searchType);

        // As far as we always have at least one root entry, we should always find it
        assert(found);

        return _getRootInfoByIndex(self, index);
    }

    function _addEntry(
        Data storage self,
        uint256 root,
        uint256 _timestamp,
        uint256 _block
    ) internal {
        self.rootEntries.push(
            RootEntry({root: root, createdAtTimestamp: _timestamp, createdAtBlock: _block})
        );

        self.rootIndexes[root].push(self.rootEntries.length - 1);
    }
}

/// @title A binary search for the sparse merkle tree root history
// Implemented as a separate library for testing purposes
library BinarySearchSmtRoots {
    /**
     * @dev Enum for the SMT history field selection
     */
    enum SearchType {
        TIMESTAMP,
        BLOCK
    }

    /**
     * @dev Binary search method for the SMT history,
     * which searches for the index of the root entry saved by the given timestamp or block
     * @param value The timestamp or block to search for.
     * @param searchType The type of the search (timestamp or block).
     */
    function binarySearchUint256(
        SmtLib.Data storage self,
        uint256 value,
        SearchType searchType
    ) internal view returns (uint256, bool) {
        if (self.rootEntries.length == 0) {
            return (0, false);
        }

        uint256 min = 0;
        uint256 max = self.rootEntries.length - 1;
        uint256 mid;

        while (min <= max) {
            mid = (max + min) / 2;

            uint256 midValue = fieldSelector(self.rootEntries[mid], searchType);
            if (midValue == value) {
                while (mid < self.rootEntries.length - 1) {
                    uint256 nextValue = fieldSelector(self.rootEntries[mid + 1], searchType);
                    if (nextValue == value) {
                        mid++;
                    } else {
                        return (mid, true);
                    }
                }
                return (mid, true);
            } else if (value > midValue) {
                min = mid + 1;
            } else if (value < midValue && mid > 0) {
                // mid > 0 is to avoid underflow
                max = mid - 1;
            } else {
                // This means that value < midValue && mid == 0. So we found nothing.
                return (0, false);
            }
        }

        // The case when the searched value does not exist and we should take the closest smaller value
        // Index in the "max" var points to the root entry with max value smaller than the searched value
        return (max, true);
    }

    /**
     * @dev Selects either timestamp or block field from the root entry struct
     * depending on the search type
     * @param rti The root entry to select the field from.
     * @param st The search type.
     */
    function fieldSelector(
        SmtLib.RootEntry memory rti,
        SearchType st
    ) internal pure returns (uint256) {
        if (st == SearchType.BLOCK) {
            return rti.createdAtBlock;
        } else if (st == SearchType.TIMESTAMP) {
            return rti.createdAtTimestamp;
        } else {
            revert("Invalid search type");
        }
    }
}

File 2 of 3 : ArrayUtils.sol
// SPDX-License-Identifier: GPL-3.0
pragma solidity 0.8.27;

/// @title A common functions for arrays.
library ArrayUtils {
    /**
     * @dev Calculates bounds for the slice of the array.
     * @param arrLength An array length.
     * @param start A start index.
     * @param length A length of the slice.
     * @param limit A limit for the length.
     * @return The bounds for the slice of the array.
     */
    function calculateBounds(
        uint256 arrLength,
        uint256 start,
        uint256 length,
        uint256 limit
    ) internal pure returns (uint256, uint256) {
        require(length > 0, "Length should be greater than 0");
        require(length <= limit, "Length limit exceeded");
        require(start < arrLength, "Start index out of bounds");

        uint256 end = start + length;
        if (end > arrLength) {
            end = arrLength;
        }

        return (start, end);
    }
}

File 3 of 3 : Poseidon.sol
// SPDX-License-Identifier: GPL-3.0
pragma solidity 0.8.27;

library PoseidonUnit1L {
    function poseidon(uint256[1] calldata) public pure returns (uint256) {}
}

library PoseidonUnit2L {
    function poseidon(uint256[2] calldata) public pure returns (uint256) {}
}

library PoseidonUnit3L {
    function poseidon(uint256[3] calldata) public pure returns (uint256) {}
}

library PoseidonUnit4L {
    function poseidon(uint256[4] calldata) public pure returns (uint256) {}
}

library PoseidonUnit5L {
    function poseidon(uint256[5] calldata) public pure returns (uint256) {}
}

library PoseidonUnit6L {
    function poseidon(uint256[6] calldata) public pure returns (uint256) {}
}

library SpongePoseidon {
    uint32 internal constant BATCH_SIZE = 6;

    function hash(uint256[] memory values) public pure returns (uint256) {
        uint256[BATCH_SIZE] memory frame = [uint256(0), 0, 0, 0, 0, 0];
        bool dirty = false;
        uint256 fullHash = 0;
        uint32 k = 0;
        for (uint32 i = 0; i < values.length; i++) {
            dirty = true;
            frame[k] = values[i];
            if (k == BATCH_SIZE - 1) {
                fullHash = PoseidonUnit6L.poseidon(frame);
                dirty = false;
                frame = [uint256(0), 0, 0, 0, 0, 0];
                frame[0] = fullHash;
                k = 1;
            } else {
                k++;
            }
        }
        if (dirty) {
            // we haven't hashed something in the main sponge loop and need to do hash here
            fullHash = PoseidonUnit6L.poseidon(frame);
        }
        return fullHash;
    }
}

library PoseidonFacade {
    function poseidon1(uint256[1] calldata el) public pure returns (uint256) {
        return PoseidonUnit1L.poseidon(el);
    }

    function poseidon2(uint256[2] calldata el) public pure returns (uint256) {
        return PoseidonUnit2L.poseidon(el);
    }

    function poseidon3(uint256[3] calldata el) public pure returns (uint256) {
        return PoseidonUnit3L.poseidon(el);
    }

    function poseidon4(uint256[4] calldata el) public pure returns (uint256) {
        return PoseidonUnit4L.poseidon(el);
    }

    function poseidon5(uint256[5] calldata el) public pure returns (uint256) {
        return PoseidonUnit5L.poseidon(el);
    }

    function poseidon6(uint256[6] calldata el) public pure returns (uint256) {
        return PoseidonUnit6L.poseidon(el);
    }

    function poseidonSponge(uint256[] calldata el) public pure returns (uint256) {
        return SpongePoseidon.hash(el);
    }
}

Settings
{
  "evmVersion": "paris",
  "optimizer": {
    "enabled": false,
    "runs": 200
  },
  "outputSelection": {
    "*": {
      "*": [
        "evm.bytecode",
        "evm.deployedBytecode",
        "devdoc",
        "userdoc",
        "metadata",
        "abi"
      ]
    }
  },
  "libraries": {
    "contracts/lib/Poseidon.sol": {
      "PoseidonUnit2L": "0x72f721d9d5f91353b505207c63b56cf3d9447edb",
      "PoseidonUnit3L": "0x5bc89782d5ebf62663df7ce5fb4bc7408926a240"
    }
  }
}

Contract Security Audit

Contract ABI

[{"inputs":[],"name":"MAX_DEPTH_HARD_CAP","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"ROOT_INFO_LIST_RETURN_LIMIT","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"}]

612f43610052600b82828239805160001a6073146045577f4e487b7100000000000000000000000000000000000000000000000000000000600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600436106101405760003560e01c806379f97125116100c2578063a751be2411610086578063a751be24146103f5578063c1d29f0114610413578063dc9a7c8c1461043c578063dea7633a1461046c578063e170cf6e1461049c578063ec145108146104cc57610140565b806379f971251461030c578063893f99f31461033c57806391761b751461036c57806392f5b06c1461039c5780639e43b813146103cc57610140565b806340a73d981161010957806340a73d981461022e5780635db40cda1461024c57806362e8f2151461027c578063792a470f146102ac57806379c17a96146102dc57610140565b806278f030146101455780630912610a14610175578063138271361461019e57806317c850f0146101ce57806321d60953146101fe575b600080fd5b61015f600480360381019061015a9190611f7a565b6104fc565b60405161016c9190611fc9565b60405180910390f35b81801561018157600080fd5b5061019c60048036038101906101979190611f7a565b61051f565b005b6101b860048036038101906101b39190611fe4565b6105fa565b6040516101c591906121c0565b60405180910390f35b6101e860048036038101906101e39190611f7a565b610629565b6040516101f5919061225d565b60405180910390f35b61021860048036038101906102139190611fe4565b610688565b60405161022591906123a2565b60405180910390f35b610236610765565b6040516102439190611fc9565b60405180910390f35b61026660048036038101906102619190611f7a565b61076b565b60405161027391906121c0565b60405180910390f35b610296600480360381019061029191906123c4565b61078e565b6040516102a39190611fc9565b60405180910390f35b6102c660048036038101906102c19190611fe4565b61079f565b6040516102d391906121c0565b60405180910390f35b6102f660048036038101906102f19190611fe4565b6107ce565b60405161030391906121c0565b60405180910390f35b610326600480360381019061032191906123c4565b610afa565b6040516103339190611fc9565b60405180910390f35b610356600480360381019061035191906123c4565b610b88565b6040516103639190611fc9565b60405180910390f35b610386600480360381019061038191906123f1565b610b96565b60405161039391906123a2565b60405180910390f35b6103b660048036038101906103b19190611f7a565b610cf5565b6040516103c39190612467565b60405180910390f35b8180156103d857600080fd5b506103f360048036038101906103ee9190611f7a565b610d1a565b005b6103fd610d9c565b60405161040a9190611fc9565b60405180910390f35b81801561041f57600080fd5b5061043a60048036038101906104359190611fe4565b610da2565b005b61045660048036038101906104519190611f7a565b610e5e565b604051610463919061225d565b60405180910390f35b61048660048036038101906104819190611f7a565b610ebd565b604051610493919061225d565b60405180910390f35b6104b660048036038101906104b19190611f7a565b610f71565b6040516104c39190612561565b60405180910390f35b6104e660048036038101906104e191906123c4565b611004565b6040516104f39190612467565b60405180910390f35b600082600201600083815260200190815260200160002080549050905092915050565b60008111610562576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610559906125ff565b60405180910390fd5b816003015481116105a8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161059f9061266b565b60405180910390fd5b6101008111156105ed576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016105e4906126fd565b60405180910390fd5b8082600301819055505050565b610602611e49565b600061060e8584610629565b905061061f858583600001516107ce565b9150509392505050565b610631611e92565b42821115610674576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161066b90612769565b60405180910390fd5b6106808383600061101f565b905092915050565b60606000806106a2866001018054905086866103e8611066565b91509150600082826106b491906127b8565b67ffffffffffffffff8111156106cd576106cc6127ec565b5b60405190808252806020026020018201604052801561070657816020015b6106f3611e92565b8152602001906001900390816106eb5790505b50905060008390505b8281101561075757610721888261115d565b82858361072e91906127b8565b8151811061073f5761073e61281b565b5b6020026020010181905250808060010191505061070f565b508093505050509392505050565b6103e881565b610773611e49565b610786838361078186610afa565b6107ce565b905092915050565b600081600101805490509050919050565b6107a7611e49565b60006107b38584610e5e565b90506107c4858583600001516107ce565b9150509392505050565b6107d6611e49565b83826107e28282610cf5565b610821576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161081890612896565b60405180910390fd5b6000866003015467ffffffffffffffff811115610841576108406127ec565b5b60405190808252806020026020018201604052801561086f5781602001602082028036833780820191505090505b50905060005b87600301548110156108af5760008282815181106108965761089561281b565b5b6020026020010181815250508080600101915050610875565b5060006040518061010001604052808781526020016000151581526020018381526020018881526020016000815260200160001515815260200160008152602001600081525090506000869050610904611ec8565b60005b8a600301548111610ae95761091c8b84610f71565b91506000600281111561093257610931612482565b5b8260000151600281111561094957610948612482565b5b0315610ae9576001600281111561096357610962612482565b5b8260000151600281111561097a57610979612482565b5b036109f25783606001518260600151036109b25760018460200190151590811515815250508160800151846080018181525050610ae9565b60018460a001901515908115158152505081606001518460c001818152505081608001518460e00181815250508160800151846080018181525050610ae9565b600280811115610a0557610a04612482565b5b82600001516002811115610a1c57610a1b612482565b5b03610a9b57600180828660600151901c1603610a665781604001519250816020015184604001518281518110610a5557610a5461281b565b5b602002602001018181525050610a96565b81602001519250816040015184604001518281518110610a8957610a8861281b565b5b6020026020010181815250505b610ad6565b6040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610acd90612902565b60405180910390fd5b8080610ae190612922565b915050610907565b508296505050505050509392505050565b600081610b0681611004565b610b45576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610b3c906129b6565b60405180910390fd5b8260010160018460010180549050610b5d91906127b8565b81548110610b6e57610b6d61281b565b5b906000526020600020906003020160000154915050919050565b600081600301549050919050565b60608484610ba48282610cf5565b610be3576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610bda90612896565b60405180910390fd5b60008760020160008881526020019081526020016000209050600080610c11838054905089896103e8611066565b9150915060008282610c2391906127b8565b67ffffffffffffffff811115610c3c57610c3b6127ec565b5b604051908082528060200260200182016040528015610c7557816020015b610c62611e92565b815260200190600190039081610c5a5790505b50905060008390505b82811015610ce357610cad8c868381548110610c9d57610c9c61281b565b5b906000526020600020015461115d565b828583610cba91906127b8565b81518110610ccb57610cca61281b565b5b60200260200101819052508080600101915050610c7e565b50809650505050505050949350505050565b6000808360020160008481526020019081526020016000208054905011905092915050565b610d2382611004565b15610d63576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610d5a90612a22565b60405180910390fd5b610d6d828261051f565b610d7b8260008060006112aa565b60018260040160006101000a81548160ff0219169083151502179055505050565b61010081565b82610dac81611004565b610deb576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610de2906129b6565b60405180910390fd5b60006040518060a0016040528060016002811115610e0c57610e0b612482565b5b815260200160008152602001600081526020018581526020018481525090506000610e3686610afa565b90506000610e478784846000611367565b9050610e55878242436112aa565b50505050505050565b610e66611e92565b43821115610ea9576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610ea090612a8e565b60405180910390fd5b610eb58383600161101f565b905092915050565b610ec5611e92565b8282610ed18282610cf5565b610f10576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610f0790612896565b60405180910390fd5b6000856002016000868152602001908152602001600020905060008160018380549050610f3d91906127b8565b81548110610f4e57610f4d61281b565b5b90600052602060002001549050610f65878261115d565b94505050505092915050565b610f79611ec8565b8260000160008381526020019081526020016000206040518060a00160405290816000820160009054906101000a900460ff166002811115610fbe57610fbd612482565b5b6002811115610fd057610fcf612482565b5b8152602001600182015481526020016002820154815260200160038201548152602001600482015481525050905092915050565b60008160040160009054906101000a900460ff169050919050565b611027611e92565b60008061103f85858861160b9092919063ffffffff16565b915091508061105157611050612aae565b5b61105b868361115d565b925050509392505050565b600080600084116110ac576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016110a390612b29565b60405180910390fd5b828411156110ef576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016110e690612b95565b60405180910390fd5b858510611131576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161112890612c01565b60405180910390fd5b6000848661113f9190612c21565b90508681111561114d578690505b8581925092505094509492505050565b611165611e92565b60006001846001018054905061117b91906127b8565b8314905060008460010184815481106111975761119661281b565b5b906000526020600020906003020190506040518060c0016040528082600001548152602001836111fa57866001016001876111d29190612c21565b815481106111e3576111e261281b565b5b9060005260206000209060030201600001546111fd565b60005b8152602001826001015481526020018361124a57866001016001876112229190612c21565b815481106112335761123261281b565b5b90600052602060002090600302016001015461124d565b60005b8152602001826002015481526020018361129a57866001016001876112729190612c21565b815481106112835761128261281b565b5b90600052602060002090600302016002015461129d565b60005b8152509250505092915050565b83600101604051806060016040528085815260200184815260200183815250908060018154018082558091505060019003906000526020600020906003020160009091909190915060008201518160000155602082015181600101556040820151816002015550508360020160008481526020019081526020016000206001856001018054905061133b91906127b8565b908060018154018082558091505060019003906000526020600020016000909190919091505550505050565b600084600301548211156113b0576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016113a790612ca1565b60405180910390fd5b60008560000160008581526020019081526020016000206040518060a00160405290816000820160009054906101000a900460ff1660028111156113f7576113f6612482565b5b600281111561140957611408612482565b5b81526020016001820154815260200160028201548152602001600382015481526020016004820154815250509050600080600090506000600281111561145257611451612482565b5b8360000151600281111561146957611468612482565b5b0361147f5761147888886117f8565b90506115fd565b6001600281111561149357611492612482565b5b836000015160028111156114aa576114a9612482565b5b036114e15786606001518360600151146114cf576114ca888885886119e9565b6114da565b6114d988886117f8565b5b90506115fc565b6002808111156114f4576114f3612482565b5b8360000151600281111561150b5761150a612482565b5b036115fb57611518611ec8565b600180878a60600151901c160361158d576115458989866040015160018a6115409190612c21565b611367565b92506040518060a0016040528060028081111561156557611564612482565b5b81526020018560200151815260200184815260200160008152602001600081525090506115ed565b6115a98989866020015160018a6115a49190612c21565b611367565b92506040518060a001604052806002808111156115c9576115c8612482565b5b81526020018481526020018560400151815260200160008152602001600081525090505b6115f789826117f8565b9150505b5b5b809350505050949350505050565b600080600085600101805490500361162957600080915091506117f0565b6000806001876001018054905061164091906127b8565b905060005b8183116117e5576002838361165a9190612c21565b6116649190612cf0565b905060006116be8960010183815481106116815761168061281b565b5b9060005260206000209060030201604051806060016040529081600082015481526020016001820154815260200160028201548152505088611be8565b905087810361178a575b600189600101805490506116dc91906127b8565b82101561177a5760006117478a6001016001856116f99190612c21565b8154811061170a5761170961281b565b5b9060005260206000209060030201604051806060016040529081600082015481526020016001820154815260200160028201548152505089611be8565b905088810361176357828061175b90612922565b935050611774565b8260019650965050505050506117f0565b506116c8565b81600195509550505050506117f0565b808811156117a65760018261179f9190612c21565b93506117df565b80881080156117b55750600082115b156117ce576001826117c791906127b8565b92506117de565b60008095509550505050506117f0565b5b50611645565b816001945094505050505b935093915050565b60008061180483611c9a565b90506000600281111561181a57611819612482565b5b84600001600083815260200190815260200160002060000160009054906101000a900460ff16600281111561185257611851612482565b5b1461196d578260000151600281111561186e5761186d612482565b5b84600001600083815260200190815260200160002060000160009054906101000a900460ff1660028111156118a6576118a5612482565b5b146118b4576118b3612aae565b5b826020015184600001600083815260200190815260200160002060010154146118e0576118df612aae565b5b8260400151846000016000838152602001908152602001600020600201541461190c5761190b612aae565b5b8260600151846000016000838152602001908152602001600020600301541461193857611937612aae565b5b8260800151846000016000838152602001908152602001600020600401541461196457611963612aae565b5b809150506119e3565b8284600001600083815260200190815260200160002060008201518160000160006101000a81548160ff021916908360028111156119ae576119ad612482565b5b021790555060208201518160010155604082015181600201556060820151816003015560808201518160040155905050809150505b92915050565b600084600301548210611a31576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611a2890612ca1565b60405180910390fd5b611a39611ec8565b6000600180858860600151901c161490506000600180868860600151901c1614905080151582151503611b1f576000611a8089898960018a611a7b9190612c21565b6119e9565b90508215611acb576040518060a00160405280600280811115611aa657611aa5612482565b5b8152602001600081526020018281526020016000815260200160008152509350611b0a565b6040518060a00160405280600280811115611ae957611ae8612482565b5b81526020018281526020016000815260200160008152602001600081525093505b611b1489856117f8565b945050505050611be0565b8115611b77576040518060a00160405280600280811115611b4357611b42612482565b5b8152602001611b5188611c9a565b8152602001611b5f89611c9a565b81526020016000815260200160008152509250611bc5565b6040518060a00160405280600280811115611b9557611b94612482565b5b8152602001611ba389611c9a565b8152602001611bb188611c9a565b815260200160008152602001600081525092505b611bcf88886117f8565b50611bda88846117f8565b93505050505b949350505050565b6000600180811115611bfd57611bfc612482565b5b826001811115611c1057611c0f612482565b5b03611c215782604001519050611c94565b60006001811115611c3557611c34612482565b5b826001811115611c4857611c47612482565b5b03611c595782602001519050611c94565b6040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611c8b90612d6d565b60405180910390fd5b92915050565b6000806000905060016002811115611cb557611cb4612482565b5b83600001516002811115611ccc57611ccb612482565b5b03611d795760006040518060600160405280856060015181526020018560800151815260200160018152509050735bc89782d5ebf62663df7ce5fb4bc7408926a2406325cc70e8826040518263ffffffff1660e01b8152600401611d309190612e11565b602060405180830381865af4158015611d4d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611d719190612e41565b915050611e40565b600280811115611d8c57611d8b612482565b5b83600001516002811115611da357611da2612482565b5b03611e3f577372f721d9d5f91353b505207c63b56cf3d9447edb6329a5f2f660405180604001604052808660200151815260200186604001518152506040518263ffffffff1660e01b8152600401611dfb9190612ef2565b602060405180830381865af4158015611e18573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611e3c9190612e41565b90505b5b80915050919050565b6040518061010001604052806000815260200160001515815260200160608152602001600081526020016000815260200160001515815260200160008152602001600081525090565b6040518060c001604052806000815260200160008152602001600081526020016000815260200160008152602001600081525090565b6040518060a0016040528060006002811115611ee757611ee6612482565b5b8152602001600081526020016000815260200160008152602001600081525090565b600080fd5b6000819050919050565b611f2181611f0e565b8114611f2c57600080fd5b50565b600081359050611f3e81611f18565b92915050565b6000819050919050565b611f5781611f44565b8114611f6257600080fd5b50565b600081359050611f7481611f4e565b92915050565b60008060408385031215611f9157611f90611f09565b5b6000611f9f85828601611f2f565b9250506020611fb085828601611f65565b9150509250929050565b611fc381611f44565b82525050565b6000602082019050611fde6000830184611fba565b92915050565b600080600060608486031215611ffd57611ffc611f09565b5b600061200b86828701611f2f565b935050602061201c86828701611f65565b925050604061202d86828701611f65565b9150509250925092565b61204081611f44565b82525050565b60008115159050919050565b61205b81612046565b82525050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b60006120998383612037565b60208301905092915050565b6000602082019050919050565b60006120bd82612061565b6120c7818561206c565b93506120d28361207d565b8060005b838110156121035781516120ea888261208d565b97506120f5836120a5565b9250506001810190506120d6565b5085935050505092915050565b6000610100830160008301516121296000860182612037565b50602083015161213c6020860182612052565b506040830151848203604086015261215482826120b2565b91505060608301516121696060860182612037565b50608083015161217c6080860182612037565b5060a083015161218f60a0860182612052565b5060c08301516121a260c0860182612037565b5060e08301516121b560e0860182612037565b508091505092915050565b600060208201905081810360008301526121da8184612110565b905092915050565b60c0820160008201516121f86000850182612037565b50602082015161220b6020850182612037565b50604082015161221e6040850182612037565b5060608201516122316060850182612037565b5060808201516122446080850182612037565b5060a082015161225760a0850182612037565b50505050565b600060c08201905061227260008301846121e2565b92915050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b60c0820160008201516122ba6000850182612037565b5060208201516122cd6020850182612037565b5060408201516122e06040850182612037565b5060608201516122f36060850182612037565b5060808201516123066080850182612037565b5060a082015161231960a0850182612037565b50505050565b600061232b83836122a4565b60c08301905092915050565b6000602082019050919050565b600061234f82612278565b6123598185612283565b935061236483612294565b8060005b8381101561239557815161237c888261231f565b975061238783612337565b925050600181019050612368565b5085935050505092915050565b600060208201905081810360008301526123bc8184612344565b905092915050565b6000602082840312156123da576123d9611f09565b5b60006123e884828501611f2f565b91505092915050565b6000806000806080858703121561240b5761240a611f09565b5b600061241987828801611f2f565b945050602061242a87828801611f65565b935050604061243b87828801611f65565b925050606061244c87828801611f65565b91505092959194509250565b61246181612046565b82525050565b600060208201905061247c6000830184612458565b92915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b600381106124c2576124c1612482565b5b50565b60008190506124d3826124b1565b919050565b60006124e3826124c5565b9050919050565b6124f3816124d8565b82525050565b60a08201600082015161250f60008501826124ea565b5060208201516125226020850182612037565b5060408201516125356040850182612037565b5060608201516125486060850182612037565b50608082015161255b6080850182612037565b50505050565b600060a08201905061257660008301846124f9565b92915050565b600082825260208201905092915050565b7f4d6178206465707468206d7573742062652067726561746572207468616e207a60008201527f65726f0000000000000000000000000000000000000000000000000000000000602082015250565b60006125e960238361257c565b91506125f48261258d565b604082019050919050565b60006020820190508181036000830152612618816125dc565b9050919050565b7f4d61782064657074682063616e206f6e6c7920626520696e6372656173656400600082015250565b6000612655601f8361257c565b91506126608261261f565b602082019050919050565b6000602082019050818103600083015261268481612648565b9050919050565b7f4d61782064657074682069732067726561746572207468616e2068617264206360008201527f6170000000000000000000000000000000000000000000000000000000000000602082015250565b60006126e760228361257c565b91506126f28261268b565b604082019050919050565b60006020820190508181036000830152612716816126da565b9050919050565b7f4e6f206675747572652074696d657374616d707320616c6c6f77656400000000600082015250565b6000612753601c8361257c565b915061275e8261271d565b602082019050919050565b6000602082019050818103600083015261278281612746565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60006127c382611f44565b91506127ce83611f44565b92508282039050818111156127e6576127e5612789565b5b92915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f526f6f7420646f6573206e6f7420657869737400000000000000000000000000600082015250565b600061288060138361257c565b915061288b8261284a565b602082019050919050565b600060208201905081810360008301526128af81612873565b9050919050565b7f496e76616c6964206e6f64652074797065000000000000000000000000000000600082015250565b60006128ec60118361257c565b91506128f7826128b6565b602082019050919050565b6000602082019050818103600083015261291b816128df565b9050919050565b600061292d82611f44565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361295f5761295e612789565b5b600182019050919050565b7f536d74206973206e6f7420696e697469616c697a656400000000000000000000600082015250565b60006129a060168361257c565b91506129ab8261296a565b602082019050919050565b600060208201905081810360008301526129cf81612993565b9050919050565b7f536d7420697320616c726561647920696e697469616c697a6564000000000000600082015250565b6000612a0c601a8361257c565b9150612a17826129d6565b602082019050919050565b60006020820190508181036000830152612a3b816129ff565b9050919050565b7f4e6f2066757475726520626c6f636b7320616c6c6f7765640000000000000000600082015250565b6000612a7860188361257c565b9150612a8382612a42565b602082019050919050565b60006020820190508181036000830152612aa781612a6b565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052600160045260246000fd5b7f4c656e6774682073686f756c642062652067726561746572207468616e203000600082015250565b6000612b13601f8361257c565b9150612b1e82612add565b602082019050919050565b60006020820190508181036000830152612b4281612b06565b9050919050565b7f4c656e677468206c696d69742065786365656465640000000000000000000000600082015250565b6000612b7f60158361257c565b9150612b8a82612b49565b602082019050919050565b60006020820190508181036000830152612bae81612b72565b9050919050565b7f537461727420696e646578206f7574206f6620626f756e647300000000000000600082015250565b6000612beb60198361257c565b9150612bf682612bb5565b602082019050919050565b60006020820190508181036000830152612c1a81612bde565b9050919050565b6000612c2c82611f44565b9150612c3783611f44565b9250828201905080821115612c4f57612c4e612789565b5b92915050565b7f4d61782064657074682072656163686564000000000000000000000000000000600082015250565b6000612c8b60118361257c565b9150612c9682612c55565b602082019050919050565b60006020820190508181036000830152612cba81612c7e565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b6000612cfb82611f44565b9150612d0683611f44565b925082612d1657612d15612cc1565b5b828204905092915050565b7f496e76616c696420736561726368207479706500000000000000000000000000600082015250565b6000612d5760138361257c565b9150612d6282612d21565b602082019050919050565b60006020820190508181036000830152612d8681612d4a565b9050919050565b600060039050919050565b600081905092915050565b6000819050919050565b6000602082019050919050565b612dc381612d8d565b612dcd8184612d98565b9250612dd882612da3565b8060005b83811015612e09578151612df0878261208d565b9650612dfb83612dad565b925050600181019050612ddc565b505050505050565b6000606082019050612e266000830184612dba565b92915050565b600081519050612e3b81611f4e565b92915050565b600060208284031215612e5757612e56611f09565b5b6000612e6584828501612e2c565b91505092915050565b600060029050919050565b600081905092915050565b6000819050919050565b6000602082019050919050565b612ea481612e6e565b612eae8184612e79565b9250612eb982612e84565b8060005b83811015612eea578151612ed1878261208d565b9650612edc83612e8e565b925050600181019050612ebd565b505050505050565b6000604082019050612f076000830184612e9b565b9291505056fea26469706673582212205abbe031e31994d755b34f8c95303d957ba6b4e7ac64a9fa5d1846ab9c21a73b64736f6c634300081b0033

Deployed Bytecode

0x73682364078e26c1626abd2b95109d2019e241f0f630146080604052600436106101405760003560e01c806379f97125116100c2578063a751be2411610086578063a751be24146103f5578063c1d29f0114610413578063dc9a7c8c1461043c578063dea7633a1461046c578063e170cf6e1461049c578063ec145108146104cc57610140565b806379f971251461030c578063893f99f31461033c57806391761b751461036c57806392f5b06c1461039c5780639e43b813146103cc57610140565b806340a73d981161010957806340a73d981461022e5780635db40cda1461024c57806362e8f2151461027c578063792a470f146102ac57806379c17a96146102dc57610140565b806278f030146101455780630912610a14610175578063138271361461019e57806317c850f0146101ce57806321d60953146101fe575b600080fd5b61015f600480360381019061015a9190611f7a565b6104fc565b60405161016c9190611fc9565b60405180910390f35b81801561018157600080fd5b5061019c60048036038101906101979190611f7a565b61051f565b005b6101b860048036038101906101b39190611fe4565b6105fa565b6040516101c591906121c0565b60405180910390f35b6101e860048036038101906101e39190611f7a565b610629565b6040516101f5919061225d565b60405180910390f35b61021860048036038101906102139190611fe4565b610688565b60405161022591906123a2565b60405180910390f35b610236610765565b6040516102439190611fc9565b60405180910390f35b61026660048036038101906102619190611f7a565b61076b565b60405161027391906121c0565b60405180910390f35b610296600480360381019061029191906123c4565b61078e565b6040516102a39190611fc9565b60405180910390f35b6102c660048036038101906102c19190611fe4565b61079f565b6040516102d391906121c0565b60405180910390f35b6102f660048036038101906102f19190611fe4565b6107ce565b60405161030391906121c0565b60405180910390f35b610326600480360381019061032191906123c4565b610afa565b6040516103339190611fc9565b60405180910390f35b610356600480360381019061035191906123c4565b610b88565b6040516103639190611fc9565b60405180910390f35b610386600480360381019061038191906123f1565b610b96565b60405161039391906123a2565b60405180910390f35b6103b660048036038101906103b19190611f7a565b610cf5565b6040516103c39190612467565b60405180910390f35b8180156103d857600080fd5b506103f360048036038101906103ee9190611f7a565b610d1a565b005b6103fd610d9c565b60405161040a9190611fc9565b60405180910390f35b81801561041f57600080fd5b5061043a60048036038101906104359190611fe4565b610da2565b005b61045660048036038101906104519190611f7a565b610e5e565b604051610463919061225d565b60405180910390f35b61048660048036038101906104819190611f7a565b610ebd565b604051610493919061225d565b60405180910390f35b6104b660048036038101906104b19190611f7a565b610f71565b6040516104c39190612561565b60405180910390f35b6104e660048036038101906104e191906123c4565b611004565b6040516104f39190612467565b60405180910390f35b600082600201600083815260200190815260200160002080549050905092915050565b60008111610562576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610559906125ff565b60405180910390fd5b816003015481116105a8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161059f9061266b565b60405180910390fd5b6101008111156105ed576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016105e4906126fd565b60405180910390fd5b8082600301819055505050565b610602611e49565b600061060e8584610629565b905061061f858583600001516107ce565b9150509392505050565b610631611e92565b42821115610674576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161066b90612769565b60405180910390fd5b6106808383600061101f565b905092915050565b60606000806106a2866001018054905086866103e8611066565b91509150600082826106b491906127b8565b67ffffffffffffffff8111156106cd576106cc6127ec565b5b60405190808252806020026020018201604052801561070657816020015b6106f3611e92565b8152602001906001900390816106eb5790505b50905060008390505b8281101561075757610721888261115d565b82858361072e91906127b8565b8151811061073f5761073e61281b565b5b6020026020010181905250808060010191505061070f565b508093505050509392505050565b6103e881565b610773611e49565b610786838361078186610afa565b6107ce565b905092915050565b600081600101805490509050919050565b6107a7611e49565b60006107b38584610e5e565b90506107c4858583600001516107ce565b9150509392505050565b6107d6611e49565b83826107e28282610cf5565b610821576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161081890612896565b60405180910390fd5b6000866003015467ffffffffffffffff811115610841576108406127ec565b5b60405190808252806020026020018201604052801561086f5781602001602082028036833780820191505090505b50905060005b87600301548110156108af5760008282815181106108965761089561281b565b5b6020026020010181815250508080600101915050610875565b5060006040518061010001604052808781526020016000151581526020018381526020018881526020016000815260200160001515815260200160008152602001600081525090506000869050610904611ec8565b60005b8a600301548111610ae95761091c8b84610f71565b91506000600281111561093257610931612482565b5b8260000151600281111561094957610948612482565b5b0315610ae9576001600281111561096357610962612482565b5b8260000151600281111561097a57610979612482565b5b036109f25783606001518260600151036109b25760018460200190151590811515815250508160800151846080018181525050610ae9565b60018460a001901515908115158152505081606001518460c001818152505081608001518460e00181815250508160800151846080018181525050610ae9565b600280811115610a0557610a04612482565b5b82600001516002811115610a1c57610a1b612482565b5b03610a9b57600180828660600151901c1603610a665781604001519250816020015184604001518281518110610a5557610a5461281b565b5b602002602001018181525050610a96565b81602001519250816040015184604001518281518110610a8957610a8861281b565b5b6020026020010181815250505b610ad6565b6040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610acd90612902565b60405180910390fd5b8080610ae190612922565b915050610907565b508296505050505050509392505050565b600081610b0681611004565b610b45576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610b3c906129b6565b60405180910390fd5b8260010160018460010180549050610b5d91906127b8565b81548110610b6e57610b6d61281b565b5b906000526020600020906003020160000154915050919050565b600081600301549050919050565b60608484610ba48282610cf5565b610be3576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610bda90612896565b60405180910390fd5b60008760020160008881526020019081526020016000209050600080610c11838054905089896103e8611066565b9150915060008282610c2391906127b8565b67ffffffffffffffff811115610c3c57610c3b6127ec565b5b604051908082528060200260200182016040528015610c7557816020015b610c62611e92565b815260200190600190039081610c5a5790505b50905060008390505b82811015610ce357610cad8c868381548110610c9d57610c9c61281b565b5b906000526020600020015461115d565b828583610cba91906127b8565b81518110610ccb57610cca61281b565b5b60200260200101819052508080600101915050610c7e565b50809650505050505050949350505050565b6000808360020160008481526020019081526020016000208054905011905092915050565b610d2382611004565b15610d63576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610d5a90612a22565b60405180910390fd5b610d6d828261051f565b610d7b8260008060006112aa565b60018260040160006101000a81548160ff0219169083151502179055505050565b61010081565b82610dac81611004565b610deb576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610de2906129b6565b60405180910390fd5b60006040518060a0016040528060016002811115610e0c57610e0b612482565b5b815260200160008152602001600081526020018581526020018481525090506000610e3686610afa565b90506000610e478784846000611367565b9050610e55878242436112aa565b50505050505050565b610e66611e92565b43821115610ea9576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610ea090612a8e565b60405180910390fd5b610eb58383600161101f565b905092915050565b610ec5611e92565b8282610ed18282610cf5565b610f10576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610f0790612896565b60405180910390fd5b6000856002016000868152602001908152602001600020905060008160018380549050610f3d91906127b8565b81548110610f4e57610f4d61281b565b5b90600052602060002001549050610f65878261115d565b94505050505092915050565b610f79611ec8565b8260000160008381526020019081526020016000206040518060a00160405290816000820160009054906101000a900460ff166002811115610fbe57610fbd612482565b5b6002811115610fd057610fcf612482565b5b8152602001600182015481526020016002820154815260200160038201548152602001600482015481525050905092915050565b60008160040160009054906101000a900460ff169050919050565b611027611e92565b60008061103f85858861160b9092919063ffffffff16565b915091508061105157611050612aae565b5b61105b868361115d565b925050509392505050565b600080600084116110ac576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016110a390612b29565b60405180910390fd5b828411156110ef576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016110e690612b95565b60405180910390fd5b858510611131576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161112890612c01565b60405180910390fd5b6000848661113f9190612c21565b90508681111561114d578690505b8581925092505094509492505050565b611165611e92565b60006001846001018054905061117b91906127b8565b8314905060008460010184815481106111975761119661281b565b5b906000526020600020906003020190506040518060c0016040528082600001548152602001836111fa57866001016001876111d29190612c21565b815481106111e3576111e261281b565b5b9060005260206000209060030201600001546111fd565b60005b8152602001826001015481526020018361124a57866001016001876112229190612c21565b815481106112335761123261281b565b5b90600052602060002090600302016001015461124d565b60005b8152602001826002015481526020018361129a57866001016001876112729190612c21565b815481106112835761128261281b565b5b90600052602060002090600302016002015461129d565b60005b8152509250505092915050565b83600101604051806060016040528085815260200184815260200183815250908060018154018082558091505060019003906000526020600020906003020160009091909190915060008201518160000155602082015181600101556040820151816002015550508360020160008481526020019081526020016000206001856001018054905061133b91906127b8565b908060018154018082558091505060019003906000526020600020016000909190919091505550505050565b600084600301548211156113b0576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016113a790612ca1565b60405180910390fd5b60008560000160008581526020019081526020016000206040518060a00160405290816000820160009054906101000a900460ff1660028111156113f7576113f6612482565b5b600281111561140957611408612482565b5b81526020016001820154815260200160028201548152602001600382015481526020016004820154815250509050600080600090506000600281111561145257611451612482565b5b8360000151600281111561146957611468612482565b5b0361147f5761147888886117f8565b90506115fd565b6001600281111561149357611492612482565b5b836000015160028111156114aa576114a9612482565b5b036114e15786606001518360600151146114cf576114ca888885886119e9565b6114da565b6114d988886117f8565b5b90506115fc565b6002808111156114f4576114f3612482565b5b8360000151600281111561150b5761150a612482565b5b036115fb57611518611ec8565b600180878a60600151901c160361158d576115458989866040015160018a6115409190612c21565b611367565b92506040518060a0016040528060028081111561156557611564612482565b5b81526020018560200151815260200184815260200160008152602001600081525090506115ed565b6115a98989866020015160018a6115a49190612c21565b611367565b92506040518060a001604052806002808111156115c9576115c8612482565b5b81526020018481526020018560400151815260200160008152602001600081525090505b6115f789826117f8565b9150505b5b5b809350505050949350505050565b600080600085600101805490500361162957600080915091506117f0565b6000806001876001018054905061164091906127b8565b905060005b8183116117e5576002838361165a9190612c21565b6116649190612cf0565b905060006116be8960010183815481106116815761168061281b565b5b9060005260206000209060030201604051806060016040529081600082015481526020016001820154815260200160028201548152505088611be8565b905087810361178a575b600189600101805490506116dc91906127b8565b82101561177a5760006117478a6001016001856116f99190612c21565b8154811061170a5761170961281b565b5b9060005260206000209060030201604051806060016040529081600082015481526020016001820154815260200160028201548152505089611be8565b905088810361176357828061175b90612922565b935050611774565b8260019650965050505050506117f0565b506116c8565b81600195509550505050506117f0565b808811156117a65760018261179f9190612c21565b93506117df565b80881080156117b55750600082115b156117ce576001826117c791906127b8565b92506117de565b60008095509550505050506117f0565b5b50611645565b816001945094505050505b935093915050565b60008061180483611c9a565b90506000600281111561181a57611819612482565b5b84600001600083815260200190815260200160002060000160009054906101000a900460ff16600281111561185257611851612482565b5b1461196d578260000151600281111561186e5761186d612482565b5b84600001600083815260200190815260200160002060000160009054906101000a900460ff1660028111156118a6576118a5612482565b5b146118b4576118b3612aae565b5b826020015184600001600083815260200190815260200160002060010154146118e0576118df612aae565b5b8260400151846000016000838152602001908152602001600020600201541461190c5761190b612aae565b5b8260600151846000016000838152602001908152602001600020600301541461193857611937612aae565b5b8260800151846000016000838152602001908152602001600020600401541461196457611963612aae565b5b809150506119e3565b8284600001600083815260200190815260200160002060008201518160000160006101000a81548160ff021916908360028111156119ae576119ad612482565b5b021790555060208201518160010155604082015181600201556060820151816003015560808201518160040155905050809150505b92915050565b600084600301548210611a31576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611a2890612ca1565b60405180910390fd5b611a39611ec8565b6000600180858860600151901c161490506000600180868860600151901c1614905080151582151503611b1f576000611a8089898960018a611a7b9190612c21565b6119e9565b90508215611acb576040518060a00160405280600280811115611aa657611aa5612482565b5b8152602001600081526020018281526020016000815260200160008152509350611b0a565b6040518060a00160405280600280811115611ae957611ae8612482565b5b81526020018281526020016000815260200160008152602001600081525093505b611b1489856117f8565b945050505050611be0565b8115611b77576040518060a00160405280600280811115611b4357611b42612482565b5b8152602001611b5188611c9a565b8152602001611b5f89611c9a565b81526020016000815260200160008152509250611bc5565b6040518060a00160405280600280811115611b9557611b94612482565b5b8152602001611ba389611c9a565b8152602001611bb188611c9a565b815260200160008152602001600081525092505b611bcf88886117f8565b50611bda88846117f8565b93505050505b949350505050565b6000600180811115611bfd57611bfc612482565b5b826001811115611c1057611c0f612482565b5b03611c215782604001519050611c94565b60006001811115611c3557611c34612482565b5b826001811115611c4857611c47612482565b5b03611c595782602001519050611c94565b6040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611c8b90612d6d565b60405180910390fd5b92915050565b6000806000905060016002811115611cb557611cb4612482565b5b83600001516002811115611ccc57611ccb612482565b5b03611d795760006040518060600160405280856060015181526020018560800151815260200160018152509050735bc89782d5ebf62663df7ce5fb4bc7408926a2406325cc70e8826040518263ffffffff1660e01b8152600401611d309190612e11565b602060405180830381865af4158015611d4d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611d719190612e41565b915050611e40565b600280811115611d8c57611d8b612482565b5b83600001516002811115611da357611da2612482565b5b03611e3f577372f721d9d5f91353b505207c63b56cf3d9447edb6329a5f2f660405180604001604052808660200151815260200186604001518152506040518263ffffffff1660e01b8152600401611dfb9190612ef2565b602060405180830381865af4158015611e18573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611e3c9190612e41565b90505b5b80915050919050565b6040518061010001604052806000815260200160001515815260200160608152602001600081526020016000815260200160001515815260200160008152602001600081525090565b6040518060c001604052806000815260200160008152602001600081526020016000815260200160008152602001600081525090565b6040518060a0016040528060006002811115611ee757611ee6612482565b5b8152602001600081526020016000815260200160008152602001600081525090565b600080fd5b6000819050919050565b611f2181611f0e565b8114611f2c57600080fd5b50565b600081359050611f3e81611f18565b92915050565b6000819050919050565b611f5781611f44565b8114611f6257600080fd5b50565b600081359050611f7481611f4e565b92915050565b60008060408385031215611f9157611f90611f09565b5b6000611f9f85828601611f2f565b9250506020611fb085828601611f65565b9150509250929050565b611fc381611f44565b82525050565b6000602082019050611fde6000830184611fba565b92915050565b600080600060608486031215611ffd57611ffc611f09565b5b600061200b86828701611f2f565b935050602061201c86828701611f65565b925050604061202d86828701611f65565b9150509250925092565b61204081611f44565b82525050565b60008115159050919050565b61205b81612046565b82525050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b60006120998383612037565b60208301905092915050565b6000602082019050919050565b60006120bd82612061565b6120c7818561206c565b93506120d28361207d565b8060005b838110156121035781516120ea888261208d565b97506120f5836120a5565b9250506001810190506120d6565b5085935050505092915050565b6000610100830160008301516121296000860182612037565b50602083015161213c6020860182612052565b506040830151848203604086015261215482826120b2565b91505060608301516121696060860182612037565b50608083015161217c6080860182612037565b5060a083015161218f60a0860182612052565b5060c08301516121a260c0860182612037565b5060e08301516121b560e0860182612037565b508091505092915050565b600060208201905081810360008301526121da8184612110565b905092915050565b60c0820160008201516121f86000850182612037565b50602082015161220b6020850182612037565b50604082015161221e6040850182612037565b5060608201516122316060850182612037565b5060808201516122446080850182612037565b5060a082015161225760a0850182612037565b50505050565b600060c08201905061227260008301846121e2565b92915050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b60c0820160008201516122ba6000850182612037565b5060208201516122cd6020850182612037565b5060408201516122e06040850182612037565b5060608201516122f36060850182612037565b5060808201516123066080850182612037565b5060a082015161231960a0850182612037565b50505050565b600061232b83836122a4565b60c08301905092915050565b6000602082019050919050565b600061234f82612278565b6123598185612283565b935061236483612294565b8060005b8381101561239557815161237c888261231f565b975061238783612337565b925050600181019050612368565b5085935050505092915050565b600060208201905081810360008301526123bc8184612344565b905092915050565b6000602082840312156123da576123d9611f09565b5b60006123e884828501611f2f565b91505092915050565b6000806000806080858703121561240b5761240a611f09565b5b600061241987828801611f2f565b945050602061242a87828801611f65565b935050604061243b87828801611f65565b925050606061244c87828801611f65565b91505092959194509250565b61246181612046565b82525050565b600060208201905061247c6000830184612458565b92915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b600381106124c2576124c1612482565b5b50565b60008190506124d3826124b1565b919050565b60006124e3826124c5565b9050919050565b6124f3816124d8565b82525050565b60a08201600082015161250f60008501826124ea565b5060208201516125226020850182612037565b5060408201516125356040850182612037565b5060608201516125486060850182612037565b50608082015161255b6080850182612037565b50505050565b600060a08201905061257660008301846124f9565b92915050565b600082825260208201905092915050565b7f4d6178206465707468206d7573742062652067726561746572207468616e207a60008201527f65726f0000000000000000000000000000000000000000000000000000000000602082015250565b60006125e960238361257c565b91506125f48261258d565b604082019050919050565b60006020820190508181036000830152612618816125dc565b9050919050565b7f4d61782064657074682063616e206f6e6c7920626520696e6372656173656400600082015250565b6000612655601f8361257c565b91506126608261261f565b602082019050919050565b6000602082019050818103600083015261268481612648565b9050919050565b7f4d61782064657074682069732067726561746572207468616e2068617264206360008201527f6170000000000000000000000000000000000000000000000000000000000000602082015250565b60006126e760228361257c565b91506126f28261268b565b604082019050919050565b60006020820190508181036000830152612716816126da565b9050919050565b7f4e6f206675747572652074696d657374616d707320616c6c6f77656400000000600082015250565b6000612753601c8361257c565b915061275e8261271d565b602082019050919050565b6000602082019050818103600083015261278281612746565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60006127c382611f44565b91506127ce83611f44565b92508282039050818111156127e6576127e5612789565b5b92915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f526f6f7420646f6573206e6f7420657869737400000000000000000000000000600082015250565b600061288060138361257c565b915061288b8261284a565b602082019050919050565b600060208201905081810360008301526128af81612873565b9050919050565b7f496e76616c6964206e6f64652074797065000000000000000000000000000000600082015250565b60006128ec60118361257c565b91506128f7826128b6565b602082019050919050565b6000602082019050818103600083015261291b816128df565b9050919050565b600061292d82611f44565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361295f5761295e612789565b5b600182019050919050565b7f536d74206973206e6f7420696e697469616c697a656400000000000000000000600082015250565b60006129a060168361257c565b91506129ab8261296a565b602082019050919050565b600060208201905081810360008301526129cf81612993565b9050919050565b7f536d7420697320616c726561647920696e697469616c697a6564000000000000600082015250565b6000612a0c601a8361257c565b9150612a17826129d6565b602082019050919050565b60006020820190508181036000830152612a3b816129ff565b9050919050565b7f4e6f2066757475726520626c6f636b7320616c6c6f7765640000000000000000600082015250565b6000612a7860188361257c565b9150612a8382612a42565b602082019050919050565b60006020820190508181036000830152612aa781612a6b565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052600160045260246000fd5b7f4c656e6774682073686f756c642062652067726561746572207468616e203000600082015250565b6000612b13601f8361257c565b9150612b1e82612add565b602082019050919050565b60006020820190508181036000830152612b4281612b06565b9050919050565b7f4c656e677468206c696d69742065786365656465640000000000000000000000600082015250565b6000612b7f60158361257c565b9150612b8a82612b49565b602082019050919050565b60006020820190508181036000830152612bae81612b72565b9050919050565b7f537461727420696e646578206f7574206f6620626f756e647300000000000000600082015250565b6000612beb60198361257c565b9150612bf682612bb5565b602082019050919050565b60006020820190508181036000830152612c1a81612bde565b9050919050565b6000612c2c82611f44565b9150612c3783611f44565b9250828201905080821115612c4f57612c4e612789565b5b92915050565b7f4d61782064657074682072656163686564000000000000000000000000000000600082015250565b6000612c8b60118361257c565b9150612c9682612c55565b602082019050919050565b60006020820190508181036000830152612cba81612c7e565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b6000612cfb82611f44565b9150612d0683611f44565b925082612d1657612d15612cc1565b5b828204905092915050565b7f496e76616c696420736561726368207479706500000000000000000000000000600082015250565b6000612d5760138361257c565b9150612d6282612d21565b602082019050919050565b60006020820190508181036000830152612d8681612d4a565b9050919050565b600060039050919050565b600081905092915050565b6000819050919050565b6000602082019050919050565b612dc381612d8d565b612dcd8184612d98565b9250612dd882612da3565b8060005b83811015612e09578151612df0878261208d565b9650612dfb83612dad565b925050600181019050612ddc565b505050505050565b6000606082019050612e266000830184612dba565b92915050565b600081519050612e3b81611f4e565b92915050565b600060208284031215612e5757612e56611f09565b5b6000612e6584828501612e2c565b91505092915050565b600060029050919050565b600081905092915050565b6000819050919050565b6000602082019050919050565b612ea481612e6e565b612eae8184612e79565b9250612eb982612e84565b8060005b83811015612eea578151612ed1878261208d565b9650612edc83612e8e565b925050600181019050612ebd565b505050505050565b6000604082019050612f076000830184612e9b565b9291505056fea26469706673582212205abbe031e31994d755b34f8c95303d957ba6b4e7ac64a9fa5d1846ab9c21a73b64736f6c634300081b0033

Block Transaction Gas Used Reward
view all blocks sequenced

Block Uncle Number Difficulty Gas Used Reward
View All Uncles
Loading...
Loading
Loading...
Loading

Validator Index Block Amount
View All Withdrawals

Transaction 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.