UNPKG

@venusprotocol/governance-contracts

Version:
47 lines 86.2 kB
{ "language": "Solidity", "sources": { "@venusprotocol/solidity-utilities/contracts/validators.sol": { "content": "// SPDX-License-Identifier: BSD-3-Clause\npragma solidity 0.8.25;\n\n/// @notice Thrown if the supplied address is a zero address where it is not allowed\nerror ZeroAddressNotAllowed();\n\n/// @notice Thrown if the supplied value is 0 where it is not allowed\nerror ZeroValueNotAllowed();\n\n/// @notice Checks if the provided address is nonzero, reverts otherwise\n/// @param address_ Address to check\n/// @custom:error ZeroAddressNotAllowed is thrown if the provided address is a zero address\nfunction ensureNonzeroAddress(address address_) pure {\n if (address_ == address(0)) {\n revert ZeroAddressNotAllowed();\n }\n}\n\n/// @notice Checks if the provided value is nonzero, reverts otherwise\n/// @param value_ Value to check\n/// @custom:error ZeroValueNotAllowed is thrown if the provided value is 0\nfunction ensureNonzeroValue(uint256 value_) pure {\n if (value_ == 0) {\n revert ZeroValueNotAllowed();\n }\n}\n" }, "contracts/Cross-chain/interfaces/IDataWarehouse.sol": { "content": "// SPDX-License-Identifier: Unlicense\npragma solidity ^0.8.0;\n\nimport {StateProofVerifier} from '../libs/StateProofVerifier.sol';\n\n/**\n * @title IDataWarehouse\n * @author BGD Labs\n * @notice interface containing the methods definitions of the DataWarehouse contract\n */\ninterface IDataWarehouse {\n /**\n * @notice event emitted when a storage root has been processed successfully\n * @param caller address that called the processStorageRoot method\n * @param account address where the root is generated\n * @param blockHash hash of the block where the root was generated\n */\n event StorageRootProcessed(\n address indexed caller,\n address indexed account,\n bytes32 indexed blockHash\n );\n\n /**\n * @notice event emitted when a storage root has been processed successfully\n * @param caller address that called the processStorageSlot method\n * @param account address where the slot is processed\n * @param blockHash hash of the block where the storage proof was generated\n * @param slot storage location to search\n * @param value storage information on the specified location\n */\n event StorageSlotProcessed(\n address indexed caller,\n address indexed account,\n bytes32 indexed blockHash,\n bytes32 slot,\n uint256 value\n );\n\n /**\n * @notice method to get the storage roots of an account (token) in a certain block hash\n * @param account address of the token to get the storage roots from\n * @param blockHash hash of the block from where the roots are generated\n * @return state root hash of the account on the block hash specified\n */\n function getStorageRoots(\n address account,\n bytes32 blockHash\n ) external view returns (bytes32);\n\n /**\n * @notice method to process the storage root from an account on a block hash.\n * @param account address of the token to get the storage roots from\n * @param blockHash hash of the block from where the roots are generated\n * @param blockHeaderRLP rlp encoded block header. At same block where the block hash was taken\n * @param accountStateProofRLP rlp encoded account state proof, taken in same block as block hash\n * @return the storage root\n */\n function processStorageRoot(\n address account,\n bytes32 blockHash,\n bytes memory blockHeaderRLP,\n bytes memory accountStateProofRLP\n ) external returns (bytes32);\n\n /**\n * @notice method to get the storage value at a certain slot and block hash for a certain address\n * @param account address of the token to get the storage roots from\n * @param blockHash hash of the block from where the roots are generated\n * @param slot hash of the explicit storage placement where the value to get is found.\n * @param storageProof generated proof containing the storage, at block hash\n * @return an object containing the slot value at the specified storage slot\n */\n function getStorage(\n address account,\n bytes32 blockHash,\n bytes32 slot,\n bytes memory storageProof\n ) external view returns (StateProofVerifier.SlotValue memory);\n\n /**\n * @notice method to register the storage value at a certain slot and block hash for a certain address\n * @param account address of the token to get the storage roots from\n * @param blockHash hash of the block from where the roots are generated\n * @param slot hash of the explicit storage placement where the value to get is found.\n * @param storageProof generated proof containing the storage, at block hash\n */\n function processStorageSlot(\n address account,\n bytes32 blockHash,\n bytes32 slot,\n bytes calldata storageProof\n ) external;\n\n /**\n * @notice method to get the value from storage at a certain block hash, previously registered.\n * @param blockHash hash of the block from where the roots are generated\n * @param account address of the token to get the storage roots from\n * @param slot hash of the explicit storage placement where the value to get is found.\n * @return numeric slot value of the slot. The value must be decoded to get the actual stored information\n */\n function getRegisteredSlot(\n bytes32 blockHash,\n address account,\n bytes32 slot\n ) external view returns (uint256);\n}\n" }, "contracts/Cross-chain/libs/MerklePatriciaProofVerifier.sol": { "content": "// SPDX-License-Identifier: MIT\n\n/**\n * Copied from https://github.com/lidofinance/curve-merkle-oracle/blob/main/contracts/MerklePatriciaProofVerifier.sol\n */\npragma solidity ^0.8.0;\n\nimport {RLPReader} from \"./RLPReader.sol\";\n\nlibrary MerklePatriciaProofVerifier {\n using RLPReader for RLPReader.RLPItem;\n using RLPReader for bytes;\n\n /// @dev Validates a Merkle-Patricia-Trie proof.\n /// If the proof proves the inclusion of some key-value pair in the\n /// trie, the value is returned. Otherwise, i.e. if the proof proves\n /// the exclusion of a key from the trie, an empty byte array is\n /// returned.\n /// @param rootHash is the Keccak-256 hash of the root node of the MPT.\n /// @param path is the key of the node whose inclusion/exclusion we are\n /// proving.\n /// @param stack is the stack of MPT nodes (starting with the root) that\n /// need to be traversed during verification.\n /// @return value whose inclusion is proved or an empty byte array for\n /// a proof of exclusion\n function extractProofValue(\n bytes32 rootHash,\n bytes memory path,\n RLPReader.RLPItem[] memory stack\n ) internal pure returns (bytes memory value) {\n bytes memory mptKey = _decodeNibbles(path, 0);\n uint256 mptKeyOffset = 0;\n\n bytes32 nodeHashHash;\n RLPReader.RLPItem[] memory node;\n\n RLPReader.RLPItem memory rlpValue;\n\n if (stack.length == 0) {\n // Root hash of empty Merkle-Patricia-Trie\n require(\n rootHash ==\n 0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421\n );\n return new bytes(0);\n }\n\n // Traverse stack of nodes starting at root.\n for (uint256 i = 0; i < stack.length; i++) {\n // We use the fact that an rlp encoded list consists of some\n // encoding of its length plus the concatenation of its\n // *rlp-encoded* items.\n\n // The root node is hashed with Keccak-256 ...\n if (i == 0 && rootHash != stack[i].rlpBytesKeccak256()) {\n revert();\n }\n // ... whereas all other nodes are hashed with the MPT\n // hash function.\n if (i != 0 && nodeHashHash != _mptHashHash(stack[i])) {\n revert();\n }\n // We verified that stack[i] has the correct hash, so we\n // may safely decode it.\n node = stack[i].toList();\n\n if (node.length == 2) {\n // Extension or Leaf node\n\n bool isLeaf;\n bytes memory nodeKey;\n (isLeaf, nodeKey) = _merklePatriciaCompactDecode(node[0].toBytes());\n\n uint256 prefixLength = _sharedPrefixLength(\n mptKeyOffset,\n mptKey,\n nodeKey\n );\n mptKeyOffset += prefixLength;\n\n if (prefixLength < nodeKey.length) {\n // Proof claims divergent extension or leaf. (Only\n // relevant for proofs of exclusion.)\n // An Extension/Leaf node is divergent iff it \"skips\" over\n // the point at which a Branch node should have been had the\n // excluded key been included in the trie.\n // Example: Imagine a proof of exclusion for path [1, 4],\n // where the current node is a Leaf node with\n // path [1, 3, 3, 7]. For [1, 4] to be included, there\n // should have been a Branch node at [1] with a child\n // at 3 and a child at 4.\n\n // Sanity check\n if (i < stack.length - 1) {\n // divergent node must come last in proof\n revert();\n }\n\n return new bytes(0);\n }\n\n if (isLeaf) {\n // Sanity check\n if (i < stack.length - 1) {\n // leaf node must come last in proof\n revert();\n }\n\n if (mptKeyOffset < mptKey.length) {\n return new bytes(0);\n }\n\n rlpValue = node[1];\n return rlpValue.toBytes();\n } else {\n // extension\n // Sanity check\n if (i == stack.length - 1) {\n // shouldn't be at last level\n revert();\n }\n\n if (!node[1].isList()) {\n // rlp(child) was at least 32 bytes. node[1] contains\n // Keccak256(rlp(child)).\n nodeHashHash = node[1].payloadKeccak256();\n } else {\n // rlp(child) was less than 32 bytes. node[1] contains\n // rlp(child).\n nodeHashHash = node[1].rlpBytesKeccak256();\n }\n }\n } else if (node.length == 17) {\n // Branch node\n\n if (mptKeyOffset != mptKey.length) {\n // we haven't consumed the entire path, so we need to look at a child\n uint8 nibble = uint8(mptKey[mptKeyOffset]);\n mptKeyOffset += 1;\n if (nibble >= 16) {\n // each element of the path has to be a nibble\n revert();\n }\n\n if (_isEmptyBytesequence(node[nibble])) {\n // Sanity\n if (i != stack.length - 1) {\n // leaf node should be at last level\n revert();\n }\n\n return new bytes(0);\n } else if (!node[nibble].isList()) {\n nodeHashHash = node[nibble].payloadKeccak256();\n } else {\n nodeHashHash = node[nibble].rlpBytesKeccak256();\n }\n } else {\n // we have consumed the entire mptKey, so we need to look at what's contained in this node.\n\n // Sanity\n if (i != stack.length - 1) {\n // should be at last level\n revert();\n }\n\n return node[16].toBytes();\n }\n }\n }\n }\n\n /// @dev Computes the hash of the Merkle-Patricia-Trie hash of the RLP item.\n /// Merkle-Patricia-Tries use a weird \"hash function\" that outputs\n /// *variable-length* hashes: If the item is shorter than 32 bytes,\n /// the MPT hash is the item. Otherwise, the MPT hash is the\n /// Keccak-256 hash of the item.\n /// The easiest way to compare variable-length byte sequences is\n /// to compare their Keccak-256 hashes.\n /// @param item The RLP item to be hashed.\n /// @return Keccak-256(MPT-hash(item))\n function _mptHashHash(\n RLPReader.RLPItem memory item\n ) private pure returns (bytes32) {\n if (item.len < 32) {\n return item.rlpBytesKeccak256();\n } else {\n return keccak256(abi.encodePacked(item.rlpBytesKeccak256()));\n }\n }\n\n function _isEmptyBytesequence(\n RLPReader.RLPItem memory item\n ) private pure returns (bool) {\n if (item.len != 1) {\n return false;\n }\n uint8 b;\n uint256 memPtr = item.memPtr;\n assembly {\n b := byte(0, mload(memPtr))\n }\n return b == 0x80 /* empty byte string */;\n }\n\n function _merklePatriciaCompactDecode(\n bytes memory compact\n ) private pure returns (bool isLeaf, bytes memory nibbles) {\n require(compact.length > 0);\n uint256 first_nibble = (uint8(compact[0]) >> 4) & 0xF;\n uint256 skipNibbles;\n if (first_nibble == 0) {\n skipNibbles = 2;\n isLeaf = false;\n } else if (first_nibble == 1) {\n skipNibbles = 1;\n isLeaf = false;\n } else if (first_nibble == 2) {\n skipNibbles = 2;\n isLeaf = true;\n } else if (first_nibble == 3) {\n skipNibbles = 1;\n isLeaf = true;\n } else {\n // Not supposed to happen!\n revert();\n }\n return (isLeaf, _decodeNibbles(compact, skipNibbles));\n }\n\n function _decodeNibbles(\n bytes memory compact,\n uint256 skipNibbles\n ) private pure returns (bytes memory nibbles) {\n require(compact.length > 0);\n\n uint256 length = compact.length * 2;\n require(skipNibbles <= length);\n length -= skipNibbles;\n\n nibbles = new bytes(length);\n uint256 nibblesLength = 0;\n\n for (uint256 i = skipNibbles; i < skipNibbles + length; i += 1) {\n if (i % 2 == 0) {\n nibbles[nibblesLength] = bytes1((uint8(compact[i / 2]) >> 4) & 0xF);\n } else {\n nibbles[nibblesLength] = bytes1((uint8(compact[i / 2]) >> 0) & 0xF);\n }\n nibblesLength += 1;\n }\n\n assert(nibblesLength == nibbles.length);\n }\n\n function _sharedPrefixLength(\n uint256 xsOffset,\n bytes memory xs,\n bytes memory ys\n ) private pure returns (uint256) {\n uint256 i;\n for (i = 0; i + xsOffset < xs.length && i < ys.length; i++) {\n if (xs[i + xsOffset] != ys[i]) {\n return i;\n }\n }\n return i;\n }\n}\n" }, "contracts/Cross-chain/libs/RLPReader.sol": { "content": "// SPDX-License-Identifier: Apache-2.0\n\n/*\n * @author Hamdi Allam hamdi.allam97@gmail.com\n * Please reach out with any questions or concerns\n * Code copied from: https://github.com/hamdiallam/Solidity-RLP/blob/master/contracts/RLPReader.sol\n */\npragma solidity ^0.8.0;\n\nlibrary RLPReader {\n uint8 constant STRING_SHORT_START = 0x80;\n uint8 constant STRING_LONG_START = 0xb8;\n uint8 constant LIST_SHORT_START = 0xc0;\n uint8 constant LIST_LONG_START = 0xf8;\n uint8 constant WORD_SIZE = 32;\n\n struct RLPItem {\n uint256 len;\n uint256 memPtr;\n }\n\n struct Iterator {\n RLPItem item; // Item that's being iterated over.\n uint256 nextPtr; // Position of the next item in the list.\n }\n\n /*\n * @dev Returns the next element in the iteration. Reverts if it has not next element.\n * @param self The iterator.\n * @return The next element in the iteration.\n */\n function next(Iterator memory self) internal pure returns (RLPItem memory) {\n require(hasNext(self));\n\n uint256 ptr = self.nextPtr;\n uint256 itemLength = _itemLength(ptr);\n self.nextPtr = ptr + itemLength;\n\n return RLPItem(itemLength, ptr);\n }\n\n /*\n * @dev Returns true if the iteration has more elements.\n * @param self The iterator.\n * @return true if the iteration has more elements.\n */\n function hasNext(Iterator memory self) internal pure returns (bool) {\n RLPItem memory item = self.item;\n return self.nextPtr < item.memPtr + item.len;\n }\n\n /*\n * @param item RLP encoded bytes\n */\n function toRlpItem(bytes memory item) internal pure returns (RLPItem memory) {\n uint256 memPtr;\n assembly {\n memPtr := add(item, 0x20)\n }\n\n return RLPItem(item.length, memPtr);\n }\n\n /*\n * @dev Create an iterator. Reverts if item is not a list.\n * @param self The RLP item.\n * @return An 'Iterator' over the item.\n */\n function iterator(\n RLPItem memory self\n ) internal pure returns (Iterator memory) {\n require(isList(self));\n\n uint256 ptr = self.memPtr + _payloadOffset(self.memPtr);\n return Iterator(self, ptr);\n }\n\n /*\n * @param the RLP item.\n */\n function rlpLen(RLPItem memory item) internal pure returns (uint256) {\n return item.len;\n }\n\n /*\n * @param the RLP item.\n * @return (memPtr, len) pair: location of the item's payload in memory.\n */\n function payloadLocation(\n RLPItem memory item\n ) internal pure returns (uint256, uint256) {\n uint256 offset = _payloadOffset(item.memPtr);\n uint256 memPtr = item.memPtr + offset;\n uint256 len = item.len - offset; // data length\n return (memPtr, len);\n }\n\n /*\n * @param the RLP item.\n */\n function payloadLen(RLPItem memory item) internal pure returns (uint256) {\n (, uint256 len) = payloadLocation(item);\n return len;\n }\n\n /*\n * @param the RLP item containing the encoded list.\n */\n function toList(\n RLPItem memory item\n ) internal pure returns (RLPItem[] memory) {\n require(isList(item));\n\n uint256 items = numItems(item);\n RLPItem[] memory result = new RLPItem[](items);\n\n uint256 memPtr = item.memPtr + _payloadOffset(item.memPtr);\n uint256 dataLen;\n for (uint256 i = 0; i < items; i++) {\n dataLen = _itemLength(memPtr);\n result[i] = RLPItem(dataLen, memPtr);\n memPtr = memPtr + dataLen;\n }\n\n return result;\n }\n\n // @return indicator whether encoded payload is a list. negate this function call for isData.\n function isList(RLPItem memory item) internal pure returns (bool) {\n if (item.len == 0) return false;\n\n uint8 byte0;\n uint256 memPtr = item.memPtr;\n assembly {\n byte0 := byte(0, mload(memPtr))\n }\n\n if (byte0 < LIST_SHORT_START) return false;\n return true;\n }\n\n /*\n * @dev A cheaper version of keccak256(toRlpBytes(item)) that avoids copying memory.\n * @return keccak256 hash of RLP encoded bytes.\n */\n function rlpBytesKeccak256(\n RLPItem memory item\n ) internal pure returns (bytes32) {\n uint256 ptr = item.memPtr;\n uint256 len = item.len;\n bytes32 result;\n assembly {\n result := keccak256(ptr, len)\n }\n return result;\n }\n\n /*\n * @dev A cheaper version of keccak256(toBytes(item)) that avoids copying memory.\n * @return keccak256 hash of the item payload.\n */\n function payloadKeccak256(\n RLPItem memory item\n ) internal pure returns (bytes32) {\n (uint256 memPtr, uint256 len) = payloadLocation(item);\n bytes32 result;\n assembly {\n result := keccak256(memPtr, len)\n }\n return result;\n }\n\n /** RLPItem conversions into data types **/\n\n // @returns raw rlp encoding in bytes\n function toRlpBytes(\n RLPItem memory item\n ) internal pure returns (bytes memory) {\n bytes memory result = new bytes(item.len);\n if (result.length == 0) return result;\n\n uint256 ptr;\n assembly {\n ptr := add(0x20, result)\n }\n\n copy(item.memPtr, ptr, item.len);\n return result;\n }\n\n // any non-zero byte except \"0x80\" is considered true\n function toBoolean(RLPItem memory item) internal pure returns (bool) {\n require(item.len == 1);\n uint256 result;\n uint256 memPtr = item.memPtr;\n assembly {\n result := byte(0, mload(memPtr))\n }\n\n // SEE Github Issue #5.\n // Summary: Most commonly used RLP libraries (i.e Geth) will encode\n // \"0\" as \"0x80\" instead of as \"0\". We handle this edge case explicitly\n // here.\n if (result == 0 || result == STRING_SHORT_START) {\n return false;\n } else {\n return true;\n }\n }\n\n function toAddress(RLPItem memory item) internal pure returns (address) {\n // 1 byte for the length prefix\n require(item.len == 21);\n\n return address(uint160(toUint(item)));\n }\n\n function toUint(RLPItem memory item) internal pure returns (uint256) {\n require(item.len > 0 && item.len <= 33);\n\n (uint256 memPtr, uint256 len) = payloadLocation(item);\n\n uint256 result;\n assembly {\n result := mload(memPtr)\n\n // shift to the correct location if neccesary\n if lt(len, 32) {\n result := div(result, exp(256, sub(32, len)))\n }\n }\n\n return result;\n }\n\n // enforces 32 byte length\n function toUintStrict(RLPItem memory item) internal pure returns (uint256) {\n // one byte prefix\n require(item.len == 33);\n\n uint256 result;\n uint256 memPtr = item.memPtr + 1;\n assembly {\n result := mload(memPtr)\n }\n\n return result;\n }\n\n function toBytes(RLPItem memory item) internal pure returns (bytes memory) {\n require(item.len > 0);\n\n (uint256 memPtr, uint256 len) = payloadLocation(item);\n bytes memory result = new bytes(len);\n\n uint256 destPtr;\n assembly {\n destPtr := add(0x20, result)\n }\n\n copy(memPtr, destPtr, len);\n return result;\n }\n\n /*\n * Private Helpers\n */\n\n // @return number of payload items inside an encoded list.\n function numItems(RLPItem memory item) private pure returns (uint256) {\n if (item.len == 0) return 0;\n\n uint256 count = 0;\n uint256 currPtr = item.memPtr + _payloadOffset(item.memPtr);\n uint256 endPtr = item.memPtr + item.len;\n while (currPtr < endPtr) {\n currPtr = currPtr + _itemLength(currPtr); // skip over an item\n count++;\n }\n\n return count;\n }\n\n // @return entire rlp item byte length\n function _itemLength(uint256 memPtr) private pure returns (uint256) {\n uint256 itemLen;\n uint256 byte0;\n assembly {\n byte0 := byte(0, mload(memPtr))\n }\n\n if (byte0 < STRING_SHORT_START) {\n itemLen = 1;\n } else if (byte0 < STRING_LONG_START) {\n itemLen = byte0 - STRING_SHORT_START + 1;\n } else if (byte0 < LIST_SHORT_START) {\n assembly {\n let byteLen := sub(byte0, 0xb7) // # of bytes the actual length is\n memPtr := add(memPtr, 1) // skip over the first byte\n\n /* 32 byte word size */\n let dataLen := div(mload(memPtr), exp(256, sub(32, byteLen))) // right shifting to get the len\n itemLen := add(dataLen, add(byteLen, 1))\n }\n } else if (byte0 < LIST_LONG_START) {\n itemLen = byte0 - LIST_SHORT_START + 1;\n } else {\n assembly {\n let byteLen := sub(byte0, 0xf7)\n memPtr := add(memPtr, 1)\n\n let dataLen := div(mload(memPtr), exp(256, sub(32, byteLen))) // right shifting to the correct length\n itemLen := add(dataLen, add(byteLen, 1))\n }\n }\n\n return itemLen;\n }\n\n // @return number of bytes until the data\n function _payloadOffset(uint256 memPtr) private pure returns (uint256) {\n uint256 byte0;\n assembly {\n byte0 := byte(0, mload(memPtr))\n }\n\n if (byte0 < STRING_SHORT_START) {\n return 0;\n } else if (\n byte0 < STRING_LONG_START ||\n (byte0 >= LIST_SHORT_START && byte0 < LIST_LONG_START)\n ) {\n return 1;\n } else if (byte0 < LIST_SHORT_START) {\n // being explicit\n return byte0 - (STRING_LONG_START - 1) + 1;\n } else {\n return byte0 - (LIST_LONG_START - 1) + 1;\n }\n }\n\n /*\n * @param src Pointer to source\n * @param dest Pointer to destination\n * @param len Amount of memory to copy from the source\n */\n function copy(uint256 src, uint256 dest, uint256 len) private pure {\n if (len == 0) return;\n\n // copy as many word sizes as possible\n for (; len >= WORD_SIZE; len -= WORD_SIZE) {\n assembly {\n mstore(dest, mload(src))\n }\n\n src += WORD_SIZE;\n dest += WORD_SIZE;\n }\n\n if (len > 0) {\n // left over bytes. Mask is used to remove unwanted bytes from the word\n uint256 mask = 256 ** (WORD_SIZE - len) - 1;\n assembly {\n let srcpart := and(mload(src), not(mask)) // zero out src\n let destpart := and(mload(dest), mask) // retrieve the bytes\n mstore(dest, or(destpart, srcpart))\n }\n }\n }\n}\n" }, "contracts/Cross-chain/libs/StateProofVerifier.sol": { "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\nimport {RLPReader} from \"./RLPReader.sol\";\nimport {MerklePatriciaProofVerifier} from \"./MerklePatriciaProofVerifier.sol\";\n\n/**\n * @title A helper library for verification of Merkle Patricia account and state proofs.\n */\nlibrary StateProofVerifier {\n using RLPReader for RLPReader.RLPItem;\n using RLPReader for bytes;\n\n uint256 constant HEADER_STATE_ROOT_INDEX = 3;\n uint256 constant HEADER_NUMBER_INDEX = 8;\n uint256 constant HEADER_TIMESTAMP_INDEX = 11;\n\n struct BlockHeader {\n bytes32 hash;\n bytes32 stateRootHash;\n uint256 number;\n uint256 timestamp;\n }\n\n struct Account {\n bool exists;\n uint256 nonce;\n uint256 balance;\n bytes32 storageRoot;\n bytes32 codeHash;\n }\n\n struct SlotValue {\n bool exists;\n uint256 value;\n }\n\n /**\n * @notice Parses block header and verifies its presence onchain within the latest 256 blocks.\n * @param _headerRlpBytes RLP-encoded block header.\n */\n function verifyBlockHeader(\n bytes memory _headerRlpBytes,\n bytes32 _blockHash\n ) internal pure returns (BlockHeader memory) {\n BlockHeader memory header = parseBlockHeader(_headerRlpBytes);\n require(header.hash == _blockHash, 'blockhash mismatch');\n return header;\n }\n\n /**\n * @notice Parses RLP-encoded block header.\n * @param _headerRlpBytes RLP-encoded block header.\n */\n function parseBlockHeader(\n bytes memory _headerRlpBytes\n ) internal pure returns (BlockHeader memory) {\n BlockHeader memory result;\n RLPReader.RLPItem[] memory headerFields = _headerRlpBytes\n .toRlpItem()\n .toList();\n\n require(headerFields.length > HEADER_TIMESTAMP_INDEX);\n\n result.stateRootHash = bytes32(\n headerFields[HEADER_STATE_ROOT_INDEX].toUint()\n );\n result.number = headerFields[HEADER_NUMBER_INDEX].toUint();\n result.timestamp = headerFields[HEADER_TIMESTAMP_INDEX].toUint();\n result.hash = keccak256(_headerRlpBytes);\n\n return result;\n }\n\n /**\n * @notice Verifies Merkle Patricia proof of an account and extracts the account fields.\n *\n * @param _addressHash Keccak256 hash of the address corresponding to the account.\n * @param _stateRootHash MPT root hash of the Ethereum state trie.\n */\n function extractAccountFromProof(\n bytes32 _addressHash, // keccak256(abi.encodePacked(address))\n bytes32 _stateRootHash,\n RLPReader.RLPItem[] memory _proof\n ) internal pure returns (Account memory) {\n bytes memory acctRlpBytes = MerklePatriciaProofVerifier.extractProofValue(\n _stateRootHash,\n abi.encodePacked(_addressHash),\n _proof\n );\n Account memory account;\n\n if (acctRlpBytes.length == 0) {\n return account;\n }\n\n RLPReader.RLPItem[] memory acctFields = acctRlpBytes.toRlpItem().toList();\n require(acctFields.length == 4);\n\n account.exists = true;\n account.nonce = acctFields[0].toUint();\n account.balance = acctFields[1].toUint();\n account.storageRoot = bytes32(acctFields[2].toUint());\n account.codeHash = bytes32(acctFields[3].toUint());\n\n return account;\n }\n\n /**\n * @notice Verifies Merkle Patricia proof of a slot and extracts the slot's value.\n *\n * @param _slotHash Keccak256 hash of the slot position.\n * @param _storageRootHash MPT root hash of the account's storage trie.\n */\n function extractSlotValueFromProof(\n bytes32 _slotHash,\n bytes32 _storageRootHash,\n RLPReader.RLPItem[] memory _proof\n ) internal pure returns (SlotValue memory) {\n bytes memory valueRlpBytes = MerklePatriciaProofVerifier.extractProofValue(\n _storageRootHash,\n abi.encodePacked(_slotHash),\n _proof\n );\n\n SlotValue memory value;\n\n if (valueRlpBytes.length != 0) {\n value.exists = true;\n value.value = valueRlpBytes.toRlpItem().toUint();\n }\n\n return value;\n }\n}\n" }, "contracts/Cross-chain/Voting/DataWarehouse.sol": { "content": "// SPDX-License-Identifier: BUSL-1.1\npragma solidity ^0.8.0;\n\nimport {IDataWarehouse} from \"../interfaces/IDataWarehouse.sol\";\nimport {StateProofVerifier} from \"../libs/StateProofVerifier.sol\";\nimport {RLPReader} from \"../libs/RLPReader.sol\";\n\n/**\n * @title DataWarehouse\n * @author BGD Labs\n * @notice This contract stores account state roots and allows proving against them\n */\ncontract DataWarehouse is IDataWarehouse {\n using RLPReader for bytes;\n using RLPReader for RLPReader.RLPItem;\n\n // account address => (block hash => Account state root hash)\n mapping(address => mapping(bytes32 => bytes32)) internal _storageRoots;\n\n // account address => (block hash => (slot => slot value))\n mapping(address => mapping(bytes32 => mapping(bytes32 => uint256)))\n internal _slotsRegistered;\n\n /// @inheritdoc IDataWarehouse\n function getStorageRoots(\n address account,\n bytes32 blockHash\n ) external view returns (bytes32) {\n return _storageRoots[account][blockHash];\n }\n\n /// @inheritdoc IDataWarehouse\n function getRegisteredSlot(\n bytes32 blockHash,\n address account,\n bytes32 slot\n ) external view returns (uint256) {\n return _slotsRegistered[account][blockHash][slot];\n }\n\n /// @inheritdoc IDataWarehouse\n function processStorageRoot(\n address account,\n bytes32 blockHash,\n bytes memory blockHeaderRLP,\n bytes memory accountStateProofRLP\n ) external returns (bytes32) {\n StateProofVerifier.BlockHeader memory decodedHeader = StateProofVerifier\n .verifyBlockHeader(blockHeaderRLP, blockHash);\n // The path for an account in the state trie is the hash of its address\n bytes32 proofPath = keccak256(abi.encodePacked(account));\n StateProofVerifier.Account memory accountData = StateProofVerifier\n .extractAccountFromProof(\n proofPath,\n decodedHeader.stateRootHash,\n accountStateProofRLP.toRlpItem().toList()\n );\n\n _storageRoots[account][blockHash] = accountData.storageRoot;\n\n emit StorageRootProcessed(msg.sender, account, blockHash);\n\n return accountData.storageRoot;\n }\n\n /// @inheritdoc IDataWarehouse\n function getStorage(\n address account,\n bytes32 blockHash,\n bytes32 slot,\n bytes memory storageProof\n ) public view returns (StateProofVerifier.SlotValue memory) {\n bytes32 root = _storageRoots[account][blockHash];\n require(root != bytes32(0), \"DataWarehouse: storage root not processed\");\n\n // The path for a storage value is the hash of its slot\n bytes32 proofPath = keccak256(abi.encodePacked(slot));\n StateProofVerifier.SlotValue memory slotData = StateProofVerifier\n .extractSlotValueFromProof(\n proofPath,\n root,\n storageProof.toRlpItem().toList()\n );\n\n return slotData;\n }\n\n /// @inheritdoc IDataWarehouse\n function processStorageSlot(\n address account,\n bytes32 blockHash,\n bytes32 slot,\n bytes calldata storageProof\n ) external {\n StateProofVerifier.SlotValue memory storageSlot = getStorage(\n account,\n blockHash,\n slot,\n storageProof\n );\n\n _slotsRegistered[account][blockHash][slot] = storageSlot.value;\n\n emit StorageSlotProcessed(\n msg.sender,\n account,\n blockHash,\n slot,\n storageSlot.value\n );\n }\n}\n" }, "contracts/Governance/TimelockV8.sol": { "content": "// SPDX-License-Identifier: BSD-3-Clause\npragma solidity 0.8.25;\nimport { ensureNonzeroAddress } from \"@venusprotocol/solidity-utilities/contracts/validators.sol\";\n\n/**\n * @title TimelockV8\n * @author Venus\n * @notice The Timelock contract using solidity V8.\n * This contract also differs from the original timelock because it has a virtual function to get minimum delays\n * and allow test deployments to override the value.\n */\ncontract TimelockV8 {\n /// @notice Required period to execute a proposal transaction\n uint256 private constant DEFAULT_GRACE_PERIOD = 14 days;\n\n /// @notice Minimum amount of time a proposal transaction must be queued\n uint256 private constant DEFAULT_MINIMUM_DELAY = 1 hours;\n\n /// @notice Maximum amount of time a proposal transaction must be queued\n uint256 private constant DEFAULT_MAXIMUM_DELAY = 30 days;\n\n /// @notice Timelock admin authorized to queue and execute transactions\n address public admin;\n\n /// @notice Account proposed as the next admin\n address public pendingAdmin;\n\n /// @notice Period for a proposal transaction to be queued\n uint256 public delay;\n\n /// @notice Mapping of queued transactions\n mapping(bytes32 => bool) public queuedTransactions;\n\n /// @notice Event emitted when a new admin is accepted\n event NewAdmin(address indexed oldAdmin, address indexed newAdmin);\n\n /// @notice Event emitted when a new admin is proposed\n event NewPendingAdmin(address indexed newPendingAdmin);\n\n /// @notice Event emitted when a new delay is proposed\n event NewDelay(uint256 indexed oldDelay, uint256 indexed newDelay);\n\n /// @notice Event emitted when a proposal transaction has been cancelled\n event CancelTransaction(\n bytes32 indexed txHash,\n address indexed target,\n uint256 value,\n string signature,\n bytes data,\n uint256 eta\n );\n\n /// @notice Event emitted when a proposal transaction has been executed\n event ExecuteTransaction(\n bytes32 indexed txHash,\n address indexed target,\n uint256 value,\n string signature,\n bytes data,\n uint256 eta\n );\n\n /// @notice Event emitted when a proposal transaction has been queued\n event QueueTransaction(\n bytes32 indexed txHash,\n address indexed target,\n uint256 value,\n string signature,\n bytes data,\n uint256 eta\n );\n\n constructor(address admin_, uint256 delay_) {\n require(delay_ >= MINIMUM_DELAY(), \"Timelock::constructor: Delay must exceed minimum delay.\");\n require(delay_ <= MAXIMUM_DELAY(), \"Timelock::setDelay: Delay must not exceed maximum delay.\");\n ensureNonzeroAddress(admin_);\n\n admin = admin_;\n delay = delay_;\n }\n\n fallback() external payable {}\n\n /**\n * @notice Setter for the transaction queue delay\n * @param delay_ The new delay period for the transaction queue\n * @custom:access Sender must be Timelock itself\n * @custom:event Emit NewDelay with old and new delay\n */\n function setDelay(uint256 delay_) public {\n require(msg.sender == address(this), \"Timelock::setDelay: Call must come from Timelock.\");\n require(delay_ >= MINIMUM_DELAY(), \"Timelock::setDelay: Delay must exceed minimum delay.\");\n require(delay_ <= MAXIMUM_DELAY(), \"Timelock::setDelay: Delay must not exceed maximum delay.\");\n emit NewDelay(delay, delay_);\n delay = delay_;\n }\n\n /**\n * @notice Return grace period\n * @return The duration of the grace period, specified as a uint256 value.\n */\n function GRACE_PERIOD() public view virtual returns (uint256) {\n return DEFAULT_GRACE_PERIOD;\n }\n\n /**\n * @notice Return required minimum delay\n * @return Minimum delay\n */\n function MINIMUM_DELAY() public view virtual returns (uint256) {\n return DEFAULT_MINIMUM_DELAY;\n }\n\n /**\n * @notice Return required maximum delay\n * @return Maximum delay\n */\n function MAXIMUM_DELAY() public view virtual returns (uint256) {\n return DEFAULT_MAXIMUM_DELAY;\n }\n\n /**\n * @notice Method for accepting a proposed admin\n * @custom:access Sender must be pending admin\n * @custom:event Emit NewAdmin with old and new admin\n */\n function acceptAdmin() public {\n require(msg.sender == pendingAdmin, \"Timelock::acceptAdmin: Call must come from pendingAdmin.\");\n emit NewAdmin(admin, msg.sender);\n admin = msg.sender;\n pendingAdmin = address(0);\n }\n\n /**\n * @notice Method to propose a new admin authorized to call timelock functions. This should be the Governor Contract\n * @param pendingAdmin_ Address of the proposed admin\n * @custom:access Sender must be Timelock contract itself or admin\n * @custom:event Emit NewPendingAdmin with new pending admin\n */\n function setPendingAdmin(address pendingAdmin_) public {\n require(\n msg.sender == address(this) || msg.sender == admin,\n \"Timelock::setPendingAdmin: Call must come from Timelock.\"\n );\n ensureNonzeroAddress(pendingAdmin_);\n pendingAdmin = pendingAdmin_;\n\n emit NewPendingAdmin(pendingAdmin);\n }\n\n /**\n * @notice Called for each action when queuing a proposal\n * @param target Address of the contract with the method to be called\n * @param value Native token amount sent with the transaction\n * @param signature Signature of the function to be called\n * @param data Arguments to be passed to the function when called\n * @param eta Timestamp after which the transaction can be executed\n * @return Hash of the queued transaction\n * @custom:access Sender must be admin\n * @custom:event Emit QueueTransaction\n */\n function queueTransaction(\n address target,\n uint256 value,\n string calldata signature,\n bytes calldata data,\n uint256 eta\n ) public returns (bytes32) {\n require(msg.sender == admin, \"Timelock::queueTransaction: Call must come from admin.\");\n require(\n eta >= getBlockTimestamp() + delay,\n \"Timelock::queueTransaction: Estimated execution block must satisfy delay.\"\n );\n\n bytes32 txHash = keccak256(abi.encode(target, value, signature, data, eta));\n require(!queuedTransactions[txHash], \"Timelock::queueTransaction: transaction already queued.\");\n queuedTransactions[txHash] = true;\n\n emit QueueTransaction(txHash, target, value, signature, data, eta);\n return txHash;\n }\n\n /**\n * @notice Called to cancel a queued transaction\n * @param target Address of the contract with the method to be called\n * @param value Native token amount sent with the transaction\n * @param signature Signature of the function to be called\n * @param data Arguments to be passed to the function when called\n * @param eta Timestamp after which the transaction can be executed\n * @custom:access Sender must be admin\n * @custom:event Emit CancelTransaction\n */\n function cancelTransaction(\n address target,\n uint256 value,\n string calldata signature,\n bytes calldata data,\n uint256 eta\n ) public {\n require(msg.sender == admin, \"Timelock::cancelTransaction: Call must come from admin.\");\n\n bytes32 txHash = keccak256(abi.encode(target, value, signature, data, eta));\n require(queuedTransactions[txHash], \"Timelock::cancelTransaction: transaction is not queued yet.\");\n delete (queuedTransactions[txHash]);\n\n emit CancelTransaction(txHash, target, value, signature, data, eta);\n }\n\n /**\n * @notice Called to execute a queued transaction\n * @param target Address of the contract with the method to be called\n * @param value Native token amount sent with the transaction\n * @param signature Signature of the function to be called\n * @param data Arguments to be passed to the function when called\n * @param eta Timestamp after which the transaction can be executed\n * @return Result of function call\n * @custom:access Sender must be admin\n * @custom:event Emit ExecuteTransaction\n */\n function executeTransaction(\n address target,\n uint256 value,\n string calldata signature,\n bytes calldata data,\n uint256 eta\n ) public returns (bytes memory) {\n require(msg.sender == admin, \"Timelock::executeTransaction: Call must come from admin.\");\n\n bytes32 txHash = keccak256(abi.encode(target, value, signature, data, eta));\n require(queuedTransactions[txHash], \"Timelock::executeTransaction: Transaction hasn't been queued.\");\n require(getBlockTimestamp() >= eta, \"Timelock::executeTransaction: Transaction hasn't surpassed time lock.\");\n require(getBlockTimestamp() <= eta + GRACE_PERIOD(), \"Timelock::executeTransaction: Transaction is stale.\");\n\n delete (queuedTransactions[txHash]);\n\n bytes memory callData;\n\n if (bytes(signature).length == 0) {\n callData = data;\n } else {\n callData = abi.encodePacked(bytes4(keccak256(bytes(signature))), data);\n }\n\n // solium-disable-next-line security/no-call-value\n (bool success, bytes memory returnData) = target.call{ value: value }(callData);\n require(success, \"Timelock::executeTransaction: Transaction execution reverted.\");\n\n emit ExecuteTransaction(txHash, target, value, signature, data, eta);\n\n return returnData;\n }\n\n /**\n * @notice Returns the current block timestamp\n * @return The current block timestamp\n */\n function getBlockTimestamp() internal view returns (uint256) {\n // solium-disable-next-line security/no-block-members\n return block.timestamp;\n }\n}\n" }, "contracts/hardhat-dependency-compiler/hardhat-deploy/solc_0.8/openzeppelin/proxy/transparent/ProxyAdmin.sol": { "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity >0.0.0;\nimport 'hardhat-deploy/solc_0.8/openzeppelin/proxy/transparent/ProxyAdmin.sol';\n" }, "contracts/hardhat-dependency-compiler/hardhat-deploy/solc_0.8/proxy/OptimizedTransparentUpgradeableProxy.sol": { "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity >0.0.0;\nimport 'hardhat-deploy/solc_0.8/proxy/OptimizedTransparentUpgradeableProxy.sol';\n" }, "contracts/test/TestTimelockV8.sol": { "content": "// SPDX-License-Identifier: BSD-3-Clause\npragma solidity 0.8.25;\nimport { TimelockV8 } from \"../Governance/TimelockV8.sol\";\n\ncontract TestTimelockV8 is TimelockV8 {\n constructor(address admin_, uint256 delay_) public TimelockV8(admin_, delay_) {}\n\n function GRACE_PERIOD() public view override returns (uint256) {\n return 1 hours;\n }\n\n function MINIMUM_DELAY() public view override returns (uint256) {\n return 1;\n }\n\n function MAXIMUM_DELAY() public view override returns (uint256) {\n return 1 hours;\n }\n}\n" }, "hardhat-deploy/solc_0.8/openzeppelin/access/Ownable.sol": { "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (access/Ownable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../utils/Context.sol\";\n\n/**\n * @dev Contract module which provides a basic access control mechanism, where\n * there is an account (an owner) that can be granted exclusive access to\n * specific functions.\n *\n * By default, the owner account will be the one that deploys the contract. This\n * can later be changed with {transferOwnership}.\n *\n * This module is used through inheritance. It will make available the modifier\n * `onlyOwner`, which can be applied to your functions to restrict their use to\n * the owner.\n */\nabstract contract Ownable is Context {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n constructor (address initialOwner) {\n _transferOwnership(initialOwner);\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n}\n" }, "hardhat-deploy/solc_0.8/openzeppelin/interfaces/draft-IERC1822.sol": { "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0-rc.0) (interfaces/draft-IERC1822.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev ERC1822: Universal Upgradeable Proxy Standard (UUPS) documents a method for upgradeability through a simplified\n * proxy whose upgrades are fully controlled by the current implementation.\n */\ninterface IERC1822Proxiable {\n /**\n * @dev Returns the storage slot that the proxiable contract assumes is being used to store the implementation\n * address.\n *\n * IMPORTANT: A proxy pointing at a proxiable contract should not be considered proxiable itself, because this risks\n * bricking a proxy that upgrades to it, by delegating to itself until out of gas. Thus it is critical that this\n * function revert if invoked through a proxy.\n */\n function proxiableUUID() external view returns (bytes32);\n}\n" }, "hardhat-deploy/solc_0.8/openzeppelin/proxy/beacon/IBeacon.sol": { "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (proxy/beacon/IBeacon.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev This is the interface that {BeaconProxy} expects of its beacon.\n */\ninterface IBeacon {\n /**\n * @dev Must return an address that can be used as a delegate call target.\n *\n * {BeaconProxy} will check that this address is a contract.\n */\n function implementation() external view returns (address);\n}\n" }, "hardhat-deploy/solc_0.8/openzeppelin/proxy/ERC1967/ERC1967Proxy.sol": { "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (proxy/ERC1967/ERC1967Proxy.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../Proxy.sol\";\nimport \"./ERC1967Upgrade.sol\";\n\n/**\n * @dev This contract implements an upgradeable proxy. It is upgradeable because calls are delegated to an\n * implementation address that can be changed. This address is stored in storage in the location specified by\n * https://eips.ethereum.org/EIPS/eip-1967[EIP1967], so that it doesn't conflict with the storage layout of the\n * implementation behind the proxy.\n */\ncontract ERC1967Proxy is Proxy, ERC1967Upgrade {\n /**\n * @dev Initializes the upgradeable proxy with an initial implementation specified by `_logic`.\n *\n * If `_data` is nonempty, it's used as data in a delegate call to `_logic`. This will typically be an encoded\n * function call, and allows initializating the storage of the proxy like a Solidity constructor.\n */\n constructor(address _logic, bytes memory _data) payable {\n assert(_IMPLEMENTATION_SLOT == bytes32(uint256(keccak256(\"eip1967.proxy.implementation\")) - 1));\n _upgradeToAndCall(_logic, _data, false);\n }\n\n /**\n * @dev Returns the current implementation address.\n */\n function _implementation() internal view virtual override returns (address impl) {\n return ERC1967Upgrade._getImplementation();\n }\n}\n" }, "hardhat-deploy/solc_0.8/openzeppelin/proxy/ERC1967/ERC1967Upgrade.sol": { "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0-rc.0) (proxy/ERC1967/ERC1967Upgrade.sol)\n\npragma solidity ^0.8.2;\n\nimport \"../beacon/IBeacon.sol\";\nimport \"../../interfaces/draft-IERC1822.sol\";\nimport \"../../utils/Address.sol\";\nimport \"../../utils/StorageSlot.sol\";\n\n/**\n * @dev This abstract contract provides getters and event emitting update functions for\n * https://eips.ethereum.org/EIPS/eip-1967[EIP1967] slots.\n *\n * _Available since v4.1._\n *\n * @custom:oz-upgrades-unsafe-allow delegatecall\n */\nabstract contract ERC1967Upgrade {\n // This is the keccak-256 hash of \"eip1967.proxy.rollback\" subtracted by 1\n bytes32 private constant _ROLLBACK_SLOT = 0x4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd9143;\n\n