@venusprotocol/governance-contracts
Version:
356 lines • 585 kB
JSON
{
"language": "Solidity",
"sources": {
"@layerzerolabs/lz-evm-messagelib-v2/contracts/libs/ExecutorOptions.sol": {
"content": "// SPDX-License-Identifier: LZBL-1.2\n\npragma solidity ^0.8.20;\n\nimport \"@layerzerolabs/lz-evm-protocol-v2/contracts/libs/CalldataBytesLib.sol\";\n\nlibrary ExecutorOptions {\n using CalldataBytesLib for bytes;\n\n uint8 internal constant WORKER_ID = 1;\n\n uint8 internal constant OPTION_TYPE_LZRECEIVE = 1;\n uint8 internal constant OPTION_TYPE_NATIVE_DROP = 2;\n uint8 internal constant OPTION_TYPE_LZCOMPOSE = 3;\n uint8 internal constant OPTION_TYPE_ORDERED_EXECUTION = 4;\n uint8 internal constant OPTION_TYPE_LZREAD = 5;\n\n error Executor_InvalidLzReceiveOption();\n error Executor_InvalidNativeDropOption();\n error Executor_InvalidLzComposeOption();\n error Executor_InvalidLzReadOption();\n\n /// @dev decode the next executor option from the options starting from the specified cursor\n /// @param _options [executor_id][executor_option][executor_id][executor_option]...\n /// executor_option = [option_size][option_type][option]\n /// option_size = len(option_type) + len(option)\n /// executor_id: uint8, option_size: uint16, option_type: uint8, option: bytes\n /// @param _cursor the cursor to start decoding from\n /// @return optionType the type of the option\n /// @return option the option of the executor\n /// @return cursor the cursor to start decoding the next executor option\n function nextExecutorOption(\n bytes calldata _options,\n uint256 _cursor\n ) internal pure returns (uint8 optionType, bytes calldata option, uint256 cursor) {\n unchecked {\n // skip worker id\n cursor = _cursor + 1;\n\n // read option size\n uint16 size = _options.toU16(cursor);\n cursor += 2;\n\n // read option type\n optionType = _options.toU8(cursor);\n\n // startCursor and endCursor are used to slice the option from _options\n uint256 startCursor = cursor + 1; // skip option type\n uint256 endCursor = cursor + size;\n option = _options[startCursor:endCursor];\n cursor += size;\n }\n }\n\n function decodeLzReceiveOption(bytes calldata _option) internal pure returns (uint128 gas, uint128 value) {\n if (_option.length != 16 && _option.length != 32) revert Executor_InvalidLzReceiveOption();\n gas = _option.toU128(0);\n value = _option.length == 32 ? _option.toU128(16) : 0;\n }\n\n function decodeNativeDropOption(bytes calldata _option) internal pure returns (uint128 amount, bytes32 receiver) {\n if (_option.length != 48) revert Executor_InvalidNativeDropOption();\n amount = _option.toU128(0);\n receiver = _option.toB32(16);\n }\n\n function decodeLzComposeOption(\n bytes calldata _option\n ) internal pure returns (uint16 index, uint128 gas, uint128 value) {\n if (_option.length != 18 && _option.length != 34) revert Executor_InvalidLzComposeOption();\n index = _option.toU16(0);\n gas = _option.toU128(2);\n value = _option.length == 34 ? _option.toU128(18) : 0;\n }\n\n function decodeLzReadOption(\n bytes calldata _option\n ) internal pure returns (uint128 gas, uint32 calldataSize, uint128 value) {\n if (_option.length != 20 && _option.length != 36) revert Executor_InvalidLzReadOption();\n gas = _option.toU128(0);\n calldataSize = _option.toU32(16);\n value = _option.length == 36 ? _option.toU128(20) : 0;\n }\n\n function encodeLzReceiveOption(uint128 _gas, uint128 _value) internal pure returns (bytes memory) {\n return _value == 0 ? abi.encodePacked(_gas) : abi.encodePacked(_gas, _value);\n }\n\n function encodeNativeDropOption(uint128 _amount, bytes32 _receiver) internal pure returns (bytes memory) {\n return abi.encodePacked(_amount, _receiver);\n }\n\n function encodeLzComposeOption(uint16 _index, uint128 _gas, uint128 _value) internal pure returns (bytes memory) {\n return _value == 0 ? abi.encodePacked(_index, _gas) : abi.encodePacked(_index, _gas, _value);\n }\n\n function encodeLzReadOption(\n uint128 _gas,\n uint32 _calldataSize,\n uint128 _value\n ) internal pure returns (bytes memory) {\n return _value == 0 ? abi.encodePacked(_gas, _calldataSize) : abi.encodePacked(_gas, _calldataSize, _value);\n }\n}\n"
},
"@layerzerolabs/lz-evm-messagelib-v2/contracts/uln/libs/DVNOptions.sol": {
"content": "// SPDX-License-Identifier: LZBL-1.2\n\npragma solidity ^0.8.20;\n\nimport { BytesLib } from \"solidity-bytes-utils/contracts/BytesLib.sol\";\n\nimport { BitMap256 } from \"@layerzerolabs/lz-evm-protocol-v2/contracts/messagelib/libs/BitMaps.sol\";\nimport { CalldataBytesLib } from \"@layerzerolabs/lz-evm-protocol-v2/contracts/libs/CalldataBytesLib.sol\";\n\nlibrary DVNOptions {\n using CalldataBytesLib for bytes;\n using BytesLib for bytes;\n\n uint8 internal constant WORKER_ID = 2;\n uint8 internal constant OPTION_TYPE_PRECRIME = 1;\n\n error DVN_InvalidDVNIdx();\n error DVN_InvalidDVNOptions(uint256 cursor);\n\n /// @dev group dvn options by its idx\n /// @param _options [dvn_id][dvn_option][dvn_id][dvn_option]...\n /// dvn_option = [option_size][dvn_idx][option_type][option]\n /// option_size = len(dvn_idx) + len(option_type) + len(option)\n /// dvn_id: uint8, dvn_idx: uint8, option_size: uint16, option_type: uint8, option: bytes\n /// @return dvnOptions the grouped options, still share the same format of _options\n /// @return dvnIndices the dvn indices\n function groupDVNOptionsByIdx(\n bytes memory _options\n ) internal pure returns (bytes[] memory dvnOptions, uint8[] memory dvnIndices) {\n if (_options.length == 0) return (dvnOptions, dvnIndices);\n\n uint8 numDVNs = getNumDVNs(_options);\n\n // if there is only 1 dvn, we can just return the whole options\n if (numDVNs == 1) {\n dvnOptions = new bytes[](1);\n dvnOptions[0] = _options;\n\n dvnIndices = new uint8[](1);\n dvnIndices[0] = _options.toUint8(3); // dvn idx\n return (dvnOptions, dvnIndices);\n }\n\n // otherwise, we need to group the options by dvn_idx\n dvnIndices = new uint8[](numDVNs);\n dvnOptions = new bytes[](numDVNs);\n unchecked {\n uint256 cursor = 0;\n uint256 start = 0;\n uint8 lastDVNIdx = 255; // 255 is an invalid dvn_idx\n\n while (cursor < _options.length) {\n ++cursor; // skip worker_id\n\n // optionLength asserted in getNumDVNs (skip check)\n uint16 optionLength = _options.toUint16(cursor);\n cursor += 2;\n\n // dvnIdx asserted in getNumDVNs (skip check)\n uint8 dvnIdx = _options.toUint8(cursor);\n\n // dvnIdx must equal to the lastDVNIdx for the first option\n // so it is always skipped in the first option\n // this operation slices out options whenever the scan finds a different lastDVNIdx\n if (lastDVNIdx == 255) {\n lastDVNIdx = dvnIdx;\n } else if (dvnIdx != lastDVNIdx) {\n uint256 len = cursor - start - 3; // 3 is for worker_id and option_length\n bytes memory opt = _options.slice(start, len);\n _insertDVNOptions(dvnOptions, dvnIndices, lastDVNIdx, opt);\n\n // reset the start and lastDVNIdx\n start += len;\n lastDVNIdx = dvnIdx;\n }\n\n cursor += optionLength;\n }\n\n // skip check the cursor here because the cursor is asserted in getNumDVNs\n // if we have reached the end of the options, we need to process the last dvn\n uint256 size = cursor - start;\n bytes memory op = _options.slice(start, size);\n _insertDVNOptions(dvnOptions, dvnIndices, lastDVNIdx, op);\n\n // revert dvnIndices to start from 0\n for (uint8 i = 0; i < numDVNs; ++i) {\n --dvnIndices[i];\n }\n }\n }\n\n function _insertDVNOptions(\n bytes[] memory _dvnOptions,\n uint8[] memory _dvnIndices,\n uint8 _dvnIdx,\n bytes memory _newOptions\n ) internal pure {\n // dvnIdx starts from 0 but default value of dvnIndices is 0,\n // so we tell if the slot is empty by adding 1 to dvnIdx\n if (_dvnIdx == 255) revert DVN_InvalidDVNIdx();\n uint8 dvnIdxAdj = _dvnIdx + 1;\n\n for (uint256 j = 0; j < _dvnIndices.length; ++j) {\n uint8 index = _dvnIndices[j];\n if (dvnIdxAdj == index) {\n _dvnOptions[j] = abi.encodePacked(_dvnOptions[j], _newOptions);\n break;\n } else if (index == 0) {\n // empty slot, that means it is the first time we see this dvn\n _dvnIndices[j] = dvnIdxAdj;\n _dvnOptions[j] = _newOptions;\n break;\n }\n }\n }\n\n /// @dev get the number of unique dvns\n /// @param _options the format is the same as groupDVNOptionsByIdx\n function getNumDVNs(bytes memory _options) internal pure returns (uint8 numDVNs) {\n uint256 cursor = 0;\n BitMap256 bitmap;\n\n // find number of unique dvn_idx\n unchecked {\n while (cursor < _options.length) {\n ++cursor; // skip worker_id\n\n uint16 optionLength = _options.toUint16(cursor);\n cursor += 2;\n if (optionLength < 2) revert DVN_InvalidDVNOptions(cursor); // at least 1 byte for dvn_idx and 1 byte for option_type\n\n uint8 dvnIdx = _options.toUint8(cursor);\n\n // if dvnIdx is not set, increment numDVNs\n // max num of dvns is 255, 255 is an invalid dvn_idx\n // The order of the dvnIdx is not required to be sequential, as enforcing the order may weaken\n // the composability of the options. e.g. if we refrain from enforcing the order, an OApp that has\n // already enforced certain options can append additional options to the end of the enforced\n // ones without restrictions.\n if (dvnIdx == 255) revert DVN_InvalidDVNIdx();\n if (!bitmap.get(dvnIdx)) {\n ++numDVNs;\n bitmap = bitmap.set(dvnIdx);\n }\n\n cursor += optionLength;\n }\n }\n if (cursor != _options.length) revert DVN_InvalidDVNOptions(cursor);\n }\n\n /// @dev decode the next dvn option from _options starting from the specified cursor\n /// @param _options the format is the same as groupDVNOptionsByIdx\n /// @param _cursor the cursor to start decoding\n /// @return optionType the type of the option\n /// @return option the option\n /// @return cursor the cursor to start decoding the next option\n function nextDVNOption(\n bytes calldata _options,\n uint256 _cursor\n ) internal pure returns (uint8 optionType, bytes calldata option, uint256 cursor) {\n unchecked {\n // skip worker id\n cursor = _cursor + 1;\n\n // read option size\n uint16 size = _options.toU16(cursor);\n cursor += 2;\n\n // read option type\n optionType = _options.toU8(cursor + 1); // skip dvn_idx\n\n // startCursor and endCursor are used to slice the option from _options\n uint256 startCursor = cursor + 2; // skip option type and dvn_idx\n uint256 endCursor = cursor + size;\n option = _options[startCursor:endCursor];\n cursor += size;\n }\n }\n}\n"
},
"@layerzerolabs/lz-evm-protocol-v2/contracts/interfaces/ILayerZeroEndpointV2.sol": {
"content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.8.0;\n\nimport { IMessageLibManager } from \"./IMessageLibManager.sol\";\nimport { IMessagingComposer } from \"./IMessagingComposer.sol\";\nimport { IMessagingChannel } from \"./IMessagingChannel.sol\";\nimport { IMessagingContext } from \"./IMessagingContext.sol\";\n\nstruct MessagingParams {\n uint32 dstEid;\n bytes32 receiver;\n bytes message;\n bytes options;\n bool payInLzToken;\n}\n\nstruct MessagingReceipt {\n bytes32 guid;\n uint64 nonce;\n MessagingFee fee;\n}\n\nstruct MessagingFee {\n uint256 nativeFee;\n uint256 lzTokenFee;\n}\n\nstruct Origin {\n uint32 srcEid;\n bytes32 sender;\n uint64 nonce;\n}\n\ninterface ILayerZeroEndpointV2 is IMessageLibManager, IMessagingComposer, IMessagingChannel, IMessagingContext {\n event PacketSent(bytes encodedPayload, bytes options, address sendLibrary);\n\n event PacketVerified(Origin origin, address receiver, bytes32 payloadHash);\n\n event PacketDelivered(Origin origin, address receiver);\n\n event LzReceiveAlert(\n address indexed receiver,\n address indexed executor,\n Origin origin,\n bytes32 guid,\n uint256 gas,\n uint256 value,\n bytes message,\n bytes extraData,\n bytes reason\n );\n\n event LzTokenSet(address token);\n\n event DelegateSet(address sender, address delegate);\n\n function quote(MessagingParams calldata _params, address _sender) external view returns (MessagingFee memory);\n\n function send(\n MessagingParams calldata _params,\n address _refundAddress\n ) external payable returns (MessagingReceipt memory);\n\n function verify(Origin calldata _origin, address _receiver, bytes32 _payloadHash) external;\n\n function verifiable(Origin calldata _origin, address _receiver) external view returns (bool);\n\n function initializable(Origin calldata _origin, address _receiver) external view returns (bool);\n\n function lzReceive(\n Origin calldata _origin,\n address _receiver,\n bytes32 _guid,\n bytes calldata _message,\n bytes calldata _extraData\n ) external payable;\n\n // oapp can burn messages partially by calling this function with its own business logic if messages are verified in order\n function clear(address _oapp, Origin calldata _origin, bytes32 _guid, bytes calldata _message) external;\n\n function setLzToken(address _lzToken) external;\n\n function lzToken() external view returns (address);\n\n function nativeToken() external view returns (address);\n\n function setDelegate(address _delegate) external;\n}\n"
},
"@layerzerolabs/lz-evm-protocol-v2/contracts/interfaces/ILayerZeroReceiver.sol": {
"content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.8.0;\n\nimport { Origin } from \"./ILayerZeroEndpointV2.sol\";\n\ninterface ILayerZeroReceiver {\n function allowInitializePath(Origin calldata _origin) external view returns (bool);\n\n function nextNonce(uint32 _eid, bytes32 _sender) external view returns (uint64);\n\n function lzReceive(\n Origin calldata _origin,\n bytes32 _guid,\n bytes calldata _message,\n address _executor,\n bytes calldata _extraData\n ) external payable;\n}\n"
},
"@layerzerolabs/lz-evm-protocol-v2/contracts/interfaces/IMessageLibManager.sol": {
"content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.8.0;\n\nstruct SetConfigParam {\n uint32 eid;\n uint32 configType;\n bytes config;\n}\n\ninterface IMessageLibManager {\n struct Timeout {\n address lib;\n uint256 expiry;\n }\n\n event LibraryRegistered(address newLib);\n event DefaultSendLibrarySet(uint32 eid, address newLib);\n event DefaultReceiveLibrarySet(uint32 eid, address newLib);\n event DefaultReceiveLibraryTimeoutSet(uint32 eid, address oldLib, uint256 expiry);\n event SendLibrarySet(address sender, uint32 eid, address newLib);\n event ReceiveLibrarySet(address receiver, uint32 eid, address newLib);\n event ReceiveLibraryTimeoutSet(address receiver, uint32 eid, address oldLib, uint256 timeout);\n\n function registerLibrary(address _lib) external;\n\n function isRegisteredLibrary(address _lib) external view returns (bool);\n\n function getRegisteredLibraries() external view returns (address[] memory);\n\n function setDefaultSendLibrary(uint32 _eid, address _newLib) external;\n\n function defaultSendLibrary(uint32 _eid) external view returns (address);\n\n function setDefaultReceiveLibrary(uint32 _eid, address _newLib, uint256 _gracePeriod) external;\n\n function defaultReceiveLibrary(uint32 _eid) external view returns (address);\n\n function setDefaultReceiveLibraryTimeout(uint32 _eid, address _lib, uint256 _expiry) external;\n\n function defaultReceiveLibraryTimeout(uint32 _eid) external view returns (address lib, uint256 expiry);\n\n function isSupportedEid(uint32 _eid) external view returns (bool);\n\n function isValidReceiveLibrary(address _receiver, uint32 _eid, address _lib) external view returns (bool);\n\n /// ------------------- OApp interfaces -------------------\n function setSendLibrary(address _oapp, uint32 _eid, address _newLib) external;\n\n function getSendLibrary(address _sender, uint32 _eid) external view returns (address lib);\n\n function isDefaultSendLibrary(address _sender, uint32 _eid) external view returns (bool);\n\n function setReceiveLibrary(address _oapp, uint32 _eid, address _newLib, uint256 _gracePeriod) external;\n\n function getReceiveLibrary(address _receiver, uint32 _eid) external view returns (address lib, bool isDefault);\n\n function setReceiveLibraryTimeout(address _oapp, uint32 _eid, address _lib, uint256 _expiry) external;\n\n function receiveLibraryTimeout(address _receiver, uint32 _eid) external view returns (address lib, uint256 expiry);\n\n function setConfig(address _oapp, address _lib, SetConfigParam[] calldata _params) external;\n\n function getConfig(\n address _oapp,\n address _lib,\n uint32 _eid,\n uint32 _configType\n ) external view returns (bytes memory config);\n}\n"
},
"@layerzerolabs/lz-evm-protocol-v2/contracts/interfaces/IMessagingChannel.sol": {
"content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.8.0;\n\ninterface IMessagingChannel {\n event InboundNonceSkipped(uint32 srcEid, bytes32 sender, address receiver, uint64 nonce);\n event PacketNilified(uint32 srcEid, bytes32 sender, address receiver, uint64 nonce, bytes32 payloadHash);\n event PacketBurnt(uint32 srcEid, bytes32 sender, address receiver, uint64 nonce, bytes32 payloadHash);\n\n function eid() external view returns (uint32);\n\n // this is an emergency function if a message cannot be verified for some reasons\n // required to provide _nextNonce to avoid race condition\n function skip(address _oapp, uint32 _srcEid, bytes32 _sender, uint64 _nonce) external;\n\n function nilify(address _oapp, uint32 _srcEid, bytes32 _sender, uint64 _nonce, bytes32 _payloadHash) external;\n\n function burn(address _oapp, uint32 _srcEid, bytes32 _sender, uint64 _nonce, bytes32 _payloadHash) external;\n\n function nextGuid(address _sender, uint32 _dstEid, bytes32 _receiver) external view returns (bytes32);\n\n function inboundNonce(address _receiver, uint32 _srcEid, bytes32 _sender) external view returns (uint64);\n\n function outboundNonce(address _sender, uint32 _dstEid, bytes32 _receiver) external view returns (uint64);\n\n function inboundPayloadHash(\n address _receiver,\n uint32 _srcEid,\n bytes32 _sender,\n uint64 _nonce\n ) external view returns (bytes32);\n\n function lazyInboundNonce(address _receiver, uint32 _srcEid, bytes32 _sender) external view returns (uint64);\n}\n"
},
"@layerzerolabs/lz-evm-protocol-v2/contracts/interfaces/IMessagingComposer.sol": {
"content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.8.0;\n\ninterface IMessagingComposer {\n event ComposeSent(address from, address to, bytes32 guid, uint16 index, bytes message);\n event ComposeDelivered(address from, address to, bytes32 guid, uint16 index);\n event LzComposeAlert(\n address indexed from,\n address indexed to,\n address indexed executor,\n bytes32 guid,\n uint16 index,\n uint256 gas,\n uint256 value,\n bytes message,\n bytes extraData,\n bytes reason\n );\n\n function composeQueue(\n address _from,\n address _to,\n bytes32 _guid,\n uint16 _index\n ) external view returns (bytes32 messageHash);\n\n function sendCompose(address _to, bytes32 _guid, uint16 _index, bytes calldata _message) external;\n\n function lzCompose(\n address _from,\n address _to,\n bytes32 _guid,\n uint16 _index,\n bytes calldata _message,\n bytes calldata _extraData\n ) external payable;\n}\n"
},
"@layerzerolabs/lz-evm-protocol-v2/contracts/interfaces/IMessagingContext.sol": {
"content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.8.0;\n\ninterface IMessagingContext {\n function isSendingMessage() external view returns (bool);\n\n function getSendContext() external view returns (uint32 dstEid, address sender);\n}\n"
},
"@layerzerolabs/lz-evm-protocol-v2/contracts/libs/CalldataBytesLib.sol": {
"content": "// SPDX-License-Identifier: LZBL-1.2\n\npragma solidity ^0.8.20;\n\nlibrary CalldataBytesLib {\n function toU8(bytes calldata _bytes, uint256 _start) internal pure returns (uint8) {\n return uint8(_bytes[_start]);\n }\n\n function toU16(bytes calldata _bytes, uint256 _start) internal pure returns (uint16) {\n unchecked {\n uint256 end = _start + 2;\n return uint16(bytes2(_bytes[_start:end]));\n }\n }\n\n function toU32(bytes calldata _bytes, uint256 _start) internal pure returns (uint32) {\n unchecked {\n uint256 end = _start + 4;\n return uint32(bytes4(_bytes[_start:end]));\n }\n }\n\n function toU64(bytes calldata _bytes, uint256 _start) internal pure returns (uint64) {\n unchecked {\n uint256 end = _start + 8;\n return uint64(bytes8(_bytes[_start:end]));\n }\n }\n\n function toU128(bytes calldata _bytes, uint256 _start) internal pure returns (uint128) {\n unchecked {\n uint256 end = _start + 16;\n return uint128(bytes16(_bytes[_start:end]));\n }\n }\n\n function toU256(bytes calldata _bytes, uint256 _start) internal pure returns (uint256) {\n unchecked {\n uint256 end = _start + 32;\n return uint256(bytes32(_bytes[_start:end]));\n }\n }\n\n function toAddr(bytes calldata _bytes, uint256 _start) internal pure returns (address) {\n unchecked {\n uint256 end = _start + 20;\n return address(bytes20(_bytes[_start:end]));\n }\n }\n\n function toB32(bytes calldata _bytes, uint256 _start) internal pure returns (bytes32) {\n unchecked {\n uint256 end = _start + 32;\n return bytes32(_bytes[_start:end]);\n }\n }\n}\n"
},
"@layerzerolabs/lz-evm-protocol-v2/contracts/messagelib/libs/BitMaps.sol": {
"content": "// SPDX-License-Identifier: MIT\n\n// modified from https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/utils/structs/BitMaps.sol\npragma solidity ^0.8.20;\n\ntype BitMap256 is uint256;\n\nusing BitMaps for BitMap256 global;\n\nlibrary BitMaps {\n /**\n * @dev Returns whether the bit at `index` is set.\n */\n function get(BitMap256 bitmap, uint8 index) internal pure returns (bool) {\n uint256 mask = 1 << index;\n return BitMap256.unwrap(bitmap) & mask != 0;\n }\n\n /**\n * @dev Sets the bit at `index`.\n */\n function set(BitMap256 bitmap, uint8 index) internal pure returns (BitMap256) {\n uint256 mask = 1 << index;\n return BitMap256.wrap(BitMap256.unwrap(bitmap) | mask);\n }\n}\n"
},
"@layerzerolabs/oapp-evm-upgradeable/contracts/oapp/OAppCoreUpgradeable.sol": {
"content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.20;\n\nimport { OwnableUpgradeable } from \"@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol\";\nimport { IOAppCore, ILayerZeroEndpointV2 } from \"@layerzerolabs/oapp-evm/contracts/oapp/interfaces/IOAppCore.sol\";\n\n/**\n * @title OAppCore\n * @dev Abstract contract implementing the IOAppCore interface with basic OApp configurations.\n */\nabstract contract OAppCoreUpgradeable is IOAppCore, OwnableUpgradeable {\n struct OAppCoreStorage {\n mapping(uint32 => bytes32) peers;\n }\n\n // keccak256(abi.encode(uint256(keccak256(\"layerzerov2.storage.oappcore\")) - 1)) & ~bytes32(uint256(0xff))\n bytes32 private constant OAPP_CORE_STORAGE_LOCATION =\n 0x72ab1bc1039b79dc4724ffca13de82c96834302d3c7e0d4252232d4b2dd8f900;\n\n function _getOAppCoreStorage() internal pure returns (OAppCoreStorage storage $) {\n assembly {\n $.slot := OAPP_CORE_STORAGE_LOCATION\n }\n }\n\n // The LayerZero endpoint associated with the given OApp\n ILayerZeroEndpointV2 public immutable endpoint;\n\n /**\n * @dev Constructor to initialize the OAppCore with the provided endpoint and delegate.\n * @param _endpoint The address of the LOCAL Layer Zero endpoint.\n */\n constructor(address _endpoint) {\n endpoint = ILayerZeroEndpointV2(_endpoint);\n }\n\n /**\n * @dev Initializes the OAppCore with the provided delegate.\n * @param _delegate The delegate capable of making OApp configurations inside of the endpoint.\n *\n * @dev The delegate typically should be set as the owner of the contract.\n * @dev Ownable is not initialized here on purpose. It should be initialized in the child contract to\n * accommodate the different version of Ownable.\n */\n function __OAppCore_init(address _delegate) internal onlyInitializing {\n __OAppCore_init_unchained(_delegate);\n }\n\n function __OAppCore_init_unchained(address _delegate) internal onlyInitializing {\n if (_delegate == address(0)) revert InvalidDelegate();\n endpoint.setDelegate(_delegate);\n }\n\n /**\n * @notice Returns the peer address (OApp instance) associated with a specific endpoint.\n * @param _eid The endpoint ID.\n * @return peer The address of the peer associated with the specified endpoint.\n */\n function peers(uint32 _eid) public view override returns (bytes32) {\n OAppCoreStorage storage $ = _getOAppCoreStorage();\n return $.peers[_eid];\n }\n\n /**\n * @notice Sets the peer address (OApp instance) for a corresponding endpoint.\n * @param _eid The endpoint ID.\n * @param _peer The address of the peer to be associated with the corresponding endpoint.\n *\n * @dev Only the owner/admin of the OApp can call this function.\n * @dev Indicates that the peer is trusted to send LayerZero messages to this OApp.\n * @dev Set this to bytes32(0) to remove the peer address.\n * @dev Peer is a bytes32 to accommodate non-evm chains.\n */\n function setPeer(uint32 _eid, bytes32 _peer) public virtual onlyOwner {\n OAppCoreStorage storage $ = _getOAppCoreStorage();\n $.peers[_eid] = _peer;\n emit PeerSet(_eid, _peer);\n }\n\n /**\n * @notice Internal function to get the peer address associated with a specific endpoint; reverts if NOT set.\n * ie. the peer is set to bytes32(0).\n * @param _eid The endpoint ID.\n * @return peer The address of the peer associated with the specified endpoint.\n */\n function _getPeerOrRevert(uint32 _eid) internal view virtual returns (bytes32) {\n OAppCoreStorage storage $ = _getOAppCoreStorage();\n bytes32 peer = $.peers[_eid];\n if (peer == bytes32(0)) revert NoPeer(_eid);\n return peer;\n }\n\n /**\n * @notice Sets the delegate address for the OApp.\n * @param _delegate The address of the delegate to be set.\n *\n * @dev Only the owner/admin of the OApp can call this function.\n * @dev Provides the ability for a delegate to set configs, on behalf of the OApp, directly on the Endpoint contract.\n */\n function setDelegate(address _delegate) public onlyOwner {\n endpoint.setDelegate(_delegate);\n }\n}\n"
},
"@layerzerolabs/oapp-evm-upgradeable/contracts/oapp/OAppReceiverUpgradeable.sol": {
"content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.20;\n\nimport { IOAppReceiver, Origin } from \"@layerzerolabs/oapp-evm/contracts/oapp/interfaces/IOAppReceiver.sol\";\nimport { OAppCoreUpgradeable } from \"./OAppCoreUpgradeable.sol\";\n\n/**\n * @title OAppReceiver\n * @dev Abstract contract implementing the ILayerZeroReceiver interface and extending OAppCore for OApp receivers.\n */\nabstract contract OAppReceiverUpgradeable is IOAppReceiver, OAppCoreUpgradeable {\n // Custom error message for when the caller is not the registered endpoint/\n error OnlyEndpoint(address addr);\n\n // @dev The version of the OAppReceiver implementation.\n // @dev Version is bumped when changes are made to this contract.\n uint64 internal constant RECEIVER_VERSION = 2;\n\n /**\n * @param _delegate The delegate capable of making OApp configurations inside of the endpoint.\n * @dev Ownable is not initialized here on purpose. It should be initialized in the child contract to\n * accommodate the different version of Ownable.\n */\n function __OAppReceiver_init(address _delegate) internal onlyInitializing {\n __OAppCore_init(_delegate);\n }\n\n function __OAppReceiver_init_unchained() internal onlyInitializing {}\n\n /**\n * @notice Retrieves the OApp version information.\n * @return senderVersion The version of the OAppSender.sol contract.\n * @return receiverVersion The version of the OAppReceiver.sol contract.\n *\n * @dev Providing 0 as the default for OAppSender version. Indicates that the OAppSender is not implemented.\n * ie. this is a RECEIVE only OApp.\n * @dev If the OApp uses both OAppSender and OAppReceiver, then this needs to be override returning the correct versions.\n */\n function oAppVersion() public view virtual returns (uint64 senderVersion, uint64 receiverVersion) {\n return (0, RECEIVER_VERSION);\n }\n\n /**\n * @notice Indicates whether an address is an approved composeMsg sender to the Endpoint.\n * @dev _origin The origin information containing the source endpoint and sender address.\n * - srcEid: The source chain endpoint ID.\n * - sender: The sender address on the src chain.\n * - nonce: The nonce of the message.\n * @dev _message The lzReceive payload.\n * @param _sender The sender address.\n * @return isSender Is a valid sender.\n *\n * @dev Applications can optionally choose to implement separate composeMsg senders that are NOT the bridging layer.\n * @dev The default sender IS the OAppReceiver implementer.\n */\n function isComposeMsgSender(\n Origin calldata /*_origin*/,\n bytes calldata /*_message*/,\n address _sender\n ) public view virtual returns (bool) {\n return _sender == address(this);\n }\n\n /**\n * @notice Checks if the path initialization is allowed based on the provided origin.\n * @param origin The origin information containing the source endpoint and sender address.\n * @return Whether the path has been initialized.\n *\n * @dev This indicates to the endpoint that the OApp has enabled msgs for this particular path to be received.\n * @dev This defaults to assuming if a peer has been set, its initialized.\n * Can be overridden by the OApp if there is other logic to determine this.\n */\n function allowInitializePath(Origin calldata origin) public view virtual returns (bool) {\n return peers(origin.srcEid) == origin.sender;\n }\n\n /**\n * @notice Retrieves the next nonce for a given source endpoint and sender address.\n * @dev _srcEid The source endpoint ID.\n * @dev _sender The sender address.\n * @return nonce The next nonce.\n *\n * @dev The path nonce starts from 1. If 0 is returned it means that there is NO nonce ordered enforcement.\n * @dev Is required by the off-chain executor to determine the OApp expects msg execution is ordered.\n * @dev This is also enforced by the OApp.\n * @dev By default this is NOT enabled. ie. nextNonce is hardcoded to return 0.\n */\n function nextNonce(uint32, /*_srcEid*/ bytes32 /*_sender*/) public view virtual returns (uint64 nonce) {\n return 0;\n }\n\n /**\n * @dev Entry point for receiving messages or packets from the endpoint.\n * @param _origin The origin information containing the source endpoint and sender address.\n * - srcEid: The source chain endpoint ID.\n * - sender: The sender address on the src chain.\n * - nonce: The nonce of the message.\n * @param _guid The unique identifier for the received LayerZero message.\n * @param _message The payload of the received message.\n * @param _executor The address of the executor for the received message.\n * @param _extraData Additional arbitrary data provided by the corresponding executor.\n *\n * @dev Entry point for receiving msg/packet from the LayerZero endpoint.\n */\n function lzReceive(\n Origin calldata _origin,\n bytes32 _guid,\n bytes calldata _message,\n address _executor,\n bytes calldata _extraData\n ) public payable virtual {\n // Ensures that only the endpoint can attempt to lzReceive() messages to this OApp.\n if (address(endpoint) != msg.sender) revert OnlyEndpoint(msg.sender);\n\n // Ensure that the sender matches the expected peer for the source endpoint.\n if (_getPeerOrRevert(_origin.srcEid) != _origin.sender) revert OnlyPeer(_origin.srcEid, _origin.sender);\n\n // Call the internal OApp implementation of lzReceive.\n _lzReceive(_origin, _guid, _message, _executor, _extraData);\n }\n\n /**\n * @dev Internal function to implement lzReceive logic without needing to copy the basic parameter validation.\n */\n function _lzReceive(\n Origin calldata _origin,\n bytes32 _guid,\n bytes calldata _message,\n address _executor,\n bytes calldata _extraData\n ) internal virtual;\n}\n"
},
"@layerzerolabs/oapp-evm-upgradeable/contracts/oapp/OAppSenderUpgradeable.sol": {
"content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.20;\n\nimport { SafeERC20, IERC20 } from \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\nimport { MessagingParams, MessagingFee, MessagingReceipt } from \"@layerzerolabs/lz-evm-protocol-v2/contracts/interfaces/ILayerZeroEndpointV2.sol\";\nimport { OAppCoreUpgradeable } from \"./OAppCoreUpgradeable.sol\";\n\n/**\n * @title OAppSender\n * @dev Abstract contract implementing the OAppSender functionality for sending messages to a LayerZero endpoint.\n */\nabstract contract OAppSenderUpgradeable is OAppCoreUpgradeable {\n using SafeERC20 for IERC20;\n\n // Custom error messages\n error NotEnoughNative(uint256 msgValue);\n error LzTokenUnavailable();\n\n // @dev The version of the OAppSender implementation.\n // @dev Version is bumped when changes are made to this contract.\n uint64 internal constant SENDER_VERSION = 1;\n\n /**\n * @param _delegate The delegate capable of making OApp configurations inside of the endpoint.\n * @dev Ownable is not initialized here on purpose. It should be initialized in the child contract to\n * accommodate the different version of Ownable.\n */\n function __OAppSender_init(address _delegate) internal onlyInitializing {\n __OAppCore_init(_delegate);\n }\n\n function __OAppSender_init_unchained() internal onlyInitializing {}\n\n /**\n * @notice Retrieves the OApp version information.\n * @return senderVersion The version of the OAppSender.sol contract.\n * @return receiverVersion The version of the OAppReceiver.sol contract.\n *\n * @dev Providing 0 as the default for OAppReceiver version. Indicates that the OAppReceiver is not implemented.\n * ie. this is a SEND only OApp.\n * @dev If the OApp uses both OAppSender and OAppReceiver, then this needs to be override returning the correct versions\n */\n function oAppVersion() public view virtual returns (uint64 senderVersion, uint64 receiverVersion) {\n return (SENDER_VERSION, 0);\n }\n\n /**\n * @dev Internal function to interact with the LayerZero EndpointV2.quote() for fee calculation.\n * @param _dstEid The destination endpoint ID.\n * @param _message The message payload.\n * @param _options Additional options for the message.\n * @param _payInLzToken Flag indicating whether to pay the fee in LZ tokens.\n * @return fee The calculated MessagingFee for the message.\n * - nativeFee: The native fee for the message.\n * - lzTokenFee: The LZ token fee for the message.\n */\n function _quote(\n uint32 _dstEid,\n bytes memory _message,\n bytes memory _options,\n bool _payInLzToken\n ) internal view virtual returns (MessagingFee memory fee) {\n return\n endpoint.quote(\n MessagingParams(_dstEid, _getPeerOrRevert(_dstEid), _message, _options, _payInLzToken),\n address(this)\n );\n }\n\n /**\n * @dev Internal function to interact with the LayerZero EndpointV2.send() for sending a message.\n * @param _dstEid The destination endpoint ID.\n * @param _message The message payload.\n * @param _options Additional options for the message.\n * @param _fee The calculated LayerZero fee for the message.\n * - nativeFee: The native fee.\n * - lzTokenFee: The lzToken fee.\n * @param _refundAddress The address to receive any excess fee values sent to the endpoint.\n * @return receipt The receipt for the sent message.\n * - guid: The unique identifier for the sent message.\n * - nonce: The nonce of the sent message.\n * - fee: The LayerZero fee incurred for the message.\n */\n function _lzSend(\n uint32 _dstEid,\n bytes memory _message,\n bytes memory _options,\n MessagingFee memory _fee,\n address _refundAddress\n ) internal virtual returns (MessagingReceipt memory receipt) {\n // @dev Push corresponding fees to the endpoint, any excess is sent back to the _refundAddress from the endpoint.\n uint256 messageValue = _payNative(_fee.nativeFee);\n if (_fee.lzTokenFee > 0) _payLzToken(_fee.lzTokenFee);\n\n return\n // solhint-disable-next-line check-send-result\n endpoint.send{ value: messageValue }(\n MessagingParams(_dstEid, _getPeerOrRevert(_dstEid), _message, _options, _fee.lzTokenFee > 0),\n _refundAddress\n );\n }\n\n /**\n * @dev Internal function to pay the native fee associated with the message.\n * @param _nativeFee The native fee to be paid.\n * @return nativeFee The amount of native currency paid.\n *\n * @dev If the OApp needs to initiate MULTIPLE LayerZero messages in a single transaction,\n * this will need to be overridden because msg.value would contain multiple lzFees.\n * @dev Should be overridden in the event the LayerZero endpoint requires a different native currency.\n * @dev Some EVMs use an ERC20 as a method for paying transactions/gasFees.\n * @dev The endpoint is EITHER/OR, ie. it will NOT support both types of native payment at a time.\n */\n function _payNative(uint256 _nativeFee) internal virtual returns (uint256 nativeFee) {\n if (msg.value != _nativeFee) revert NotEnoughNative(msg.value);\n return _nativeFee;\n }\n\n /**\n * @dev Internal function to pay the LZ token fee associated with the message.\n * @param _lzTokenFee The LZ token fee to be paid.\n *\n * @dev If the caller is trying to pay in the specified lzToken, then the lzTokenFee is passed to the endpoint.\n * @dev Any excess sent, is passed back to the specified _refundAddress in the _lzSend().\n */\n function _payLzToken(uint256 _lzTokenFee) internal virtual {\n // @dev Cannot cache the token because it is not immutable in the endpoint.\n address lzToken = endpoint.lzToken();\n if (lzToken == address(0)) revert LzTokenUnavailable();\n\n // Pay LZ token fee by sending tokens to the endpoint.\n IERC20(lzToken).safeTransferFrom(msg.sender, address(endpoint), _lzTokenFee);\n }\n}\n"
},
"@layerzerolabs/oapp-evm-upgradeable/contracts/oapp/OAppUpgradeable.sol": {
"content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.20;\n\n// @dev Import the 'MessagingFee' and 'MessagingReceipt' so it's exposed to OApp implementers\n// solhint-disable-next-line no-unused-import\nimport { OAppSenderUpgradeable, MessagingFee, MessagingReceipt } from \"./OAppSenderUpgradeable.sol\";\n// @dev Import the 'Origin' so it's exposed to OApp implementers\n// solhint-disable-next-line no-unused-import\nimport { OAppReceiverUpgradeable, Origin } from \"./OAppReceiverUpgradeable.sol\";\nimport { OAppCoreUpgradeable } from \"./OAppCoreUpgradeable.sol\";\n\n/**\n * @title OApp\n * @dev Abstract contract serving as the base for OApp implementation, combining OAppSender and OAppReceiver functionality.\n */\nabstract contract OAppUpgradeable is OAppSenderUpgradeable, OAppReceiverUpgradeable {\n /**\n * @dev Constructor to initialize the OApp with the provided endpoint and owner.\n * @param _endpoint The address of the LOCAL LayerZero endpoint.\n */\n constructor(address _endpoint) OAppCoreUpgradeable(_endpoint) {}\n\n /**\n * @dev Initializes the OApp with the provided delegate.\n * @param _delegate The delegate capable of making OApp configurations inside of the endpoint.\n *\n * @dev The delegate typically should be set as the owner of the contract.\n * @dev Ownable is not initialized here on purpose. It should be initialized in the child contract to\n * accommodate the different version of Ownable.\n */\n function __OApp_init(address _delegate) internal onlyInitializing {\n __OAppCore_init(_delegate);\n __OAppReceiver_init_unchained();\n __OAppSender_init_unchained();\n }\n\n function __OApp_init_unchained() internal onlyInitializing {}\n\n /**\n * @notice Retrieves the OApp version information.\n * @return senderVersion The version of the OAppSender.sol implementation.\n * @return receiverVersion The version of the OAppReceiver.sol implementation.\n */\n function oAppVersion()\n public\n pure\n virtual\n override(OAppSenderUpgradeable, OAppReceiverUpgradeable)\n returns (uint64 senderVersion, uint64 receiverVersion)\n {\n return (SENDER_VERSION, RECEIVER_VERSION);\n }\n}\n"
},
"@layerzerolabs/oapp-evm/contracts/oapp/interfaces/IOAppCore.sol": {
"content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.20;\n\nimport { ILayerZeroEndpointV2 } from \"@layerzerolabs/lz-evm-protocol-v2/contracts/interfaces/ILayerZeroEndpointV2.sol\";\n\n/**\n * @title IOAppCore\n */\ninterface IOAppCore {\n // Custom error messages\n error OnlyPeer(uint32 eid, bytes32 sender);\n error NoPeer(uint32 eid);\n error InvalidEndpointCall();\n error InvalidDelegate();\n\n // Event emitted when a peer (OApp) is set for a corresponding endpoint\n event PeerSet(uint32 eid, bytes32 peer);\n\n /**\n * @notice Retrieves the OApp version information.\n * @return senderVersion The version of the OAppSender.sol contract.\n * @return receiverVersion The version of the OAppReceiver.sol contract.\n */\n function oAppVersion() external view returns (uint64 senderVersion, uint64 receiverVersion);\n\n /**\n * @notice Retrieves the LayerZero endpoint associated with the OApp.\n * @return iEndpoint The LayerZero endpoint as an interface.\n */\n function endpoint() external view returns (ILayerZeroEndpointV2 iEndpoint);\n\n /**\n * @notice Retrieves the peer (OApp) associated with a corresponding endpoint.\n * @param _eid The endpoint ID.\n * @return peer The peer address (OApp instance) associated with the corresponding endpoint.\n */\n function peers(uint32 _eid) external view returns (bytes32 peer);\n\n /**\n * @notice Sets the peer address (OApp instance) for a corresponding endpoint.\n * @param _eid The endpoint ID.\n * @param _peer The address of the peer to be associated with the corresponding endpoint.\n */\n function setPeer(uint32 _eid, bytes32 _peer) external;\n\n /**\n * @notice Sets the delegate address for the OApp Core.\n * @param _delegate The address of the delegate to be set.\n */\n function setDelegate(address _delegate) external;\n}\n"
},
"@layerzerolabs/oapp-evm/contracts/oapp/interfaces/IOAppReceiver.sol": {
"content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.20;\n\nimport { ILayerZeroReceiver, Origin } from \"@layerzerolabs/lz-evm-protocol-v2/contracts/interfaces/ILayerZeroReceiver.sol\";\n\ninterface IOAppReceiver is ILayerZeroReceiver {\n /**\n * @notice Indicates whether an address is an approved composeMsg sender to the Endpoint.\n * @param _origin The origin information containing the source endpoint and sender address.\n * - srcEid: The source chain endpoint ID.\n * - sender: The sender address on the src chain.\n * - nonce: The nonce of the message.\n * @param _message The lzReceive payload.\n * @param _sender The sender address.\n * @return isSender Is a valid sender.\n *\n * @dev Applications can optionally choose to implement a separate composeMsg sender that is NOT the bridging layer.\n * @dev The default sender IS the OAppReceiver implementer.\n */\n function isComposeMsgSender(\n Origin calldata _origin,\n bytes calldata _message,\n address _sender\n ) external view returns (bool isSender);\n}\n"
},
"@layerzerolabs/oapp-evm/contracts/oapp/libs/OptionsBuilder.sol": {
"content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.20;\n\nimport { BytesLib } from \"solidity-bytes-utils/contracts/BytesLib.sol\";\nimport { SafeCast } from \"@openzeppelin/contracts/utils/math/SafeCast.sol\";\n\nimport { ExecutorOptions } from \"@layerzerolabs/lz-evm-messagelib-v2/contracts/libs/ExecutorOptions.sol\";\nimport { DVNOptions } from \"@layerzerolabs/lz-evm-messagelib-v2/contracts/uln/libs/DVNOptions.sol\";\n\n/**\n * @title OptionsBuilder\n * @dev Library for building and encoding various message options.\n */\nlibrary OptionsBuilder {\n using SafeCast for uint256;\n using BytesLib for bytes;\n\n // Constants for options types\n uint16 internal constant TYPE_1 = 1; // legacy options type 1\n uint16 internal constant TYPE_2 = 2; // legacy options type 2\n uint16 internal constant TYPE_3 = 3;\n\n // Custom error message\n error InvalidSize(uint256 max, uint256 actual);\n error InvalidOptionType(uint16 optionType);\n\n // Modifier to ensure only options of type 3 are used\n modifier onlyType3(bytes memory _options) {\n if (_options.toUint16(0) != TYPE_3) revert InvalidOptionType(_options.toUint16(0));\n _;\n }\n\n /**\n * @dev Creates a new options container with type 3.\n * @return options The newly created options container.\n */\n function newOptions() internal pure returns (bytes memory) {\n return abi.encodePacked(TYPE_3);\n }\n\n /**\n * @dev Adds an executor LZ receive option to the existing options.\n * @param _options The existing options container.\n * @param _gas The gasLimit used on the lzReceive() function in the OApp.\n * @param _value The msg.value passed to the lzReceive() function in the OApp.\n * @return options The updated options container.\n *\n * @dev When multiples of this option are added, they are summed by the executor\n * eg. if (_gas: 200k, and _value: 1 ether) AND (_gas: 100k, _value: 0.5 ether) are sent in an option to the LayerZeroEndpoint,\n * that becomes (300k, 1.5 ether) when the message is executed on the remote lzReceive() function.\n */\n function addExecutorLzReceiveOption(\n bytes memory _options,\n uint128 _gas,\n uint128 _value\n ) internal pure onlyType3(_options) returns (bytes memory) {\n bytes memory option = ExecutorOptions.encodeLzReceiveOption(_gas, _value);\n return addExecutorOption(_options, ExecutorOptions.OPTION_TYPE_LZRECEIVE, option);\n }\n\n /**\n * @dev Adds an executor native drop option to the existing options.\n * @param _options The existing options container.\n * @param _amount The amount for the native value that is airdropped to the 'receiver'.\n * @param _receiver The receiver address for the native drop option.\n * @return options The updated options container.\n *\n * @dev When multiples of this option are added, they are summed by the executor on the remote chain.\n */\n function addExecutorNativeDropOption(\n bytes memory _options,\n uint128 _amount,\n bytes32 _receiver\n ) internal pure onlyType3(_options) returns (bytes memory) {\n bytes memory option = ExecutorOptions.encodeNativeDropOption(_amount, _receiver);\n return addExecutorOption(_options, ExecutorOptions.OPTION_TYPE_NATIVE_DROP, option);\n }\n\n // /**\n // * @dev Adds an executor native drop option to the existing options.\n // * @param _options The existing options container.\n // * @param _amount The amount for the native value that is airdropped to the 'receiver'.\n // * @param _receiver The receiver address for the native drop option.\n // * @return options The updated options container.\n // *\n // * @dev When multiples of this option are added, they are summed by the executor on the remote chain.\n // */\n function addExecutorLzReadOption(\n bytes memory _options,\n uint128 _gas,\n uint32 _size,\n uint128 _value\n ) internal pure onlyType3(_options) returns (bytes memory) {\n bytes memory option = ExecutorOptions.encodeLzReadOption(_gas, _size, _value);\n return addExecutorOption(_options, ExecutorOptions.OPTION_TYPE_LZREAD, option);\n }\n\n /**\n * @dev Adds an executor LZ compose option to the existing options.\n * @param _options The existing options container.\n * @param _index The index for the lzCompose() function call.\n * @param _gas The gasLimit for the lzCompose() function call.\n * @param _value The msg.value for the lzCompose() function call.\n * @return options The updated options container.\n *\n * @dev When multiples of this option are added, they are summed PER index by the executor on the remote chain.\n * @dev If the OApp sends N lzCompose calls on the remote, you must provide N incremented indexes starting with 0.\n * ie. When your remote OApp composes (N = 3) messages, you must set this option for index 0,1,2\n */\n function addExecutorLzComposeOption(\n bytes memory _options,\n uint16 _index,\n uint128 _gas,\n uint128 _value\n ) internal pure onlyType3(_options) returns (bytes memory) {\n bytes memory option = ExecutorOptions.encodeLzComposeOption(_index, _gas, _value);\n return addExecutorOption(_options, ExecutorOptions.OPTION_TYPE_LZCOMPOSE, option);\n }\n\n /**\n * @dev Adds an executor ordered execution option to the existing options.\n * @param _options The existing options container.\n * @return options The updated options container.\n */\n function addExecutorOrderedExecutionOption(\n bytes memory _options\n ) internal pure onlyType3(_options) returns (bytes memory) {\n return addExecutorOption(_options, ExecutorOptions.OPTION_TYPE_ORDERED_EXECUTION, bytes(\"\"));\n }\n\n /**\n * @dev Adds a DVN pre-crime option to the existing options.\n * @param _options The existing options container.\n * @param _dvnIdx The DVN index for the pre-crime option.\n * @return options The updated options container.\n */\n function addDVNPreCrimeOption(\n bytes memory _options,\n uint8 _dvnIdx\n ) internal pure onlyType3(_options) returns (bytes memory) {\n return addDVNOption(_options, _dvnIdx, DVNOptions.OPTION_TYPE_PRECRIME, bytes(\"\"));\n }\n\n /**\n * @dev Adds an executor option to the existing options.\n * @param _options The existing options container.\n * @param _optionType The type of the executor option.\n * @param _option The encoded data for the executor option.\n * @return options The updated options container.\n */\n function addExecutorOption(\n bytes memory _options,\n uint8 _optionType,\n bytes memory _option\n ) internal pure onlyType3(_options) returns (bytes memory) {\n return\n abi.encodePacked(\n _options,\n ExecutorOptions.WORKER_ID,\n _option.length.toUint16() + 1, // +1 for optionType\n _optionType,\n _option\n );\n }\n\n /**\n * @dev Adds a DVN option to the existing options.\n * @param _options The existing options container.\n * @param _dvnIdx The DVN index for the DVN option.\n * @param _optionType The type of the DVN option.\n * @param _option The encoded data for the DVN option.\n * @return options The updated options container.\n */\n function addDVNOption(\n bytes memory _options,\n uint8 _dvnIdx,\n uint8 _optionType,\n bytes memory _option\n ) internal pure onlyType3(_options) returns (bytes memory) {\n return\n abi.encodePacked(\n _options,\n DVNOptions.WORKER_ID,\n _option.length.toUint16() + 2, // +2 for optionType and dvnIdx\n _dvnIdx,\n _optionType,\n _option\n );\n }\n\n /**\n * @dev Encodes legacy options of type 1.\n * @param _executionGas The gasLimit value passed to lzReceive().\n * @return legacyOptions The encoded legacy options.\n */\n function encodeLegacyOptionsType1(uint256 _executionGas) internal pure returns (bytes memory) {\n if (_executionGas > type(uint128).max) revert InvalidSize(type(uint128).max, _executionGas);\n return abi.encodePacked(TYPE_1, _executionGas);\n }\n\n /**\n * @dev Encodes legacy options of type 2.\n * @param _executionGas The gasLimit value passed to lzReceive().\n * @param _nativeForDst The amount of native air dropped to the receiver.\n * @param _receiver The _nativeForDst receiver address.\n * @return legacyOptions The encoded legacy options of type 2.\n */\n function encodeLegacyOptionsType2(\n uint256 _executionGas,\n uint256 _nativeForDst,\n bytes memory _receiver // @dev Use bytes instead of bytes32 in legacy type 2 for _receiver.\n ) internal pure returns (bytes memory) {\n if (_executionGas > type(uint128).max) revert InvalidSize(type(uint128).max, _executionGas);\n if (_nativeForDst > type(uint128).max) revert InvalidSize(type(uint128).max, _nativeForDst);\n if (_receiver.length > 32) revert InvalidSize(32, _receiver.length);\n return abi.encodePacked(TYPE_2, _executionGas, _nativeForDst, _receiver);\n }\n}\n"
},
"@layerzerolabs/solidity-examples/contracts/libraries/BytesLib.sol": {
"content": "// SPDX-License-Identifier: Unlicense\n/*\n * @title Solidity Bytes Arrays Utils\n * @author Gonçalo Sá <goncalo.sa@consensys.net>\n *\n * @dev Bytes tightly packed arrays utility library for ethereum contracts written in Solidity.\n * The library lets you concatenate, slice and type cast bytes arrays both in memory and storage.\n */\npragma solidity >=0.8.0 <0.9.0;\n\nlibrary BytesLib {\n function concat(bytes memory _preBytes, bytes memory _postBytes) internal pure returns (bytes memory) {\n bytes memory tempBytes;\n\n assembly {\n // Get a location of some free memory and store it in tempBytes as\n // Solidity does for memory variables.\n tempBytes := mload(0x40)\n\n // Store the length of the first bytes array at the beginning of\n // the memory for tempBytes.\n let length := mload(_preBytes)\n mstore(tempBytes, length)\n\n // Maintain a memory counter for the current write location in the\n // temp bytes array by adding the 32 bytes for the array length to\n // the starting location.\n let mc := add(tempBytes, 0x20)\n // Stop copying when the memory counter reaches the length of the\n // first bytes array.\n let end := add(mc, length)\n\n for {\n // Initialize a copy counter to the start of the _preBytes data,\n // 32 bytes into its memory.\n let cc := add(_preBytes, 0x20)\n } lt(mc, end) {\n // Increase both counters by 32 bytes each iteration.\n mc := add(mc, 0x20)\n cc := add(cc, 0x20)\n } {\n // Write the _preBytes data into the tempBytes memory 32 bytes\n // at a time.\n mstore(mc, mload(cc))\n }\n\n // Add the length of _postBytes to the current length of tempBytes\n // and store it as the new length in the first 32 bytes of the\n // tempBytes memory.\n length := mload(_postBytes)\n mstore(tempBytes, add(length, mload(tempBytes)))\n\n // Move the memory counter back from a multiple of 0x20 to the\n // actual end of the _preBytes data.\n mc := end\n // Stop copying when the memory counter reaches the new combined\n // length of the arrays.\n end := add(mc, length)\n\n for {\n let cc := add(_postBytes, 0x20)\n } lt(mc, end) {\n mc := add(mc, 0x20)\n cc := add(cc, 0x20)\n } {\n mstore(mc, mload(cc))\n }\n\n // Update the free-memory pointer by padding our last write location\n // to 32 bytes: add 31 bytes to the end of tempBytes to move to the\n // next 32 byte block, then round down to the nearest multiple of\n // 32. If the sum of the length of the two arrays is zero then add\n // one before rounding down to leave a blank 32 bytes (the length block with 0).\n mstore(\n 0x40,\n and(\n add(add(end, iszero(add(length, mload(_preBytes)))), 31),\n not(31) // Round down to the nearest 32 bytes.\n )\n )\n }\n\n return tempBytes;\n }\n\n function concatStorage(bytes storage _preBytes, bytes memory _postBytes) internal {\n assembly {\n // Read the first 32 bytes of _preBytes storage, which is the length\n // of the array. (We don't need to use the offset into the slot\n // because arrays use the entire slot.)\n let fslot := sload(_preBytes.slot)\n // Arrays of 31 bytes or less have an even value in their slot,\n // while longer arrays have an odd value. The actual length is\n // the slot divided by two for odd values, and the lowest order\n // byte divided by two for even values.\n // If the slot is even, bitwise and the slot with 255 and divide by\n // two to get the length. If the slot is odd, bitwise and the slot\n // with -1 and divide by two.\n let slength := div(and(fslot, sub(mul(0x100, iszero(and(fslot, 1))), 1)), 2)\n let mlength := mload(_postBytes)\n let newlength := add(slength, mlength)\n // slength can contain both the length and contents of the array\n // if length < 32 bytes so let's prepare for that\n // v. http://solidity.readthedocs.io/en/latest/miscellaneous.html#layout-of-state-variables-in-storage\n switch add(lt(slength, 32), lt(newlength, 32))\n case 2 {\n // Since the new array still fits in the slot, we just need to\n // update the contents of the slot.\n // uint256(bytes_storage) = uint256(bytes_storage) + uint256(bytes_memory) + new_length\n sstore(\n _preBytes.slot,\n // all the modifications to the slot are inside this\n // next block\n add(\n // we can just add to the slot contents because the\n // bytes we want to change are the LSBs\n fslot,\n add(\n mul(\n div(\n // load the bytes from memory\n mload(add(_postBytes, 0x20)),\n // zero all bytes to the right\n exp(0x100, sub(32, mlength))\n ),\n // and now shift left the number of bytes to\n // leave space for the length in the slot\n exp(0x100, sub(32, newlength))\n ),\n // increase length by the double of the memory\n // bytes length\n mul(mlength, 2)\n )\n )\n )\n }\n case 1 {\n // The stored value fits in the slot, but the combined value\n // will exceed it.\n // get the keccak hash to get the contents of the array\n mstore(0x0, _preBytes.slot)\n let sc := add(keccak256(0x0, 0x20), div(slength, 32))\n\n // save new length\n sstore(_preBytes.slot, add(mul(newlength, 2), 1))\n\n // The contents of the _postBytes array start 32 bytes into\n // the structure. Our first read should obtain the `submod`\n // bytes that can fit into the unused space in the last word\n // of the stored array. To get this, we read 32 bytes starting\n // from `submod`, so the data we read overlaps with the array\n // contents by `submod` bytes. Masking the lowest-order\n // `submod` bytes allows us to add that value directly to the\n // stored value.\n\n let submod := sub(32, slength)\n let mc := add(_postBytes, submod)\n let end := add(_postBytes, mlength)\n let mask := sub(exp(0x100, submod), 1)\n\n sstore(sc, add(and(fslot, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00), and(mload(mc), mask)))\n\n for {\n mc := add(mc, 0x20)\n sc := add(sc, 1)\n } lt(mc, end) {\n sc := add(sc, 1)\n mc := add(mc, 0x20)\n } {\n sstore(sc, mload(mc))\n }\n\n mask := exp(0x100, sub(mc, end))\n\n sstore(sc, mul(div(mload(mc), mask), mask))\n }\n default {\n // get the keccak hash to get the contents of the array\n mstore(0x0, _preBytes.slot)\n // Start copying to the last used word of the stored array.\n let sc := add(keccak256(0x0, 0x20), div(slength, 32))\n\n // save new length\n sstore(_preBytes.slot, add(mul(newlength, 2), 1))\n\n // Copy over the first `submod` bytes of the new data as in\n // case 1 above.\n let slengthmod := mod(slength, 32)\n let mlengthmod := mod(mlength, 32)\n let submod := sub(32, slengthmod)\n let mc := add(_postBytes, submod)\n let end := add(_postBytes, mlength)\n let mask := sub(exp(0x100, submod), 1)\n\n sstore(sc, add(sload(sc), and(mload(mc), mask)))\n\n for {\n sc := add(sc, 1)\n mc := add(mc, 0x20)\n } lt(mc, end) {\n sc := add(sc, 1)\n mc := add(mc, 0x20)\n } {\n sstore(sc, mload(mc))\n }\n\n mask := exp(0x100, sub(mc, end))\n\n sstore(sc, mul(div(mload(mc), mask), mask))\n }\n }\n }\n\n function slice(\n bytes memory _bytes,\n uint _start,\n uint _length\n ) internal pure returns (bytes memory) {\n require(_length + 31 >= _length, \"slice_overflow\");\n require(_bytes.length >= _start + _length, \"slice_outOfBounds\");\n\n bytes memory tempBytes;\n\n assembly {\n switch iszero(_length)\n case 0 {\n // Get a location of some free memory and store it in tempBytes as\n // Solidity does for memory variables.\n tempBytes := mload(0x40)\n\n // The first word of the slice result is potentially a partial\n // word read from the original array. To read it, we calculate\n // the length of that partial word and start copying that many\n // bytes into the array. The first word we copy will start with\n // data we don't care about, but the last `lengthmod` bytes will\n // land at the beginning of the contents of the new array. When\n // we're done copying, we overwrite the full first word with\n // the actual length of the slice.\n let lengthmod := and(_length, 31)\n\n // The multiplication in the next line is necessary\n // because when slicing multiples of 32 bytes (lengthmod == 0)\n // the following copy loop was copying the origin's length\n // and then ending prematurely not copying everything it should.\n let mc := add(add(tempBytes, lengthmod), mul(0x20, iszero(lengthmod)))\n let end := add(mc, _length)\n\n for {\n // The multiplication in the next line has the same exact purpose\n // as the one above.\n let cc := add(add(add(_bytes, lengthmod), mul(0x20, iszero(lengthmod))), _start)\n } lt(mc, end) {\n mc := add(mc, 0x20)\n cc := add(cc, 0x20)\n } {\n mstore(mc, mload(cc))\n }\n\n mstore(tempBytes, _length)\n\n //update free-memory pointer\n //allocating the array padded to 32 bytes like the compiler does now\n mstore(0x40, and(add(mc, 31), not(31)))\n }\n //if we want a zero-length slice let's just return a zero-length array\n default {\n tempBytes := mload(0x40)\n //zero out the 32 bytes slice we are about to return\n //we need to do it because Solidity does not garbage collect\n mstore(tempBytes, 0)\n\n mstore(0x40, add(tempBytes, 0x20))\n }\n }\n\n return tempBytes;\n }\n\n function toAddress(bytes memory _bytes, uint _start) internal pure returns (address) {\n require(_bytes.length >= _start + 20, \"toAddress_outOfBounds\");\n address tempAddress;\n\n assembly {\n tempAddress := div(mload(add(add(_bytes, 0x20), _start)), 0x1000000000000000000000000)\n }\n\n return tempAddress;\n }\n\n function toUint8(bytes memory _bytes, uint _start) internal pure returns (uint8) {\n require(_bytes.length >= _start + 1, \"toUint8_outOfBounds\");\n uint8 tempUint;\n\n assembly {\n tempUint := mload(add(add(_bytes, 0x1), _start))\n }\n\n return tempUint;\n }\n\n function toUint16(bytes memory _bytes, uint _start) internal pure returns (uint16) {\n require(_bytes.length >= _start + 2, \"toUint16_outOfBounds\");\n uint16 tempUint;\n\n assembly {\n tempUint := mload(add(add(_bytes, 0x2), _start))\n }\n\n return tempUint;\n }\n\n function toUint32(bytes memory _bytes, uint _start) internal pure returns (uint32) {\n require(_bytes.length >= _start + 4, \"toUint32_outOfBounds\");\n uint32 tempUint;\n\n assembly {\n tempUint := mload(add(add(_bytes, 0x4), _start))\n }\n\n return tempUint;\n }\n\n function toUint64(bytes memory _bytes, uint _start) internal pure returns (uint64) {\n require(_bytes.length >= _start + 8, \"toUint64_outOfBounds\");\n uint64 tempUint;\n\n assembly {\n tempUint := mload(add(add(_bytes, 0x8), _start))\n }\n\n return tempUint;\n }\n\n function toUint96(bytes memory _bytes, uint _start) internal pure returns (uint96) {\n require(_bytes.length >= _start + 12, \"toUint96_outOfBounds\");\n uint96 tempUint;\n\n assembly {\n tempUint := mload(add(add(_bytes, 0xc), _start))\n }\n\n return tempUint;\n }\n\n function toUint128(bytes memory _bytes, uint _start) internal pure returns (uint128) {\n require(_bytes.length >= _start + 16, \"toUint128_outOfBounds\");\n uint128 tempUint;\n\n assembly {\n tempUint := mload(add(add(_bytes, 0x10), _start))\n }\n\n return tempUint;\n }\n\n function toUint256(bytes memory _bytes, uint _start) internal pure returns (uint) {\n require(_bytes.length >= _start + 32, \"toUint256_outOfBounds\");\n uint tempUint;\n\n assembly {\n tempUint := mload(add(add(_bytes, 0x20), _start))\n }\n\n return tempUint;\n }\n\n function toBytes32(bytes memory _bytes, uint _start) internal pure returns (bytes32) {\n require(_bytes.length >= _start + 32, \"toBytes32_outOfBounds\");\n bytes32 tempBytes32;\n\n assembly {\n tempBytes32 := mload(add(add(_bytes, 0x20), _start))\n }\n\n return tempBytes32;\n }\n\n function equal(bytes memory _preBytes, bytes memory _postBytes) internal pure returns (bool) {\n bool success = true;\n\n assembly {\n let length := mload(_preBytes)\n\n // if lengths don't match the arrays are not equal\n switch eq(length, mload(_postBytes))\n case 1 {\n // cb is a circuit breaker in the for loop since there's\n // no said feature for inline assembly loops\n // cb = 1 - don't breaker\n // cb = 0 - break\n let cb := 1\n\n let mc := add(_preBytes, 0x20)\n let end := add(mc, length)\n\n for {\n let cc := add(_postBytes, 0x20)\n // the next line is the loop condition:\n // while(uint256(mc < end) + cb == 2)\n } eq(add(lt(mc, end), cb), 2) {\n mc := add(mc, 0x20)\n cc := add(cc, 0x20)\n } {\n // if any of these checks fails then arrays are not equal\n if iszero(eq(mload(mc), mload(cc))) {\n // unsuccess:\n success := 0\n cb := 0\n }\n }\n }\n default {\n // unsuccess:\n success := 0\n }\n }\n\n return success;\n }\n\n function equalStorage(bytes storage _preBytes, bytes memory _postBytes) internal view returns (bool) {\n bool success = true;\n\n assembly {\n // we know _preBytes_offset is 0\n let fslot := sload(_preBytes.slot)\n // Decode the length of the stored array like in concatStorage().\n let slength := div(and(fslot, sub(mul(0x100, iszero(and(fslot, 1))), 1)), 2)\n let mlength := mload(_postBytes)\n\n // if lengths don't match the arrays are not equal\n switch eq(slength, mlength)\n case 1 {\n // slength can contain both the length and contents of the array\n // if length < 32 bytes so let's prepare for that\n // v. http://solidity.readthedocs.io/en/latest/miscellaneous.html#layout-of-state-variables-in-storage\n if iszero(iszero(slength)) {\n switch lt(slength, 32)\n case 1 {\n // blank the last byte which is the length\n fslot := mul(div(fslot, 0x100), 0x100)\n\n if iszero(eq(fslot, mload(add(_postBytes, 0x20)))) {\n // unsuccess:\n success := 0\n }\n }\n default {\n // cb is a circuit breaker in the for loop since there's\n // no said feature for inline assembly loops\n // cb = 1 - don't breaker\n // cb = 0 - break\n let cb := 1\n\n // get the keccak hash to get the contents of the array\n mstore(0x0, _preBytes.slot)\n let sc := keccak256(0x0, 0x20)\n\n let mc := add(_postBytes, 0x20)\n let end := add(mc, mlength)\n\n // the next line is the loop condition:\n // while(uint256(mc < end) + cb == 2)\n for {\n\n } eq(add(lt(mc, end), cb), 2) {\n sc := add(sc, 1)\n mc := add(mc, 0x20)\n } {\n if iszero(eq(sload(sc), mload(mc))) {\n // unsuccess:\n success := 0\n cb := 0\n }\n }\n }\n }\n }\n default {\n // unsuccess:\n success := 0\n }\n }\n\n return success;\n }\n}\n"
},
"@layerzerolabs/solidity-examples/contracts/libraries/ExcessivelySafeCall.sol": {
"content": "// SPDX-License-Identifier: MIT OR Apache-2.0\npragma solidity >=0.7.6;\n\nlibrary ExcessivelySafeCall {\n uint constant LOW_28_MASK = 0x00000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffff;\n\n /// @notice Use when you _really_ really _really_ don't trust the called\n /// contract. This prevents the called contract from causing reversion of\n /// the caller in as many ways as we can.\n /// @dev The main difference between this and a solidity low-level call is\n /// that we limit the number of bytes that the callee can cause to be\n /// copied to caller memory. This prevents stupid things like malicious\n /// contracts returning 10,000,000 bytes causing a local OOG when copying\n /// to memory.\n /// @param _target The address to call\n /// @param _gas The amount of gas to forward to the remote contract\n /// @param _maxCopy The maximum number of bytes of returndata to copy\n /// to memory.\n /// @param _calldata The data to send to the remote contract\n /// @return success and returndata, as `.call()`. Returndata is capped to\n /// `_maxCopy` bytes.\n function excessivelySafeCall(\n address _target,\n uint _gas,\n uint16 _maxCopy,\n bytes memory _calldata\n ) internal returns (bool, bytes memory) {\n // set up for assembly call\n uint _toCopy;\n bool _success;\n bytes memory _returnData = new bytes(_maxCopy);\n // dispatch message to recipient\n // by assembly calling \"handle\" function\n // we call via assembly to avoid memcopying a very large returndata\n // returned by a malicious contract\n assembly {\n _success := call(\n _gas, // gas\n _target, // recipient\n 0, // ether value\n add(_calldata, 0x20), // inloc\n mload(_calldata), // inlen\n 0, // outloc\n 0 // outlen\n )\n // limit our copy to 256 bytes\n _toCopy := returndatasize()\n if gt(_toCopy, _maxCopy) {\n _toCopy := _maxCopy\n }\n // Store the length of the copied bytes\n mstore(_returnData, _toCopy)\n // copy the bytes from returndata[0:_toCopy]\n returndatacopy(add(_returnData, 0x20), 0, _toCopy)\n }\n return (_success, _returnData);\n }\n\n /// @notice Use when you _really_ really _really_ don't trust the called\n /// contract. This prevents the called contract from causing reversion of\n /// the caller in as many ways as we can.\n /// @dev The main difference between this and a solidity low-level call is\n /// that we limit the number of bytes that the callee can cause to be\n /// copied to caller memory. This prevents stupid things like malicious\n /// contracts returning 10,000,000 bytes causing a local OOG when copying\n /// to memory.\n /// @param _target The address to call\n /// @param _gas The amount of gas to forward to the remote contract\n /// @param _maxCopy The maximum number of bytes of returndata to copy\n /// to memory.\n /// @param _calldata The data to send to the remote contract\n /// @return success and returndata, as `.call()`. Returndata is capped to\n /// `_maxCopy` bytes.\n function excessivelySafeStaticCall(\n address _target,\n uint _gas,\n uint16 _maxCopy,\n bytes memory _calldata\n ) internal view returns (bool, bytes memory) {\n // set up for assembly call\n uint _toCopy;\n bool _success;\n bytes memory _returnData = new bytes(_maxCopy);\n // dispatch message to recipient\n // by assembly calling \"handle\" function\n // we call via assembly to avoid memcopying a very large returndata\n // returned by a malicious contract\n assembly {\n _success := staticcall(\n _gas, // gas\n _target, // recipient\n add(_calldata, 0x20), // inloc\n mload(_calldata), // inlen\n 0, // outloc\n 0 // outlen\n )\n // limit our copy to 256 bytes\n _toCopy := returndatasize()\n if gt(_toCopy, _maxCopy) {\n _toCopy := _maxCopy\n }\n // Store the length of the copied bytes\n mstore(_returnData, _toCopy)\n // copy the bytes from returndata[0:_toCopy]\n returndatacopy(add(_returnData, 0x20), 0, _toCopy)\n }\n return (_success, _returnData);\n }\n\n /**\n * @notice Swaps function selectors in encoded contract calls\n * @dev Allows reuse of encoded calldata for functions with identical\n * argument types but different names. It simply swaps out the first 4 bytes\n * for the new selector. This function modifies memory in place, and should\n * only be used with caution.\n * @param _newSelector The new 4-byte selector\n * @param _buf The encoded contract args\n */\n function swapSelector(bytes4 _newSelector, bytes memory _buf) internal pure {\n require(_buf.length >= 4);\n uint _mask = LOW_28_MASK;\n assembly {\n // load the first word of\n let _word := mload(add(_buf, 0x20))\n // mask out the top 4 bytes\n // /x\n _word := and(_word, _mask)\n _word := or(_newSelector, _word)\n mstore(add(_buf, 0x20), _word)\n }\n }\n}\n"
},
"@layerzerolabs/solidity-examples/contracts/lzApp/interfaces/ILayerZeroEndpoint.sol": {
"content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.5.0;\n\nimport \"./ILayerZeroUserApplicationConfig.sol\";\n\ninterface ILayerZeroEndpoint is ILayerZeroUserApplicationConfig {\n // @notice send a LayerZero message to the specified address at a LayerZero endpoint.\n // @param _dstChainId - the destination chain identifier\n // @param _destination - the address on destination chain (in bytes). address length/format may vary by chains\n // @param _payload - a custom bytes payload to send to the destination contract\n // @param _refundAddress - if the source transaction is cheaper than the amount of value passed, refund the additional amount to this address\n // @param _zroPaymentAddress - the address of the ZRO token holder who would pay for the transaction\n // @param _adapterParams - parameters for custom functionality. e.g. receive airdropped native gas from the relayer on destination\n function send(\n uint16 _dstChainId,\n bytes calldata _destination,\n bytes calldata _payload,\n address payable _refundAddress,\n address _zroPaymentAddress,\n bytes calldata _adapterParams\n ) external payable;\n\n // @notice used by the messaging library to publish verified payload\n // @param _srcChainId - the source chain identifier\n // @param _srcAddress - the source contract (as bytes) at the source chain\n // @param _dstAddress - the address on destination chain\n // @param _nonce - the unbound message ordering nonce\n // @param _gasLimit - the gas limit for external contract execution\n // @param _payload - verified payload to send to the destination contract\n function receivePayload(\n uint16 _srcChainId,\n bytes calldata _srcAddress,\n address _dstAddress,\n uint64 _nonce,\n uint _gasLimit,\n bytes calldata _payload\n ) external;\n\n // @notice get the inboundNonce of a lzApp from a source chain which could be EVM or non-EVM chain\n // @param _srcChainId - the source chain identifier\n // @param _srcAddress - the source chain contract address\n function getInboundNonce(uint16 _srcChainId, bytes calldata _srcAddress) external view returns (uint64);\n\n // @notice get the outboundNonce from this source chain which, consequently, is always an EVM\n // @param _srcAddress - the source chain contract address\n function getOutboundNonce(uint16 _dstChainId, address _srcAddress) external view returns (uint64);\n\n // @notice gets a quote in source native gas, for the amount that send() requires to pay for message delivery\n // @param _dstChainId - the destination chain identifier\n // @param _userApplication - the user app address on this EVM chain\n // @param _payload - the custom message to send over LayerZero\n // @param _payInZRO - if false, user app pays the protocol fee in native token\n // @param _adapterParam - parameters for the adapter service, e.g. send some dust native token to dstChain\n function estimateFees(\n uint16 _dstChainId,\n address _userApplication,\n bytes calldata _payload,\n bool _payInZRO,\n bytes calldata _adapterParam\n ) external view returns (uint nativeFee, uint zroFee);\n\n // @notice get this Endpoint's immutable source identifier\n function getChainId() external view returns (uint16);\n\n // @notice the interface to retry failed message on this Endpoint destination\n // @param _srcChainId - the source chain identifier\n // @param _srcAddress - the source chain contract address\n // @param _payload - the payload to be retried\n function retryPayload(\n uint16 _srcChainId,\n bytes calldata _srcAddress,\n bytes calldata _payload\n ) external;\n\n // @notice query if any STORED payload (message blocking) at the endpoint.\n // @param _srcChainId - the source chain identifier\n // @param _srcAddress - the source chain contract address\n function hasStoredPayload(uint16 _srcChainId, bytes calldata _srcAddress) external view returns (bool);\n\n // @notice query if the _libraryAddress is valid for sending msgs.\n // @param _userApplication - the user app address on this EVM chain\n function getSendLibraryAddress(address _userApplication) external view returns (address);\n\n // @notice query if the _libraryAddress is valid for receiving msgs.\n // @param _userApplication - the user app address on this EVM chain\n function getReceiveLibraryAddress(address _userApplication) external view returns (address);\n\n // @notice query if the non-reentrancy guard for send() is on\n // @return true if the guard is on. false otherwise\n function isSendingPayload() external view returns (bool);\n\n // @notice query if the non-reentrancy guard for receive() is on\n // @return true if the guard is on. false otherwise\n function isReceivingPayload() external view returns (bool);\n\n // @notice get the configuration of the LayerZero messaging library of the specified version\n // @param _version - messaging library version\n // @param _chainId - the chainId for the pending config change\n // @param _userApplication - the contract address of the user application\n // @param _configType - type of configuration. every messaging library has its own convention.\n function getConfig(\n uint16 _version,\n uint16 _chainId,\n address _userApplication,\n uint _configType\n ) external view returns (bytes memory);\n\n // @notice get the send() LayerZero messaging library version\n // @param _userApplication - the contract address of the user application\n function getSendVersion(address _userApplication) external view returns (uint16);\n\n // @notice get the lzReceive() LayerZero messaging library version\n // @param _userApplication - the contract address of the user application\n function getReceiveVersion(address _userApplication) external view returns (uint16);\n}\n"
},
"@layerzerolabs/solidity-examples/contracts/lzApp/interfaces/ILayerZeroReceiver.sol": {
"content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.5.0;\n\ninterface ILayerZeroReceiver {\n // @notice LayerZero endpoint will invoke this function to deliver the message on the destination\n // @param _srcChainId - the source endpoint identifier\n // @param _srcAddress - the source sending contract address from the source chain\n // @param _nonce - the ordered message nonce\n // @param _payload - the signed payload is the UA bytes has encoded to be sent\n function lzReceive(\n uint16 _srcChainId,\n bytes calldata _srcAddress,\n uint64 _nonce,\n bytes calldata _payload\n ) external;\n}\n"
},
"@layerzerolabs/solidity-examples/contracts/lzApp/interfaces/ILayerZeroUserApplicationConfig.sol": {
"content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.5.0;\n\ninterface ILayerZeroUserApplicationConfig {\n // @notice set the configuration of the LayerZero messaging library of the specified version\n // @param _version - messaging library version\n // @param _chainId - the chainId for the pending config change\n // @param _configType - type of configuration. every messaging library has its own convention.\n // @param _config - configuration in the bytes. can encode arbitrary content.\n function setConfig(\n uint16 _version,\n uint16 _chainId,\n uint _configType,\n bytes calldata _config\n ) external;\n\n // @notice set the send() LayerZero messaging library version to _version\n // @param _version - new messaging library version\n function setSendVersion(uint16 _version) external;\n\n // @notice set the lzReceive() LayerZero messaging library version to _version\n // @param _version - new messaging library version\n function setReceiveVersion(uint16 _version) external;\n\n // @notice Only when the UA needs to resume the message flow in blocking mode and clear the stored payload\n // @param _srcChainId - the chainId of the source chain\n // @param _srcAddress - the contract address of the source contract at the source chain\n function forceResumeReceive(uint16 _srcChainId, bytes calldata _srcAddress) external;\n}\n"
},
"@layerzerolabs/solidity-examples/contracts/lzApp/libs/LzLib.sol": {
"content": "// SPDX-License-Identifier: BUSL-1.1\n\npragma solidity >=0.6.0;\npragma experimental ABIEncoderV2;\n\nlibrary LzLib {\n // LayerZero communication\n struct CallParams {\n address payable refundAddress;\n address zroPaymentAddress;\n }\n\n //---------------------------------------------------------------------------\n // Address type handling\n\n struct AirdropParams {\n uint airdropAmount;\n bytes32 airdropAddress;\n }\n\n function buildAdapterParams(LzLib.AirdropParams memory _airdropParams, uint _uaGasLimit) internal pure returns (bytes memory adapterParams) {\n if (_airdropParams.airdropAmount == 0 && _airdropParams.airdropAddress == bytes32(0x0)) {\n adapterParams = buildDefaultAdapterParams(_uaGasLimit);\n } else {\n adapterParams = buildAirdropAdapterParams(_uaGasLimit, _airdropParams);\n }\n }\n\n // Build Adapter Params\n function buildDefaultAdapterParams(uint _uaGas) internal pure returns (bytes memory) {\n // txType 1\n // bytes [2 32 ]\n // fields [txType extraGas]\n return abi.encodePacked(uint16(1), _uaGas);\n }\n\n function buildAirdropAdapterParams(uint _uaGas, AirdropParams memory _params) internal pure returns (bytes memory) {\n require(_params.airdropAmount > 0, \"Airdrop amount must be greater than 0\");\n require(_params.airdropAddress != bytes32(0x0), \"Airdrop address must be set\");\n\n // txType 2\n // bytes [2 32 32 bytes[] ]\n // fields [txType extraGas dstNativeAmt dstNativeAddress]\n return abi.encodePacked(uint16(2), _uaGas, _params.airdropAmount, _params.airdropAddress);\n }\n\n function getGasLimit(bytes memory _adapterParams) internal pure returns (uint gasLimit) {\n require(_adapterParams.length == 34 || _adapterParams.length > 66, \"Invalid adapterParams\");\n assembly {\n gasLimit := mload(add(_adapterParams, 34))\n }\n }\n\n // Decode Adapter Params\n function decodeAdapterParams(bytes memory _adapterParams)\n internal\n pure\n returns (\n uint16 txType,\n uint uaGas,\n uint airdropAmount,\n address payable airdropAddress\n )\n {\n require(_adapterParams.length == 34 || _adapterParams.length > 66, \"Invalid adapterParams\");\n assembly {\n txType := mload(add(_adapterParams, 2))\n uaGas := mload(add(_adapterParams, 34))\n }\n require(txType == 1 || txType == 2, \"Unsupported txType\");\n require(uaGas > 0, \"Gas too low\");\n\n if (txType == 2) {\n assembly {\n airdropAmount := mload(add(_adapterParams, 66))\n airdropAddress := mload(add(_adapterParams, 86))\n }\n }\n }\n\n //---------------------------------------------------------------------------\n // Address type handling\n function bytes32ToAddress(bytes32 _bytes32Address) internal pure returns (address _address) {\n return address(uint160(uint(_bytes32Address)));\n }\n\n function addressToBytes32(address _address) internal pure returns (bytes32 _bytes32Address) {\n return bytes32(uint(uint160(_address)));\n }\n}\n"
},
"@layerzerolabs/solidity-examples/contracts/lzApp/LzApp.sol": {
"content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\nimport \"@openzeppelin/contracts/access/Ownable.sol\";\nimport \"./interfaces/ILayerZeroReceiver.sol\";\nimport \"./interfaces/ILayerZeroUserApplicationConfig.sol\";\nimport \"./interfaces/ILayerZeroEndpoint.sol\";\nimport \"../libraries/BytesLib.sol\";\n\n/*\n * a generic LzReceiver implementation\n */\nabstract contract LzApp is Ownable, ILayerZeroReceiver, ILayerZeroUserApplicationConfig {\n using BytesLib for bytes;\n\n // ua can not send payload larger than this by default, but it can be changed by the ua owner\n uint public constant DEFAULT_PAYLOAD_SIZE_LIMIT = 10000;\n\n ILayerZeroEndpoint public immutable lzEndpoint;\n mapping(uint16 => bytes) public trustedRemoteLookup;\n mapping(uint16 => mapping(uint16 => uint)) public minDstGasLookup;\n mapping(uint16 => uint) public payloadSizeLimitLookup;\n address public precrime;\n\n event SetPrecrime(address precrime);\n event SetTrustedRemote(uint16 _remoteChainId, bytes _path);\n event SetTrustedRemoteAddress(uint16 _remoteChainId, bytes _remoteAddress);\n event SetMinDstGas(uint16 _dstChainId, uint16 _type, uint _minDstGas);\n\n constructor(address _endpoint) {\n lzEndpoint = ILayerZeroEndpoint(_endpoint);\n }\n\n function lzReceive(\n uint16 _srcChainId,\n bytes calldata _srcAddress,\n uint64 _nonce,\n bytes calldata _payload\n ) public virtual override {\n // lzReceive must be called by the endpoint for security\n require(_msgSender() == address(lzEndpoint), \"LzApp: invalid endpoint caller\");\n\n bytes memory trustedRemote = trustedRemoteLookup[_srcChainId];\n // if will still block the message pathway from (srcChainId, srcAddress). should not receive message from untrusted remote.\n require(\n _srcAddress.length == trustedRemote.length && trustedRemote.length > 0 && keccak256(_srcAddress) == keccak256(trustedRemote),\n \"LzApp: invalid source sending contract\"\n );\n\n _blockingLzReceive(_srcChainId, _srcAddress, _nonce, _payload);\n }\n\n // abstract function - the default behaviour of LayerZero is blocking. See: NonblockingLzApp if you dont need to enforce ordered messaging\n function _blockingLzReceive(\n uint16 _srcChainId,\n bytes memory _srcAddress,\n uint64 _nonce,\n bytes memory _payload\n ) internal virtual;\n\n function _lzSend(\n uint16 _dstChainId,\n bytes memory _payload,\n address payable _refundAddress,\n address _zroPaymentAddress,\n bytes memory _adapterParams,\n uint _nativeFee\n ) internal virtual {\n bytes memory trustedRemote = trustedRemoteLookup[_dstChainId];\n require(trustedRemote.length != 0, \"LzApp: destination chain is not a trusted source\");\n _checkPayloadSize(_dstChainId, _payload.length);\n lzEndpoint.send{value: _nativeFee}(_dstChainId, trustedRemote, _payload, _refundAddress, _zroPaymentAddress, _adapterParams);\n }\n\n function _checkGasLimit(\n uint16 _dstChainId,\n uint16 _type,\n bytes memory _adapterParams,\n uint _extraGas\n ) internal view virtual {\n uint providedGasLimit = _getGasLimit(_adapterParams);\n uint minGasLimit = minDstGasLookup[_dstChainId][_type];\n require(minGasLimit > 0, \"LzApp: minGasLimit not set\");\n require(providedGasLimit >= minGasLimit + _extraGas, \"LzApp: gas limit is too low\");\n }\n\n function _getGasLimit(bytes memory _adapterParams) internal pure virtual returns (uint gasLimit) {\n require(_adapterParams.length >= 34, \"LzApp: invalid adapterParams\");\n assembly {\n gasLimit := mload(add(_adapterParams, 34))\n }\n }\n\n function _checkPayloadSize(uint16 _dstChainId, uint _payloadSize) internal view virtual {\n uint payloadSizeLimit = payloadSizeLimitLookup[_dstChainId];\n if (payloadSizeLimit == 0) {\n // use default if not set\n payloadSizeLimit = DEFAULT_PAYLOAD_SIZE_LIMIT;\n }\n require(_payloadSize <= payloadSizeLimit, \"LzApp: payload size is too large\");\n }\n\n //---------------------------UserApplication config----------------------------------------\n function getConfig(\n uint16 _version,\n uint16 _chainId,\n address,\n uint _configType\n ) external view returns (bytes memory) {\n return lzEndpoint.getConfig(_version, _chainId, address(this), _configType);\n }\n\n // generic config for LayerZero user Application\n function setConfig(\n uint16 _version,\n uint16 _chainId,\n uint _configType,\n bytes calldata _config\n ) external override onlyOwner {\n lzEndpoint.setConfig(_version, _chainId, _configType, _config);\n }\n\n function setSendVersion(uint16 _version) external override onlyOwner {\n lzEndpoint.setSendVersion(_version);\n }\n\n function setReceiveVersion(uint16 _version) external override onlyOwner {\n lzEndpoint.setReceiveVersion(_version);\n }\n\n function forceResumeReceive(uint16 _srcChainId, bytes calldata _srcAddress) external override onlyOwner {\n lzEndpoint.forceResumeReceive(_srcChainId, _srcAddress);\n }\n\n // _path = abi.encodePacked(remoteAddress, localAddress)\n // this function set the trusted path for the cross-chain communication\n function setTrustedRemote(uint16 _remoteChainId, bytes calldata _path) external onlyOwner {\n trustedRemoteLookup[_remoteChainId] = _path;\n emit SetTrustedRemote(_remoteChainId, _path);\n }\n\n function setTrustedRemoteAddress(uint16 _remoteChainId, bytes calldata _remoteAddress) external onlyOwner {\n trustedRemoteLookup[_remoteChainId] = abi.encodePacked(_remoteAddress, address(this));\n emit SetTrustedRemoteAddress(_remoteChainId, _remoteAddress);\n }\n\n function getTrustedRemoteAddress(uint16 _remoteChainId) external view returns (bytes memory) {\n bytes memory path = trustedRemoteLookup[_remoteChainId];\n require(path.length != 0, \"LzApp: no trusted path record\");\n return path.slice(0, path.length - 20); // the last 20 bytes should be address(this)\n }\n\n function setPrecrime(address _precrime) external onlyOwner {\n precrime = _precrime;\n emit SetPrecrime(_precrime);\n }\n\n function setMinDstGas(\n uint16 _dstChainId,\n uint16 _packetType,\n uint _minGas\n ) external onlyOwner {\n minDstGasLookup[_dstChainId][_packetType] = _minGas;\n emit SetMinDstGas(_dstChainId, _packetType, _minGas);\n }\n\n // if the size is 0, it means default size limit\n function setPayloadSizeLimit(uint16 _dstChainId, uint _size) external onlyOwner {\n payloadSizeLimitLookup[_dstChainId] = _size;\n }\n\n //--------------------------- VIEW FUNCTION ----------------------------------------\n function isTrustedRemote(uint16 _srcChainId, bytes calldata _srcAddress) external view returns (bool) {\n bytes memory trustedSource = trustedRemoteLookup[_srcChainId];\n return keccak256(trustedSource) == keccak256(_srcAddress);\n }\n}\n"
},
"@layerzerolabs/solidity-examples/contracts/lzApp/mocks/LZEndpointMock.sol": {
"content": "// SPDX-License-Identifier: BUSL-1.1\n\npragma solidity ^0.8.0;\npragma abicoder v2;\n\nimport \"../interfaces/ILayerZeroReceiver.sol\";\nimport \"../interfaces/ILayerZeroEndpoint.sol\";\nimport \"../libs/LzLib.sol\";\n\n/*\nlike a real LayerZero endpoint but can be mocked, which handle message transmission, verification, and receipt.\n- blocking: LayerZero provides ordered delivery of messages from a given sender to a destination chain.\n- non-reentrancy: endpoint has a non-reentrancy guard for both the send() and receive(), respectively.\n- adapter parameters: allows UAs to add arbitrary transaction params in the send() function, like airdrop on destination chain.\nunlike a real LayerZero endpoint, it is\n- no messaging library versioning\n- send() will short circuit to lzReceive()\n- no user application configuration\n*/\ncontract LZEndpointMock is ILayerZeroEndpoint {\n uint8 internal constant _NOT_ENTERED = 1;\n uint8 internal constant _ENTERED = 2;\n\n mapping(address => address) public lzEndpointLookup;\n\n uint16 public mockChainId;\n bool public nextMsgBlocked;\n\n // fee config\n RelayerFeeConfig public relayerFeeConfig;\n ProtocolFeeConfig public protocolFeeConfig;\n uint public oracleFee;\n bytes public defaultAdapterParams;\n\n // path = remote addrss + local address\n // inboundNonce = [srcChainId][path].\n mapping(uint16 => mapping(bytes => uint64)) public inboundNonce;\n //todo: this is a hack\n // outboundNonce = [dstChainId][srcAddress]\n mapping(uint16 => mapping(address => uint64)) public outboundNonce;\n // // outboundNonce = [dstChainId][path].\n // mapping(uint16 => mapping(bytes => uint64)) public outboundNonce;\n // storedPayload = [srcChainId][path]\n mapping(uint16 => mapping(bytes => StoredPayload)) public storedPayload;\n // msgToDeliver = [srcChainId][path]\n mapping(uint16 => mapping(bytes => QueuedPayload[])) public msgsToDeliver;\n\n // reentrancy guard\n uint8 internal _send_entered_state = 1;\n uint8 internal _receive_entered_state = 1;\n\n struct ProtocolFeeConfig {\n uint zroFee;\n uint nativeBP;\n }\n\n struct RelayerFeeConfig {\n uint128 dstPriceRatio; // 10^10\n uint128 dstGasPriceInWei;\n uint128 dstNativeAmtCap;\n uint64 baseGas;\n uint64 gasPerByte;\n }\n\n struct StoredPayload {\n uint64 payloadLength;\n address dstAddress;\n bytes32 payloadHash;\n }\n\n struct QueuedPayload {\n address dstAddress;\n uint64 nonce;\n bytes payload;\n }\n\n modifier sendNonReentrant() {\n require(_send_entered_state == _NOT_ENTERED, \"LayerZeroMock: no send reentrancy\");\n _send_entered_state = _ENTERED;\n _;\n _send_entered_state = _NOT_ENTERED;\n }\n\n modifier receiveNonReentrant() {\n require(_receive_entered_state == _NOT_ENTERED, \"LayerZeroMock: no receive reentrancy\");\n _receive_entered_state = _ENTERED;\n _;\n _receive_entered_state = _NOT_ENTERED;\n }\n\n event UaForceResumeReceive(uint16 chainId, bytes srcAddress);\n event PayloadCleared(uint16 srcChainId, bytes srcAddress, uint64 nonce, address dstAddress);\n event PayloadStored(uint16 srcChainId, bytes srcAddress, address dstAddress, uint64 nonce, bytes payload, bytes reason);\n event ValueTransferFailed(address indexed to, uint indexed quantity);\n\n constructor(uint16 _chainId) {\n mockChainId = _chainId;\n\n // init config\n relayerFeeConfig = RelayerFeeConfig({\n dstPriceRatio: 1e10, // 1:1, same chain, same native coin\n dstGasPriceInWei: 1e10,\n dstNativeAmtCap: 1e19,\n baseGas: 100,\n gasPerByte: 1\n });\n protocolFeeConfig = ProtocolFeeConfig({zroFee: 1e18, nativeBP: 1000}); // BP 0.1\n oracleFee = 1e16;\n defaultAdapterParams = LzLib.buildDefaultAdapterParams(200000);\n }\n\n // ------------------------------ ILayerZeroEndpoint Functions ------------------------------\n function send(\n uint16 _chainId,\n bytes memory _path,\n bytes calldata _payload,\n address payable _refundAddress,\n address _zroPaymentAddress,\n bytes memory _adapterParams\n ) external payable override sendNonReentrant {\n require(_path.length == 40, \"LayerZeroMock: incorrect remote address size\"); // only support evm chains\n\n address dstAddr;\n assembly {\n dstAddr := mload(add(_path, 20))\n }\n\n address lzEndpoint = lzEndpointLookup[dstAddr];\n require(lzEndpoint != address(0), \"LayerZeroMock: destination LayerZero Endpoint not found\");\n\n // not handle zro token\n bytes memory adapterParams = _adapterParams.length > 0 ? _adapterParams : defaultAdapterParams;\n (uint nativeFee, ) = estimateFees(_chainId, msg.sender, _payload, _zroPaymentAddress != address(0x0), adapterParams);\n require(msg.value >= nativeFee, \"LayerZeroMock: not enough native for fees\");\n\n uint64 nonce = ++outboundNonce[_chainId][msg.sender];\n\n // refund if they send too much\n uint amount = msg.value - nativeFee;\n if (amount > 0) {\n (bool success, ) = _refundAddress.call{value: amount}(\"\");\n require(success, \"LayerZeroMock: failed to refund\");\n }\n\n // Mock the process of receiving msg on dst chain\n // Mock the relayer paying the dstNativeAddr the amount of extra native token\n (, uint extraGas, uint dstNativeAmt, address payable dstNativeAddr) = LzLib.decodeAdapterParams(adapterParams);\n if (dstNativeAmt > 0) {\n (bool success, ) = dstNativeAddr.call{value: dstNativeAmt}(\"\");\n if (!success) {\n emit ValueTransferFailed(dstNativeAddr, dstNativeAmt);\n }\n }\n\n bytes memory srcUaAddress = abi.encodePacked(msg.sender, dstAddr); // cast this address to bytes\n bytes memory payload = _payload;\n LZEndpointMock(lzEndpoint).receivePayload(mockChainId, srcUaAddress, dstAddr, nonce, extraGas, payload);\n }\n\n function receivePayload(\n uint16 _srcChainId,\n bytes calldata _path,\n address _dstAddress,\n uint64 _nonce,\n uint _gasLimit,\n bytes calldata _payload\n ) external override receiveNonReentrant {\n StoredPayload storage sp = storedPayload[_srcChainId][_path];\n\n // assert and increment the nonce. no message shuffling\n require(_nonce == ++inboundNonce[_srcChainId][_path], \"LayerZeroMock: wrong nonce\");\n\n // queue the following msgs inside of a stack to simulate a successful send on src, but not fully delivered on dst\n if (sp.payloadHash != bytes32(0)) {\n QueuedPayload[] storage msgs = msgsToDeliver[_srcChainId][_path];\n QueuedPayload memory newMsg = QueuedPayload(_dstAddress, _nonce, _payload);\n\n // warning, might run into gas issues trying to forward through a bunch of queued msgs\n // shift all the msgs over so we can treat this like a fifo via array.pop()\n if (msgs.length > 0) {\n // extend the array\n msgs.push(newMsg);\n\n // shift all the indexes up for pop()\n for (uint i = 0; i < msgs.length - 1; i++) {\n msgs[i + 1] = msgs[i];\n }\n\n // put the newMsg at the bottom of the stack\n msgs[0] = newMsg;\n } else {\n msgs.push(newMsg);\n }\n } else if (nextMsgBlocked) {\n storedPayload[_srcChainId][_path] = StoredPayload(uint64(_payload.length), _dstAddress, keccak256(_payload));\n emit PayloadStored(_srcChainId, _path, _dstAddress, _nonce, _payload, bytes(\"\"));\n // ensure the next msgs that go through are no longer blocked\n nextMsgBlocked = false;\n } else {\n try ILayerZeroReceiver(_dstAddress).lzReceive{gas: _gasLimit}(_srcChainId, _path, _nonce, _payload) {} catch (bytes memory reason) {\n storedPayload[_srcChainId][_path] = StoredPayload(uint64(_payload.length), _dstAddress, keccak256(_payload));\n emit PayloadStored(_srcChainId, _path, _dstAddress, _nonce, _payload, reason);\n // ensure the next msgs that go through are no longer blocked\n nextMsgBlocked = false;\n }\n }\n }\n\n function getInboundNonce(uint16 _chainID, bytes calldata _path) external view override returns (uint64) {\n return inboundNonce[_chainID][_path];\n }\n\n function getOutboundNonce(uint16 _chainID, address _srcAddress) external view override returns (uint64) {\n return outboundNonce[_chainID][_srcAddress];\n }\n\n function estimateFees(\n uint16 _dstChainId,\n address _userApplication,\n bytes memory _payload,\n bool _payInZRO,\n bytes memory _adapterParams\n ) public view override returns (uint nativeFee, uint zroFee) {\n bytes memory adapterParams = _adapterParams.length > 0 ? _adapterParams : defaultAdapterParams;\n\n // Relayer Fee\n uint relayerFee = _getRelayerFee(_dstChainId, 1, _userApplication, _payload.length, adapterParams);\n\n // LayerZero Fee\n uint protocolFee = _getProtocolFees(_payInZRO, relayerFee, oracleFee);\n _payInZRO ? zroFee = protocolFee : nativeFee = protocolFee;\n\n // return the sum of fees\n nativeFee = nativeFee + relayerFee + oracleFee;\n }\n\n function getChainId() external view override returns (uint16) {\n return mockChainId;\n }\n\n function retryPayload(\n uint16 _srcChainId,\n bytes calldata _path,\n bytes calldata _payload\n ) external override {\n StoredPayload storage sp = storedPayload[_srcChainId][_path];\n require(sp.payloadHash != bytes32(0), \"LayerZeroMock: no stored payload\");\n require(_payload.length == sp.payloadLength && keccak256(_payload) == sp.payloadHash, \"LayerZeroMock: invalid payload\");\n\n address dstAddress = sp.dstAddress;\n // empty the storedPayload\n sp.payloadLength = 0;\n sp.dstAddress = address(0);\n sp.payloadHash = bytes32(0);\n\n uint64 nonce = inboundNonce[_srcChainId][_path];\n\n ILayerZeroReceiver(dstAddress).lzReceive(_srcChainId, _path, nonce, _payload);\n emit PayloadCleared(_srcChainId, _path, nonce, dstAddress);\n }\n\n function hasStoredPayload(uint16 _srcChainId, bytes calldata _path) external view override returns (bool) {\n StoredPayload storage sp = storedPayload[_srcChainId][_path];\n return sp.payloadHash != bytes32(0);\n }\n\n function getSendLibraryAddress(address) external view override returns (address) {\n return address(this);\n }\n\n function getReceiveLibraryAddress(address) external view override returns (address) {\n return address(this);\n }\n\n function isSendingPayload() external view override returns (bool) {\n return _send_entered_state == _ENTERED;\n }\n\n function isReceivingPayload() external view override returns (bool) {\n return _receive_entered_state == _ENTERED;\n }\n\n function getConfig(\n uint16, /*_version*/\n uint16, /*_chainId*/\n address, /*_ua*/\n uint /*_configType*/\n ) external pure override returns (bytes memory) {\n return \"\";\n }\n\n function getSendVersion(\n address /*_userApplication*/\n ) external pure override returns (uint16) {\n return 1;\n }\n\n function getReceiveVersion(\n address /*_userApplication*/\n ) external pure override returns (uint16) {\n return 1;\n }\n\n function setConfig(\n uint16, /*_version*/\n uint16, /*_chainId*/\n uint, /*_configType*/\n bytes memory /*_config*/\n ) external override {}\n\n function setSendVersion(\n uint16 /*version*/\n ) external override {}\n\n function setReceiveVersion(\n uint16 /*version*/\n ) external override {}\n\n function forceResumeReceive(uint16 _srcChainId, bytes calldata _path) external override {\n StoredPayload storage sp = storedPayload[_srcChainId][_path];\n // revert if no messages are cached. safeguard malicious UA behaviour\n require(sp.payloadHash != bytes32(0), \"LayerZeroMock: no stored payload\");\n require(sp.dstAddress == msg.sender, \"LayerZeroMock: invalid caller\");\n\n // empty the storedPayload\n sp.payloadLength = 0;\n sp.dstAddress = address(0);\n sp.payloadHash = bytes32(0);\n\n emit UaForceResumeReceive(_srcChainId, _path);\n\n // resume the receiving of msgs after we force clear the \"stuck\" msg\n _clearMsgQue(_srcChainId, _path);\n }\n\n // ------------------------------ Other Public/External Functions --------------------------------------------------\n\n function getLengthOfQueue(uint16 _srcChainId, bytes calldata _srcAddress) external view returns (uint) {\n return msgsToDeliver[_srcChainId][_srcAddress].length;\n }\n\n // used to simulate messages received get stored as a payload\n function blockNextMsg() external {\n nextMsgBlocked = true;\n }\n\n function setDestLzEndpoint(address destAddr, address lzEndpointAddr) external {\n lzEndpointLookup[destAddr] = lzEndpointAddr;\n }\n\n function setRelayerPrice(\n uint128 _dstPriceRatio,\n uint128 _dstGasPriceInWei,\n uint128 _dstNativeAmtCap,\n uint64 _baseGas,\n uint64 _gasPerByte\n ) external {\n relayerFeeConfig.dstPriceRatio = _dstPriceRatio;\n relayerFeeConfig.dstGasPriceInWei = _dstGasPriceInWei;\n relayerFeeConfig.dstNativeAmtCap = _dstNativeAmtCap;\n relayerFeeConfig.baseGas = _baseGas;\n relayerFeeConfig.gasPerByte = _gasPerByte;\n }\n\n function setProtocolFee(uint _zroFee, uint _nativeBP) external {\n protocolFeeConfig.zroFee = _zroFee;\n protocolFeeConfig.nativeBP = _nativeBP;\n }\n\n function setOracleFee(uint _oracleFee) external {\n oracleFee = _oracleFee;\n }\n\n function setDefaultAdapterParams(bytes memory _adapterParams) external {\n defaultAdapterParams = _adapterParams;\n }\n\n // --------------------- Internal Functions ---------------------\n // simulates the relayer pushing through the rest of the msgs that got delayed due to the stored payload\n function _clearMsgQue(uint16 _srcChainId, bytes calldata _path) internal {\n QueuedPayload[] storage msgs = msgsToDeliver[_srcChainId][_path];\n\n // warning, might run into gas issues trying to forward through a bunch of queued msgs\n while (msgs.length > 0) {\n QueuedPayload memory payload = msgs[msgs.length - 1];\n ILayerZeroReceiver(payload.dstAddress).lzReceive(_srcChainId, _path, payload.nonce, payload.payload);\n msgs.pop();\n }\n }\n\n function _getProtocolFees(\n bool _payInZro,\n uint _relayerFee,\n uint _oracleFee\n ) internal view returns (uint) {\n if (_payInZro) {\n return protocolFeeConfig.zroFee;\n } else {\n return ((_relayerFee + _oracleFee) * protocolFeeConfig.nativeBP) / 10000;\n }\n }\n\n function _getRelayerFee(\n uint16, /* _dstChainId */\n uint16, /* _outboundProofType */\n address, /* _userApplication */\n uint _payloadSize,\n bytes memory _adapterParams\n ) internal view returns (uint) {\n (uint16 txType, uint extraGas, uint dstNativeAmt, ) = LzLib.decodeAdapterParams(_adapterParams);\n uint totalRemoteToken; // = baseGas + extraGas + requiredNativeAmount\n if (txType == 2) {\n require(relayerFeeConfig.dstNativeAmtCap >= dstNativeAmt, \"LayerZeroMock: dstNativeAmt too large \");\n totalRemoteToken += dstNativeAmt;\n }\n // remoteGasTotal = dstGasPriceInWei * (baseGas + extraGas)\n uint remoteGasTotal = relayerFeeConfig.dstGasPriceInWei * (relayerFeeConfig.baseGas + extraGas);\n totalRemoteToken += remoteGasTotal;\n\n // tokenConversionRate = dstPrice / localPrice\n // basePrice = totalRemoteToken * tokenConversionRate\n uint basePrice = (totalRemoteToken * relayerFeeConfig.dstPriceRatio) / 10**10;\n\n // pricePerByte = (dstGasPriceInWei * gasPerBytes) * tokenConversionRate\n uint pricePerByte = (relayerFeeConfig.dstGasPriceInWei * relayerFeeConfig.gasPerByte * relayerFeeConfig.dstPriceRatio) / 10**10;\n\n return basePrice + _payloadSize * pricePerByte;\n }\n}\n"
},
"@layerzerolabs/solidity-examples/contracts/lzApp/NonblockingLzApp.sol": {
"content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\nimport \"./LzApp.sol\";\nimport \"../libraries/ExcessivelySafeCall.sol\";\n\n/*\n * the default LayerZero messaging behaviour is blocking, i.e. any failed message will block the channel\n * this abstract class try-catch all fail messages and store locally for future retry. hence, non-blocking\n * NOTE: if the srcAddress is not configured properly, it will still block the message pathway from (srcChainId, srcAddress)\n */\nabstract contract NonblockingLzApp is LzApp {\n using ExcessivelySafeCall for address;\n\n constructor(address _endpoint) LzApp(_endpoint) {}\n\n mapping(uint16 => mapping(bytes => mapping(uint64 => bytes32))) public failedMessages;\n\n event MessageFailed(uint16 _srcChainId, bytes _srcAddress, uint64 _nonce, bytes _payload, bytes _reason);\n event RetryMessageSuccess(uint16 _srcChainId, bytes _srcAddress, uint64 _nonce, bytes32 _payloadHash);\n\n // overriding the virtual function in LzReceiver\n function _blockingLzReceive(\n uint16 _srcChainId,\n bytes memory _srcAddress,\n uint64 _nonce,\n bytes memory _payload\n ) internal virtual override {\n (bool success, bytes memory reason) = address(this).excessivelySafeCall(\n gasleft(),\n 150,\n abi.encodeWithSelector(this.nonblockingLzReceive.selector, _srcChainId, _srcAddress, _nonce, _payload)\n );\n if (!success) {\n _storeFailedMessage(_srcChainId, _srcAddress, _nonce, _payload, reason);\n }\n }\n\n function _storeFailedMessage(\n uint16 _srcChainId,\n bytes memory _srcAddress,\n uint64 _nonce,\n bytes memory _payload,\n bytes memory _reason\n ) internal virtual {\n failedMessages[_srcChainId][_srcAddress][_nonce] = keccak256(_payload);\n emit MessageFailed(_srcChainId, _srcAddress, _nonce, _payload, _reason);\n }\n\n function nonblockingLzReceive(\n uint16 _srcChainId,\n bytes calldata _srcAddress,\n uint64 _nonce,\n bytes calldata _payload\n ) public virtual {\n // only internal transaction\n require(_msgSender() == address(this), \"NonblockingLzApp: caller must be LzApp\");\n _nonblockingLzReceive(_srcChainId, _srcAddress, _nonce, _payload);\n }\n\n //@notice override this function\n function _nonblockingLzReceive(\n uint16 _srcChainId,\n bytes memory _srcAddress,\n uint64 _nonce,\n bytes memory _payload\n ) internal virtual;\n\n function retryMessage(\n uint16 _srcChainId,\n bytes calldata _srcAddress,\n uint64 _nonce,\n bytes calldata _payload\n ) public payable virtual {\n // assert there is message to retry\n bytes32 payloadHash = failedMessages[_srcChainId][_srcAddress][_nonce];\n require(payloadHash != bytes32(0), \"NonblockingLzApp: no stored message\");\n require(keccak256(_payload) == payloadHash, \"NonblockingLzApp: invalid payload\");\n // clear the stored message\n failedMessages[_srcChainId][_srcAddress][_nonce] = bytes32(0);\n // execute the message. revert if it fails again\n _nonblockingLzReceive(_srcChainId, _srcAddress, _nonce, _payload);\n emit RetryMessageSuccess(_srcChainId, _srcAddress, _nonce, payloadHash);\n }\n}\n"
},
"@openzeppelin/contracts-upgradeable/access/Ownable2StepUpgradeable.sol": {
"content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.8.0) (access/Ownable2Step.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./OwnableUpgradeable.sol\";\nimport \"../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Contract module which provides 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} and {acceptOwnership}.\n *\n * This module is used through inheritance. It will make available all functions\n * from parent (Ownable).\n */\nabstract contract Ownable2StepUpgradeable is Initializable, OwnableUpgradeable {\n function __Ownable2Step_init() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n function __Ownable2Step_init_unchained() internal onlyInitializing {\n }\n address private _pendingOwner;\n\n event OwnershipTransferStarted(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Returns the address of the pending owner.\n */\n function pendingOwner() public view virtual returns (address) {\n return _pendingOwner;\n }\n\n /**\n * @dev Starts the ownership transfer of the contract to a new account. Replaces the pending transfer if there is one.\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual override onlyOwner {\n _pendingOwner = newOwner;\n emit OwnershipTransferStarted(owner(), newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`) and deletes any pending owner.\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual override {\n delete _pendingOwner;\n super._transferOwnership(newOwner);\n }\n\n /**\n * @dev The new owner accepts the ownership transfer.\n */\n function acceptOwnership() external {\n address sender = _msgSender();\n require(pendingOwner() == sender, \"Ownable2Step: caller is not the new owner\");\n _transferOwnership(sender);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n"
},
"@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol": {
"content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (access/Ownable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../utils/ContextUpgradeable.sol\";\nimport \"../proxy/utils/Initializable.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 OwnableUpgradeable is Initializable, ContextUpgradeable {\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 function __Ownable_init() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n function __Ownable_init_unchained() internal onlyInitializing {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n _checkOwner();\n _;\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 the sender is not the owner.\n */\n function _checkOwner() internal view virtual {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\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 /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n"
},
"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol": {
"content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.8.1) (proxy/utils/Initializable.sol)\n\npragma solidity ^0.8.2;\n\nimport \"../../utils/AddressUpgradeable.sol\";\n\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts.\n *\n * Similar to `reinitializer(1)`, except that functions marked with `initializer` can be nested in the context of a\n * constructor.\n *\n * Emits an {Initialized} event.\n */\n modifier initializer() {\n bool isTopLevelCall = !_initializing;\n require(\n (isTopLevelCall && _initialized < 1) || (!AddressUpgradeable.isContract(address(this)) && _initialized == 1),\n \"Initializable: contract is already initialized\"\n );\n _initialized = 1;\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * A reinitializer may be used after the original initialization step. This is essential to configure modules that\n * are added through upgrades and that require initialization.\n *\n * When `version` is 1, this modifier is similar to `initializer`, except that functions marked with `reinitializer`\n * cannot be nested. If one is invoked in the context of another, execution will revert.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n *\n * WARNING: setting the version to 255 will prevent any future reinitialization.\n *\n * Emits an {Initialized} event.\n */\n modifier reinitializer(uint8 version) {\n require(!_initializing && _initialized < version, \"Initializable: contract is already initialized\");\n _initialized = version;\n _initializing = true;\n _;\n _initializing = false;\n emit Initialized(version);\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n *\n * Emits an {Initialized} event the first time it is successfully executed.\n */\n function _disableInitializers() internal virtual {\n require(!_initializing, \"Initializable: contract is initializing\");\n if (_initialized < type(uint8).max) {\n _initialized = type(uint8).max;\n emit Initialized(type(uint8).max);\n }\n }\n\n /**\n * @dev Returns the highest version that has been initialized. See {reinitializer}.\n */\n function _getInitializedVersion() internal view returns (uint8) {\n return _initialized;\n }\n\n /**\n * @dev Returns `true` if the contract is currently initializing. See {onlyInitializing}.\n */\n function _isInitializing() internal view returns (bool) {\n return _initializing;\n }\n}\n"
},
"@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol": {
"content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.8.0) (utils/Address.sol)\n\npragma solidity ^0.8.1;\n\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length > 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance >= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance >= value, \"Address: insufficient balance for call\");\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling\n * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract.\n *\n * _Available since v4.8._\n */\n function verifyCallResultFromTarget(\n address target,\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n if (success) {\n if (returndata.length == 0) {\n // only check isContract if the call was successful and the return data is empty\n // otherwise we already know that it was a contract\n require(isContract(target), \"Address: call to non-contract\");\n }\n return returndata;\n } else {\n _revert(returndata, errorMessage);\n }\n }\n\n /**\n * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason or using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n _revert(returndata, errorMessage);\n }\n }\n\n function _revert(bytes memory returndata, string memory errorMessage) private pure {\n // Look for revert reason and bubble it up if present\n if (returndata.length > 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n /// @solidity memory-safe-assembly\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n}\n"
},
"@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol": {
"content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n\npragma solidity ^0.8.0;\nimport \"../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n"
},
"@openzeppelin/contracts/access/AccessControl.sol": {
"content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (access/AccessControl.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IAccessControl.sol\";\nimport \"../utils/Context.sol\";\nimport \"../utils/Strings.sol\";\nimport \"../utils/introspection/ERC165.sol\";\n\n/**\n * @dev Contract module that allows children to implement role-based access\n * control mechanisms. This is a lightweight version that doesn't allow enumerating role\n * members except through off-chain means by accessing the contract event logs. Some\n * applications may benefit from on-chain enumerability, for those cases see\n * {AccessControlEnumerable}.\n *\n * Roles are referred to by their `bytes32` identifier. These should be exposed\n * in the external API and be unique. The best way to achieve this is by\n * using `public constant` hash digests:\n *\n * ```solidity\n * bytes32 public constant MY_ROLE = keccak256(\"MY_ROLE\");\n * ```\n *\n * Roles can be used to represent a set of permissions. To restrict access to a\n * function call, use {hasRole}:\n *\n * ```solidity\n * function foo() public {\n * require(hasRole(MY_ROLE, msg.sender));\n * ...\n * }\n * ```\n *\n * Roles can be granted and revoked dynamically via the {grantRole} and\n * {revokeRole} functions. Each role has an associated admin role, and only\n * accounts that have a role's admin role can call {grantRole} and {revokeRole}.\n *\n * By default, the admin role for all roles is `DEFAULT_ADMIN_ROLE`, which means\n * that only accounts with this role will be able to grant or revoke other\n * roles. More complex role relationships can be created by using\n * {_setRoleAdmin}.\n *\n * WARNING: The `DEFAULT_ADMIN_ROLE` is also its own admin: it has permission to\n * grant and revoke this role. Extra precautions should be taken to secure\n * accounts that have been granted it. We recommend using {AccessControlDefaultAdminRules}\n * to enforce additional security measures for this role.\n */\nabstract contract AccessControl is Context, IAccessControl, ERC165 {\n struct RoleData {\n mapping(address => bool) members;\n bytes32 adminRole;\n }\n\n mapping(bytes32 => RoleData) private _roles;\n\n bytes32 public constant DEFAULT_ADMIN_ROLE = 0x00;\n\n /**\n * @dev Modifier that checks that an account has a specific role. Reverts\n * with a standardized message including the required role.\n *\n * The format of the revert reason is given by the following regular expression:\n *\n * /^AccessControl: account (0x[0-9a-f]{40}) is missing role (0x[0-9a-f]{64})$/\n *\n * _Available since v4.1._\n */\n modifier onlyRole(bytes32 role) {\n _checkRole(role);\n _;\n }\n\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n return interfaceId == type(IAccessControl).interfaceId || super.supportsInterface(interfaceId);\n }\n\n /**\n * @dev Returns `true` if `account` has been granted `role`.\n */\n function hasRole(bytes32 role, address account) public view virtual override returns (bool) {\n return _roles[role].members[account];\n }\n\n /**\n * @dev Revert with a standard message if `_msgSender()` is missing `role`.\n * Overriding this function changes the behavior of the {onlyRole} modifier.\n *\n * Format of the revert message is described in {_checkRole}.\n *\n * _Available since v4.6._\n */\n function _checkRole(bytes32 role) internal view virtual {\n _checkRole(role, _msgSender());\n }\n\n /**\n * @dev Revert with a standard message if `account` is missing `role`.\n *\n * The format of the revert reason is given by the following regular expression:\n *\n * /^AccessControl: account (0x[0-9a-f]{40}) is missing role (0x[0-9a-f]{64})$/\n */\n function _checkRole(bytes32 role, address account) internal view virtual {\n if (!hasRole(role, account)) {\n revert(\n string(\n abi.encodePacked(\n \"AccessControl: account \",\n Strings.toHexString(account),\n \" is missing role \",\n Strings.toHexString(uint256(role), 32)\n )\n )\n );\n }\n }\n\n /**\n * @dev Returns the admin role that controls `role`. See {grantRole} and\n * {revokeRole}.\n *\n * To change a role's admin, use {_setRoleAdmin}.\n */\n function getRoleAdmin(bytes32 role) public view virtual override returns (bytes32) {\n return _roles[role].adminRole;\n }\n\n /**\n * @dev Grants `role` to `account`.\n *\n * If `account` had not been already granted `role`, emits a {RoleGranted}\n * event.\n *\n * Requirements:\n *\n * - the caller must have ``role``'s admin role.\n *\n * May emit a {RoleGranted} event.\n */\n function grantRole(bytes32 role, address account) public virtual override onlyRole(getRoleAdmin(role)) {\n _grantRole(role, account);\n }\n\n /**\n * @dev Revokes `role` from `account`.\n *\n * If `account` had been granted `role`, emits a {RoleRevoked} event.\n *\n * Requirements:\n *\n * - the caller must have ``role``'s admin role.\n *\n * May emit a {RoleRevoked} event.\n */\n function revokeRole(bytes32 role, address account) public virtual override onlyRole(getRoleAdmin(role)) {\n _revokeRole(role, account);\n }\n\n /**\n * @dev Revokes `role` from the calling account.\n *\n * Roles are often managed via {grantRole} and {revokeRole}: this function's\n * purpose is to provide a mechanism for accounts to lose their privileges\n * if they are compromised (such as when a trusted device is misplaced).\n *\n * If the calling account had been revoked `role`, emits a {RoleRevoked}\n * event.\n *\n * Requirements:\n *\n * - the caller must be `account`.\n *\n * May emit a {RoleRevoked} event.\n */\n function renounceRole(bytes32 role, address account) public virtual override {\n require(account == _msgSender(), \"AccessControl: can only renounce roles for self\");\n\n _revokeRole(role, account);\n }\n\n /**\n * @dev Grants `role` to `account`.\n *\n * If `account` had not been already granted `role`, emits a {RoleGranted}\n * event. Note that unlike {grantRole}, this function doesn't perform any\n * checks on the calling account.\n *\n * May emit a {RoleGranted} event.\n *\n * [WARNING]\n * ====\n * This function should only be called from the constructor when setting\n * up the initial roles for the system.\n *\n * Using this function in any other way is effectively circumventing the admin\n * system imposed by {AccessControl}.\n * ====\n *\n * NOTE: This function is deprecated in favor of {_grantRole}.\n */\n function _setupRole(bytes32 role, address account) internal virtual {\n _grantRole(role, account);\n }\n\n /**\n * @dev Sets `adminRole` as ``role``'s admin role.\n *\n * Emits a {RoleAdminChanged} event.\n */\n function _setRoleAdmin(bytes32 role, bytes32 adminRole) internal virtual {\n bytes32 previousAdminRole = getRoleAdmin(role);\n _roles[role].adminRole = adminRole;\n emit RoleAdminChanged(role, previousAdminRole, adminRole);\n }\n\n /**\n * @dev Grants `role` to `account`.\n *\n * Internal function without access restriction.\n *\n * May emit a {RoleGranted} event.\n */\n function _grantRole(bytes32 role, address account) internal virtual {\n if (!hasRole(role, account)) {\n _roles[role].members[account] = true;\n emit RoleGranted(role, account, _msgSender());\n }\n }\n\n /**\n * @dev Revokes `role` from `account`.\n *\n * Internal function without access restriction.\n *\n * May emit a {RoleRevoked} event.\n */\n function _revokeRole(bytes32 role, address account) internal virtual {\n if (hasRole(role, account)) {\n _roles[role].members[account] = false;\n emit RoleRevoked(role, account, _msgSender());\n }\n }\n}\n"
},
"@openzeppelin/contracts/access/IAccessControl.sol": {
"content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (access/IAccessControl.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev External interface of AccessControl declared to support ERC165 detection.\n */\ninterface IAccessControl {\n /**\n * @dev Emitted when `newAdminRole` is set as ``role``'s admin role, replacing `previousAdminRole`\n *\n * `DEFAULT_ADMIN_ROLE` is the starting admin for all roles, despite\n * {RoleAdminChanged} not being emitted signaling this.\n *\n * _Available since v3.1._\n */\n event RoleAdminChanged(bytes32 indexed role, bytes32 indexed previousAdminRole, bytes32 indexed newAdminRole);\n\n /**\n * @dev Emitted when `account` is granted `role`.\n *\n * `sender` is the account that originated the contract call, an admin role\n * bearer except when using {AccessControl-_setupRole}.\n */\n event RoleGranted(bytes32 indexed role, address indexed account, address indexed sender);\n\n /**\n * @dev Emitted when `account` is revoked `role`.\n *\n * `sender` is the account that originated the contract call:\n * - if using `revokeRole`, it is the admin role bearer\n * - if using `renounceRole`, it is the role bearer (i.e. `account`)\n */\n event RoleRevoked(bytes32 indexed role, address indexed account, address indexed sender);\n\n /**\n * @dev Returns `true` if `account` has been granted `role`.\n */\n function hasRole(bytes32 role, address account) external view returns (bool);\n\n /**\n * @dev Returns the admin role that controls `role`. See {grantRole} and\n * {revokeRole}.\n *\n * To change a role's admin, use {AccessControl-_setRoleAdmin}.\n */\n function getRoleAdmin(bytes32 role) external view returns (bytes32);\n\n /**\n * @dev Grants `role` to `account`.\n *\n * If `account` had not been already granted `role`, emits a {RoleGranted}\n * event.\n *\n * Requirements:\n *\n * - the caller must have ``role``'s admin role.\n */\n function grantRole(bytes32 role, address account) external;\n\n /**\n * @dev Revokes `role` from `account`.\n *\n * If `account` had been granted `role`, emits a {RoleRevoked} event.\n *\n * Requirements:\n *\n * - the caller must have ``role``'s admin role.\n */\n function revokeRole(bytes32 role, address account) external;\n\n /**\n * @dev Revokes `role` from the calling account.\n *\n * Roles are often managed via {grantRole} and {revokeRole}: this function's\n * purpose is to provide a mechanism for accounts to lose their privileges\n * if they are compromised (such as when a trusted device is misplaced).\n *\n * If the calling account had been granted `role`, emits a {RoleRevoked}\n * event.\n *\n * Requirements:\n *\n * - the caller must be `account`.\n */\n function renounceRole(bytes32 role, address account) external;\n}\n"
},
"@openzeppelin/contracts/access/Ownable.sol": {
"content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (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() {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n _checkOwner();\n _;\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 the sender is not the owner.\n */\n function _checkOwner() internal view virtual {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby disabling 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"
},
"@openzeppelin/contracts/interfaces/draft-IERC1822.sol": {
"content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.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"
},
"@openzeppelin/contracts/interfaces/IERC1967.sol": {
"content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (interfaces/IERC1967.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev ERC-1967: Proxy Storage Slots. This interface contains the events defined in the ERC.\n *\n * _Available since v4.8.3._\n */\ninterface IERC1967 {\n /**\n * @dev Emitted when the implementation is upgraded.\n */\n event Upgraded(address indexed implementation);\n\n /**\n * @dev Emitted when the admin account has changed.\n */\n event AdminChanged(address previousAdmin, address newAdmin);\n\n /**\n * @dev Emitted when the beacon is changed.\n */\n event BeaconUpgraded(address indexed beacon);\n}\n"
},
"@openzeppelin/contracts/proxy/beacon/BeaconProxy.sol": {
"content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (proxy/beacon/BeaconProxy.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IBeacon.sol\";\nimport \"../Proxy.sol\";\nimport \"../ERC1967/ERC1967Upgrade.sol\";\n\n/**\n * @dev This contract implements a proxy that gets the implementation address for each call from an {UpgradeableBeacon}.\n *\n * The beacon address is stored in storage slot `uint256(keccak256('eip1967.proxy.beacon')) - 1`, so that it doesn't\n * conflict with the storage layout of the implementation behind the proxy.\n *\n * _Available since v3.4._\n */\ncontract BeaconProxy is Proxy, ERC1967Upgrade {\n /**\n * @dev Initializes the proxy with `beacon`.\n *\n * If `data` is nonempty, it's used as data in a delegate call to the implementation returned by the beacon. This\n * will typically be an encoded function call, and allows initializing the storage of the proxy like a Solidity\n * constructor.\n *\n * Requirements:\n *\n * - `beacon` must be a contract with the interface {IBeacon}.\n */\n constructor(address beacon, bytes memory data) payable {\n _upgradeBeaconToAndCall(beacon, data, false);\n }\n\n /**\n * @dev Returns the current beacon address.\n */\n function _beacon() internal view virtual returns (address) {\n return _getBeacon();\n }\n\n /**\n * @dev Returns the current implementation address of the associated beacon.\n */\n function _implementation() internal view virtual override returns (address) {\n return IBeacon(_getBeacon()).implementation();\n }\n\n /**\n * @dev Changes the proxy to use a new beacon. Deprecated: see {_upgradeBeaconToAndCall}.\n *\n * If `data` is nonempty, it's used as data in a delegate call to the implementation returned by the beacon.\n *\n * Requirements:\n *\n * - `beacon` must be a contract.\n * - The implementation returned by `beacon` must be a contract.\n */\n function _setBeacon(address beacon, bytes memory data) internal virtual {\n _upgradeBeaconToAndCall(beacon, data, false);\n }\n}\n"
},
"@openzeppelin/contracts/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"
},
"@openzeppelin/contracts/proxy/beacon/UpgradeableBeacon.sol": {
"content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (proxy/beacon/UpgradeableBeacon.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IBeacon.sol\";\nimport \"../../access/Ownable.sol\";\nimport \"../../utils/Address.sol\";\n\n/**\n * @dev This contract is used in conjunction with one or more instances of {BeaconProxy} to determine their\n * implementation contract, which is where they will delegate all function calls.\n *\n * An owner is able to change the implementation the beacon points to, thus upgrading the proxies that use this beacon.\n */\ncontract UpgradeableBeacon is IBeacon, Ownable {\n address private _implementation;\n\n /**\n * @dev Emitted when the implementation returned by the beacon is changed.\n */\n event Upgraded(address indexed implementation);\n\n /**\n * @dev Sets the address of the initial implementation, and the deployer account as the owner who can upgrade the\n * beacon.\n */\n constructor(address implementation_) {\n _setImplementation(implementation_);\n }\n\n /**\n * @dev Returns the current implementation address.\n */\n function implementation() public view virtual override returns (address) {\n return _implementation;\n }\n\n /**\n * @dev Upgrades the beacon to a new implementation.\n *\n * Emits an {Upgraded} event.\n *\n * Requirements:\n *\n * - msg.sender must be the owner of the contract.\n * - `newImplementation` must be a contract.\n */\n function upgradeTo(address newImplementation) public virtual onlyOwner {\n _setImplementation(newImplementation);\n emit Upgraded(newImplementation);\n }\n\n /**\n * @dev Sets the implementation contract address for this beacon\n *\n * Requirements:\n *\n * - `newImplementation` must be a contract.\n */\n function _setImplementation(address newImplementation) private {\n require(Address.isContract(newImplementation), \"UpgradeableBeacon: implementation is not a contract\");\n _implementation = newImplementation;\n }\n}\n"
},
"@openzeppelin/contracts/proxy/ERC1967/ERC1967Proxy.sol": {
"content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (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 initializing the storage of the proxy like a Solidity constructor.\n */\n constructor(address _logic, bytes memory _data) payable {\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"
},
"@openzeppelin/contracts/proxy/ERC1967/ERC1967Upgrade.sol": {
"content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (proxy/ERC1967/ERC1967Upgrade.sol)\n\npragma solidity ^0.8.2;\n\nimport \"../beacon/IBeacon.sol\";\nimport \"../../interfaces/IERC1967.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 */\nabstract contract ERC1967Upgrade is IERC1967 {\n // This is the keccak-256 hash of \"eip1967.proxy.rollback\" subtracted by 1\n bytes32 private constant _ROLLBACK_SLOT = 0x4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd9143;\n\n /**\n * @dev Storage slot with the address of the current implementation.\n * This is the keccak-256 hash of \"eip1967.proxy.implementation\" subtracted by 1, and is\n * validated in the constructor.\n */\n bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\n\n /**\n * @dev Returns the current implementation address.\n */\n function _getImplementation() internal view returns (address) {\n return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value;\n }\n\n /**\n * @dev Stores a new address in the EIP1967 implementation slot.\n */\n function _setImplementation(address newImplementation) private {\n require(Address.isContract(newImplementation), \"ERC1967: new implementation is not a contract\");\n StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation;\n }\n\n /**\n * @dev Perform implementation upgrade\n *\n * Emits an {Upgraded} event.\n */\n function _upgradeTo(address newImplementation) internal {\n _setImplementation(newImplementation);\n emit Upgraded(newImplementation);\n }\n\n /**\n * @dev Perform implementation upgrade with additional setup call.\n *\n * Emits an {Upgraded} event.\n */\n function _upgradeToAndCall(address newImplementation, bytes memory data, bool forceCall) internal {\n _upgradeTo(newImplementation);\n if (data.length > 0 || forceCall) {\n Address.functionDelegateCall(newImplementation, data);\n }\n }\n\n /**\n * @dev Perform implementation upgrade with security checks for UUPS proxies, and additional setup call.\n *\n * Emits an {Upgraded} event.\n */\n function _upgradeToAndCallUUPS(address newImplementation, bytes memory data, bool forceCall) internal {\n // Upgrades from old implementations will perform a rollback test. This test requires the new\n // implementation to upgrade back to the old, non-ERC1822 compliant, implementation. Removing\n // this special case will break upgrade paths from old UUPS implementation to new ones.\n if (StorageSlot.getBooleanSlot(_ROLLBACK_SLOT).value) {\n _setImplementation(newImplementation);\n } else {\n try IERC1822Proxiable(newImplementation).proxiableUUID() returns (bytes32 slot) {\n require(slot == _IMPLEMENTATION_SLOT, \"ERC1967Upgrade: unsupported proxiableUUID\");\n } catch {\n revert(\"ERC1967Upgrade: new implementation is not UUPS\");\n }\n _upgradeToAndCall(newImplementation, data, forceCall);\n }\n }\n\n /**\n * @dev Storage slot with the admin of the contract.\n * This is the keccak-256 hash of \"eip1967.proxy.admin\" subtracted by 1, and is\n * validated in the constructor.\n */\n bytes32 internal constant _ADMIN_SLOT = 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103;\n\n /**\n * @dev Returns the current admin.\n */\n function _getAdmin() internal view returns (address) {\n return StorageSlot.getAddressSlot(_ADMIN_SLOT).value;\n }\n\n /**\n * @dev Stores a new address in the EIP1967 admin slot.\n */\n function _setAdmin(address newAdmin) private {\n require(newAdmin != address(0), \"ERC1967: new admin is the zero address\");\n StorageSlot.getAddressSlot(_ADMIN_SLOT).value = newAdmin;\n }\n\n /**\n * @dev Changes the admin of the proxy.\n *\n * Emits an {AdminChanged} event.\n */\n function _changeAdmin(address newAdmin) internal {\n emit AdminChanged(_getAdmin(), newAdmin);\n _setAdmin(newAdmin);\n }\n\n /**\n * @dev The storage slot of the UpgradeableBeacon contract which defines the implementation for this proxy.\n * This is bytes32(uint256(keccak256('eip1967.proxy.beacon')) - 1)) and is validated in the constructor.\n */\n bytes32 internal constant _BEACON_SLOT = 0xa3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6cb3582b35133d50;\n\n /**\n * @dev Returns the current beacon.\n */\n function _getBeacon() internal view returns (address) {\n return StorageSlot.getAddressSlot(_BEACON_SLOT).value;\n }\n\n /**\n * @dev Stores a new beacon in the EIP1967 beacon slot.\n */\n function _setBeacon(address newBeacon) private {\n require(Address.isContract(newBeacon), \"ERC1967: new beacon is not a contract\");\n require(\n Address.isContract(IBeacon(newBeacon).implementation()),\n \"ERC1967: beacon implementation is not a contract\"\n );\n StorageSlot.getAddressSlot(_BEACON_SLOT).value = newBeacon;\n }\n\n /**\n * @dev Perform beacon upgrade with additional setup call. Note: This upgrades the address of the beacon, it does\n * not upgrade the implementation contained in the beacon (see {UpgradeableBeacon-_setImplementation} for that).\n *\n * Emits a {BeaconUpgraded} event.\n */\n function _upgradeBeaconToAndCall(address newBeacon, bytes memory data, bool forceCall) internal {\n _setBeacon(newBeacon);\n emit BeaconUpgraded(newBeacon);\n if (data.length > 0 || forceCall) {\n Address.functionDelegateCall(IBeacon(newBeacon).implementation(), data);\n }\n }\n}\n"
},
"@openzeppelin/contracts/proxy/Proxy.sol": {
"content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.6.0) (proxy/Proxy.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev This abstract contract provides a fallback function that delegates all calls to another contract using the EVM\n * instruction `delegatecall`. We refer to the second contract as the _implementation_ behind the proxy, and it has to\n * be specified by overriding the virtual {_implementation} function.\n *\n * Additionally, delegation to the implementation can be triggered manually through the {_fallback} function, or to a\n * different contract through the {_delegate} function.\n *\n * The success and return data of the delegated call will be returned back to the caller of the proxy.\n */\nabstract contract Proxy {\n /**\n * @dev Delegates the current call to `implementation`.\n *\n * This function does not return to its internal call site, it will return directly to the external caller.\n */\n function _delegate(address implementation) internal virtual {\n assembly {\n // Copy msg.data. We take full control of memory in this inline assembly\n // block because it will not return to Solidity code. We overwrite the\n // Solidity scratch pad at memory position 0.\n calldatacopy(0, 0, calldatasize())\n\n // Call the implementation.\n // out and outsize are 0 because we don't know the size yet.\n let result := delegatecall(gas(), implementation, 0, calldatasize(), 0, 0)\n\n // Copy the returned data.\n returndatacopy(0, 0, returndatasize())\n\n switch result\n // delegatecall returns 0 on error.\n case 0 {\n revert(0, returndatasize())\n }\n default {\n return(0, returndatasize())\n }\n }\n }\n\n /**\n * @dev This is a virtual function that should be overridden so it returns the address to which the fallback function\n * and {_fallback} should delegate.\n */\n function _implementation() internal view virtual returns (address);\n\n /**\n * @dev Delegates the current call to the address returned by `_implementation()`.\n *\n * This function does not return to its internal call site, it will return directly to the external caller.\n */\n function _fallback() internal virtual {\n _beforeFallback();\n _delegate(_implementation());\n }\n\n /**\n * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if no other\n * function in the contract matches the call data.\n */\n fallback() external payable virtual {\n _fallback();\n }\n\n /**\n * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if call data\n * is empty.\n */\n receive() external payable virtual {\n _fallback();\n }\n\n /**\n * @dev Hook that is called before falling back to the implementation. Can happen as part of a manual `_fallback`\n * call, or as part of the Solidity `fallback` or `receive` functions.\n *\n * If overridden should call `super._beforeFallback()`.\n */\n function _beforeFallback() internal virtual {}\n}\n"
},
"@openzeppelin/contracts/proxy/transparent/ProxyAdmin.sol": {
"content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.8.3) (proxy/transparent/ProxyAdmin.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./TransparentUpgradeableProxy.sol\";\nimport \"../../access/Ownable.sol\";\n\n/**\n * @dev This is an auxiliary contract meant to be assigned as the admin of a {TransparentUpgradeableProxy}. For an\n * explanation of why you would want to use this see the documentation for {TransparentUpgradeableProxy}.\n */\ncontract ProxyAdmin is Ownable {\n /**\n * @dev Returns the current implementation of `proxy`.\n *\n * Requirements:\n *\n * - This contract must be the admin of `proxy`.\n */\n function getProxyImplementation(ITransparentUpgradeableProxy proxy) public view virtual returns (address) {\n // We need to manually run the static call since the getter cannot be flagged as view\n // bytes4(keccak256(\"implementation()\")) == 0x5c60da1b\n (bool success, bytes memory returndata) = address(proxy).staticcall(hex\"5c60da1b\");\n require(success);\n return abi.decode(returndata, (address));\n }\n\n /**\n * @dev Returns the current admin of `proxy`.\n *\n * Requirements:\n *\n * - This contract must be the admin of `proxy`.\n */\n function getProxyAdmin(ITransparentUpgradeableProxy proxy) public view virtual returns (address) {\n // We need to manually run the static call since the getter cannot be flagged as view\n // bytes4(keccak256(\"admin()\")) == 0xf851a440\n (bool success, bytes memory returndata) = address(proxy).staticcall(hex\"f851a440\");\n require(success);\n return abi.decode(returndata, (address));\n }\n\n /**\n * @dev Changes the admin of `proxy` to `newAdmin`.\n *\n * Requirements:\n *\n * - This contract must be the current admin of `proxy`.\n */\n function changeProxyAdmin(ITransparentUpgradeableProxy proxy, address newAdmin) public virtual onlyOwner {\n proxy.changeAdmin(newAdmin);\n }\n\n /**\n * @dev Upgrades `proxy` to `implementation`. See {TransparentUpgradeableProxy-upgradeTo}.\n *\n * Requirements:\n *\n * - This contract must be the admin of `proxy`.\n */\n function upgrade(ITransparentUpgradeableProxy proxy, address implementation) public virtual onlyOwner {\n proxy.upgradeTo(implementation);\n }\n\n /**\n * @dev Upgrades `proxy` to `implementation` and calls a function on the new implementation. See\n * {TransparentUpgradeableProxy-upgradeToAndCall}.\n *\n * Requirements:\n *\n * - This contract must be the admin of `proxy`.\n */\n function upgradeAndCall(\n ITransparentUpgradeableProxy proxy,\n address implementation,\n bytes memory data\n ) public payable virtual onlyOwner {\n proxy.upgradeToAndCall{value: msg.value}(implementation, data);\n }\n}\n"
},
"@openzeppelin/contracts/proxy/transparent/TransparentUpgradeableProxy.sol": {
"content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (proxy/transparent/TransparentUpgradeableProxy.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../ERC1967/ERC1967Proxy.sol\";\n\n/**\n * @dev Interface for {TransparentUpgradeableProxy}. In order to implement transparency, {TransparentUpgradeableProxy}\n * does not implement this interface directly, and some of its functions are implemented by an internal dispatch\n * mechanism. The compiler is unaware that these functions are implemented by {TransparentUpgradeableProxy} and will not\n * include them in the ABI so this interface must be used to interact with it.\n */\ninterface ITransparentUpgradeableProxy is IERC1967 {\n function admin() external view returns (address);\n\n function implementation() external view returns (address);\n\n function changeAdmin(address) external;\n\n function upgradeTo(address) external;\n\n function upgradeToAndCall(address, bytes memory) external payable;\n}\n\n/**\n * @dev This contract implements a proxy that is upgradeable by an admin.\n *\n * To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector\n * clashing], which can potentially be used in an attack, this contract uses the\n * https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two\n * things that go hand in hand:\n *\n * 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if\n * that call matches one of the admin functions exposed by the proxy itself.\n * 2. If the admin calls the proxy, it can access the admin functions, but its calls will never be forwarded to the\n * implementation. If the admin tries to call a function on the implementation it will fail with an error that says\n * \"admin cannot fallback to proxy target\".\n *\n * These properties mean that the admin account can only be used for admin actions like upgrading the proxy or changing\n * the admin, so it's best if it's a dedicated account that is not used for anything else. This will avoid headaches due\n * to sudden errors when trying to call a function from the proxy implementation.\n *\n * Our recommendation is for the dedicated account to be an instance of the {ProxyAdmin} contract. If set up this way,\n * you should think of the `ProxyAdmin` instance as the real administrative interface of your proxy.\n *\n * NOTE: The real interface of this proxy is that defined in `ITransparentUpgradeableProxy`. This contract does not\n * inherit from that interface, and instead the admin functions are implicitly implemented using a custom dispatch\n * mechanism in `_fallback`. Consequently, the compiler will not produce an ABI for this contract. This is necessary to\n * fully implement transparency without decoding reverts caused by selector clashes between the proxy and the\n * implementation.\n *\n * WARNING: It is not recommended to extend this contract to add additional external functions. If you do so, the compiler\n * will not check that there are no selector conflicts, due to the note above. A selector clash between any new function\n * and the functions declared in {ITransparentUpgradeableProxy} will be resolved in favor of the new one. This could\n * render the admin operations inaccessible, which could prevent upgradeability. Transparency may also be compromised.\n */\ncontract TransparentUpgradeableProxy is ERC1967Proxy {\n /**\n * @dev Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and\n * optionally initialized with `_data` as explained in {ERC1967Proxy-constructor}.\n */\n constructor(address _logic, address admin_, bytes memory _data) payable ERC1967Proxy(_logic, _data) {\n _changeAdmin(admin_);\n }\n\n /**\n * @dev Modifier used internally that will delegate the call to the implementation unless the sender is the admin.\n *\n * CAUTION: This modifier is deprecated, as it could cause issues if the modified function has arguments, and the\n * implementation provides a function with the same selector.\n */\n modifier ifAdmin() {\n if (msg.sender == _getAdmin()) {\n _;\n } else {\n _fallback();\n }\n }\n\n /**\n * @dev If caller is the admin process the call internally, otherwise transparently fallback to the proxy behavior\n */\n function _fallback() internal virtual override {\n if (msg.sender == _getAdmin()) {\n bytes memory ret;\n bytes4 selector = msg.sig;\n if (selector == ITransparentUpgradeableProxy.upgradeTo.selector) {\n ret = _dispatchUpgradeTo();\n } else if (selector == ITransparentUpgradeableProxy.upgradeToAndCall.selector) {\n ret = _dispatchUpgradeToAndCall();\n } else if (selector == ITransparentUpgradeableProxy.changeAdmin.selector) {\n ret = _dispatchChangeAdmin();\n } else if (selector == ITransparentUpgradeableProxy.admin.selector) {\n ret = _dispatchAdmin();\n } else if (selector == ITransparentUpgradeableProxy.implementation.selector) {\n ret = _dispatchImplementation();\n } else {\n revert(\"TransparentUpgradeableProxy: admin cannot fallback to proxy target\");\n }\n assembly {\n return(add(ret, 0x20), mload(ret))\n }\n } else {\n super._fallback();\n }\n }\n\n /**\n * @dev Returns the current admin.\n *\n * TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the\n * https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.\n * `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`\n */\n function _dispatchAdmin() private returns (bytes memory) {\n _requireZeroValue();\n\n address admin = _getAdmin();\n return abi.encode(admin);\n }\n\n /**\n * @dev Returns the current implementation.\n *\n * TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the\n * https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.\n * `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`\n */\n function _dispatchImplementation() private returns (bytes memory) {\n _requireZeroValue();\n\n address implementation = _implementation();\n return abi.encode(implementation);\n }\n\n /**\n * @dev Changes the admin of the proxy.\n *\n * Emits an {AdminChanged} event.\n */\n function _dispatchChangeAdmin() private returns (bytes memory) {\n _requireZeroValue();\n\n address newAdmin = abi.decode(msg.data[4:], (address));\n _changeAdmin(newAdmin);\n\n return \"\";\n }\n\n /**\n * @dev Upgrade the implementation of the proxy.\n */\n function _dispatchUpgradeTo() private returns (bytes memory) {\n _requireZeroValue();\n\n address newImplementation = abi.decode(msg.data[4:], (address));\n _upgradeToAndCall(newImplementation, bytes(\"\"), false);\n\n return \"\";\n }\n\n /**\n * @dev Upgrade the implementation of the proxy, and then call a function from the new implementation as specified\n * by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the\n * proxied contract.\n */\n function _dispatchUpgradeToAndCall() private returns (bytes memory) {\n (address newImplementation, bytes memory data) = abi.decode(msg.data[4:], (address, bytes));\n _upgradeToAndCall(newImplementation, data, true);\n\n return \"\";\n }\n\n /**\n * @dev Returns the current admin.\n *\n * CAUTION: This function is deprecated. Use {ERC1967Upgrade-_getAdmin} instead.\n */\n function _admin() internal view virtual returns (address) {\n return _getAdmin();\n }\n\n /**\n * @dev To keep this contract fully transparent, all `ifAdmin` functions must be payable. This helper is here to\n * emulate some proxy functions being non-payable while still allowing value to pass through.\n */\n function _requireZeroValue() private {\n require(msg.value == 0);\n }\n}\n"
},
"@openzeppelin/contracts/security/Pausable.sol": {
"content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (security/Pausable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../utils/Context.sol\";\n\n/**\n * @dev Contract module which allows children to implement an emergency stop\n * mechanism that can be triggered by an authorized account.\n *\n * This module is used through inheritance. It will make available the\n * modifiers `whenNotPaused` and `whenPaused`, which can be applied to\n * the functions of your contract. Note that they will not be pausable by\n * simply including this module, only once the modifiers are put in place.\n */\nabstract contract Pausable is Context {\n /**\n * @dev Emitted when the pause is triggered by `account`.\n */\n event Paused(address account);\n\n /**\n * @dev Emitted when the pause is lifted by `account`.\n */\n event Unpaused(address account);\n\n bool private _paused;\n\n /**\n * @dev Initializes the contract in unpaused state.\n */\n constructor() {\n _paused = false;\n }\n\n /**\n * @dev Modifier to make a function callable only when the contract is not paused.\n *\n * Requirements:\n *\n * - The contract must not be paused.\n */\n modifier whenNotPaused() {\n _requireNotPaused();\n _;\n }\n\n /**\n * @dev Modifier to make a function callable only when the contract is paused.\n *\n * Requirements:\n *\n * - The contract must be paused.\n */\n modifier whenPaused() {\n _requirePaused();\n _;\n }\n\n /**\n * @dev Returns true if the contract is paused, and false otherwise.\n */\n function paused() public view virtual returns (bool) {\n return _paused;\n }\n\n /**\n * @dev Throws if the contract is paused.\n */\n function _requireNotPaused() internal view virtual {\n require(!paused(), \"Pausable: paused\");\n }\n\n /**\n * @dev Throws if the contract is not paused.\n */\n function _requirePaused() internal view virtual {\n require(paused(), \"Pausable: not paused\");\n }\n\n /**\n * @dev Triggers stopped state.\n *\n * Requirements:\n *\n * - The contract must not be paused.\n */\n function _pause() internal virtual whenNotPaused {\n _paused = true;\n emit Paused(_msgSender());\n }\n\n /**\n * @dev Returns to normal state.\n *\n * Requirements:\n *\n * - The contract must be paused.\n */\n function _unpause() internal virtual whenPaused {\n _paused = false;\n emit Unpaused(_msgSender());\n }\n}\n"
},
"@openzeppelin/contracts/security/ReentrancyGuard.sol": {
"content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (security/ReentrancyGuard.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Contract module that helps prevent reentrant calls to a function.\n *\n * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier\n * available, which can be applied to functions to make sure there are no nested\n * (reentrant) calls to them.\n *\n * Note that because there is a single `nonReentrant` guard, functions marked as\n * `nonReentrant` may not call one another. This can be worked around by making\n * those functions `private`, and then adding `external` `nonReentrant` entry\n * points to them.\n *\n * TIP: If you would like to learn more about reentrancy and alternative ways\n * to protect against it, check out our blog post\n * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].\n */\nabstract contract ReentrancyGuard {\n // Booleans are more expensive than uint256 or any type that takes up a full\n // word because each write operation emits an extra SLOAD to first read the\n // slot's contents, replace the bits taken up by the boolean, and then write\n // back. This is the compiler's defense against contract upgrades and\n // pointer aliasing, and it cannot be disabled.\n\n // The values being non-zero value makes deployment a bit more expensive,\n // but in exchange the refund on every call to nonReentrant will be lower in\n // amount. Since refunds are capped to a percentage of the total\n // transaction's gas, it is best to keep them low in cases like this one, to\n // increase the likelihood of the full refund coming into effect.\n uint256 private constant _NOT_ENTERED = 1;\n uint256 private constant _ENTERED = 2;\n\n uint256 private _status;\n\n constructor() {\n _status = _NOT_ENTERED;\n }\n\n /**\n * @dev Prevents a contract from calling itself, directly or indirectly.\n * Calling a `nonReentrant` function from another `nonReentrant`\n * function is not supported. It is possible to prevent this from happening\n * by making the `nonReentrant` function external, and making it call a\n * `private` function that does the actual work.\n */\n modifier nonReentrant() {\n _nonReentrantBefore();\n _;\n _nonReentrantAfter();\n }\n\n function _nonReentrantBefore() private {\n // On the first call to nonReentrant, _status will be _NOT_ENTERED\n require(_status != _ENTERED, \"ReentrancyGuard: reentrant call\");\n\n // Any calls to nonReentrant after this point will fail\n _status = _ENTERED;\n }\n\n function _nonReentrantAfter() private {\n // By storing the original value once again, a refund is triggered (see\n // https://eips.ethereum.org/EIPS/eip-2200)\n _status = _NOT_ENTERED;\n }\n\n /**\n * @dev Returns true if the reentrancy guard is currently set to \"entered\", which indicates there is a\n * `nonReentrant` function in the call stack.\n */\n function _reentrancyGuardEntered() internal view returns (bool) {\n return _status == _ENTERED;\n }\n}\n"
},
"@openzeppelin/contracts/token/ERC20/extensions/IERC20Permit.sol": {
"content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.4) (token/ERC20/extensions/IERC20Permit.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in\n * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].\n *\n * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by\n * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't\n * need to send a transaction, and thus is not required to hold Ether at all.\n *\n * ==== Security Considerations\n *\n * There are two important considerations concerning the use of `permit`. The first is that a valid permit signature\n * expresses an allowance, and it should not be assumed to convey additional meaning. In particular, it should not be\n * considered as an intention to spend the allowance in any specific way. The second is that because permits have\n * built-in replay protection and can be submitted by anyone, they can be frontrun. A protocol that uses permits should\n * take this into consideration and allow a `permit` call to fail. Combining these two aspects, a pattern that may be\n * generally recommended is:\n *\n * ```solidity\n * function doThingWithPermit(..., uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s) public {\n * try token.permit(msg.sender, address(this), value, deadline, v, r, s) {} catch {}\n * doThing(..., value);\n * }\n *\n * function doThing(..., uint256 value) public {\n * token.safeTransferFrom(msg.sender, address(this), value);\n * ...\n * }\n * ```\n *\n * Observe that: 1) `msg.sender` is used as the owner, leaving no ambiguity as to the signer intent, and 2) the use of\n * `try/catch` allows the permit to fail and makes the code tolerant to frontrunning. (See also\n * {SafeERC20-safeTransferFrom}).\n *\n * Additionally, note that smart contract wallets (such as Argent or Safe) are not able to produce permit signatures, so\n * contracts should have entry points that don't rely on permit.\n */\ninterface IERC20Permit {\n /**\n * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens,\n * given ``owner``'s signed approval.\n *\n * IMPORTANT: The same issues {IERC20-approve} has related to transaction\n * ordering also apply here.\n *\n * Emits an {Approval} event.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n * - `deadline` must be a timestamp in the future.\n * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner`\n * over the EIP712-formatted function arguments.\n * - the signature must use ``owner``'s current nonce (see {nonces}).\n *\n * For more information on the signature format, see the\n * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP\n * section].\n *\n * CAUTION: See Security Considerations above.\n */\n function permit(\n address owner,\n address spender,\n uint256 value,\n uint256 deadline,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) external;\n\n /**\n * @dev Returns the current nonce for `owner`. This value must be\n * included whenever a signature is generated for {permit}.\n *\n * Every successful call to {permit} increases ``owner``'s nonce by one. This\n * prevents a signature from being used multiple times.\n */\n function nonces(address owner) external view returns (uint256);\n\n /**\n * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}.\n */\n // solhint-disable-next-line func-name-mixedcase\n function DOMAIN_SEPARATOR() external view returns (bytes32);\n}\n"
},
"@openzeppelin/contracts/token/ERC20/IERC20.sol": {
"content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/IERC20.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC20 standard as defined in the EIP.\n */\ninterface IERC20 {\n /**\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\n * another (`to`).\n *\n * Note that `value` may be zero.\n */\n event Transfer(address indexed from, address indexed to, uint256 value);\n\n /**\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\n * a call to {approve}. `value` is the new allowance.\n */\n event Approval(address indexed owner, address indexed spender, uint256 value);\n\n /**\n * @dev Returns the amount of tokens in existence.\n */\n function totalSupply() external view returns (uint256);\n\n /**\n * @dev Returns the amount of tokens owned by `account`.\n */\n function balanceOf(address account) external view returns (uint256);\n\n /**\n * @dev Moves `amount` tokens from the caller's account to `to`.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * Emits a {Transfer} event.\n */\n function transfer(address to, uint256 amount) external returns (bool);\n\n /**\n * @dev Returns the remaining number of tokens that `spender` will be\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\n * zero by default.\n *\n * This value changes when {approve} or {transferFrom} are called.\n */\n function allowance(address owner, address spender) external view returns (uint256);\n\n /**\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\n * that someone may use both the old and the new allowance by unfortunate\n * transaction ordering. One possible solution to mitigate this race\n * condition is to first reduce the spender's allowance to 0 and set the\n * desired value afterwards:\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\n *\n * Emits an {Approval} event.\n */\n function approve(address spender, uint256 amount) external returns (bool);\n\n /**\n * @dev Moves `amount` tokens from `from` to `to` using the\n * allowance mechanism. `amount` is then deducted from the caller's\n * allowance.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * Emits a {Transfer} event.\n */\n function transferFrom(address from, address to, uint256 amount) external returns (bool);\n}\n"
},
"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol": {
"content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.3) (token/ERC20/utils/SafeERC20.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC20.sol\";\nimport \"../extensions/IERC20Permit.sol\";\nimport \"../../../utils/Address.sol\";\n\n/**\n * @title SafeERC20\n * @dev Wrappers around ERC20 operations that throw on failure (when the token\n * contract returns false). Tokens that return no value (and instead revert or\n * throw on failure) are also supported, non-reverting calls are assumed to be\n * successful.\n * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,\n * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\n */\nlibrary SafeERC20 {\n using Address for address;\n\n /**\n * @dev Transfer `value` amount of `token` from the calling contract to `to`. If `token` returns no value,\n * non-reverting calls are assumed to be successful.\n */\n function safeTransfer(IERC20 token, address to, uint256 value) internal {\n _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\n }\n\n /**\n * @dev Transfer `value` amount of `token` from `from` to `to`, spending the approval given by `from` to the\n * calling contract. If `token` returns no value, non-reverting calls are assumed to be successful.\n */\n function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal {\n _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));\n }\n\n /**\n * @dev Deprecated. This function has issues similar to the ones found in\n * {IERC20-approve}, and its usage is discouraged.\n *\n * Whenever possible, use {safeIncreaseAllowance} and\n * {safeDecreaseAllowance} instead.\n */\n function safeApprove(IERC20 token, address spender, uint256 value) internal {\n // safeApprove should only be called when setting an initial allowance,\n // or when resetting it to zero. To increase and decrease it, use\n // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'\n require(\n (value == 0) || (token.allowance(address(this), spender) == 0),\n \"SafeERC20: approve from non-zero to non-zero allowance\"\n );\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));\n }\n\n /**\n * @dev Increase the calling contract's allowance toward `spender` by `value`. If `token` returns no value,\n * non-reverting calls are assumed to be successful.\n */\n function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal {\n uint256 oldAllowance = token.allowance(address(this), spender);\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance + value));\n }\n\n /**\n * @dev Decrease the calling contract's allowance toward `spender` by `value`. If `token` returns no value,\n * non-reverting calls are assumed to be successful.\n */\n function safeDecreaseAllowance(IERC20 token, address spender, uint256 value) internal {\n unchecked {\n uint256 oldAllowance = token.allowance(address(this), spender);\n require(oldAllowance >= value, \"SafeERC20: decreased allowance below zero\");\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance - value));\n }\n }\n\n /**\n * @dev Set the calling contract's allowance toward `spender` to `value`. If `token` returns no value,\n * non-reverting calls are assumed to be successful. Meant to be used with tokens that require the approval\n * to be set to zero before setting it to a non-zero value, such as USDT.\n */\n function forceApprove(IERC20 token, address spender, uint256 value) internal {\n bytes memory approvalCall = abi.encodeWithSelector(token.approve.selector, spender, value);\n\n if (!_callOptionalReturnBool(token, approvalCall)) {\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, 0));\n _callOptionalReturn(token, approvalCall);\n }\n }\n\n /**\n * @dev Use a ERC-2612 signature to set the `owner` approval toward `spender` on `token`.\n * Revert on invalid signature.\n */\n function safePermit(\n IERC20Permit token,\n address owner,\n address spender,\n uint256 value,\n uint256 deadline,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal {\n uint256 nonceBefore = token.nonces(owner);\n token.permit(owner, spender, value, deadline, v, r, s);\n uint256 nonceAfter = token.nonces(owner);\n require(nonceAfter == nonceBefore + 1, \"SafeERC20: permit did not succeed\");\n }\n\n /**\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\n * on the return value: the return value is optional (but if data is returned, it must not be false).\n * @param token The token targeted by the call.\n * @param data The call data (encoded using abi.encode or one of its variants).\n */\n function _callOptionalReturn(IERC20 token, bytes memory data) private {\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\n // we're implementing it ourselves. We use {Address-functionCall} to perform this call, which verifies that\n // the target address contains contract code and also asserts for success in the low-level call.\n\n bytes memory returndata = address(token).functionCall(data, \"SafeERC20: low-level call failed\");\n require(returndata.length == 0 || abi.decode(returndata, (bool)), \"SafeERC20: ERC20 operation did not succeed\");\n }\n\n /**\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\n * on the return value: the return value is optional (but if data is returned, it must not be false).\n * @param token The token targeted by the call.\n * @param data The call data (encoded using abi.encode or one of its variants).\n *\n * This is a variant of {_callOptionalReturn} that silents catches all reverts and returns a bool instead.\n */\n function _callOptionalReturnBool(IERC20 token, bytes memory data) private returns (bool) {\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\n // we're implementing it ourselves. We cannot use {Address-functionCall} here since this should return false\n // and not revert is the subcall reverts.\n\n (bool success, bytes memory returndata) = address(token).call(data);\n return\n success && (returndata.length == 0 || abi.decode(returndata, (bool))) && Address.isContract(address(token));\n }\n}\n"
},
"@openzeppelin/contracts/utils/Address.sol": {
"content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/Address.sol)\n\npragma solidity ^0.8.1;\n\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary Address {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n *\n * Furthermore, `isContract` will also return true if the target contract within\n * the same transaction is already scheduled for destruction by `SELFDESTRUCT`,\n * which only has an effect at the end of a transaction.\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length > 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://consensys.net/diligence/blog/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.8.0/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance >= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance >= value, \"Address: insufficient balance for call\");\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionDelegateCall(target, data, \"Address: low-level delegate call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n (bool success, bytes memory returndata) = target.delegatecall(data);\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling\n * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract.\n *\n * _Available since v4.8._\n */\n function verifyCallResultFromTarget(\n address target,\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n if (success) {\n if (returndata.length == 0) {\n // only check isContract if the call was successful and the return data is empty\n // otherwise we already know that it was a contract\n require(isContract(target), \"Address: call to non-contract\");\n }\n return returndata;\n } else {\n _revert(returndata, errorMessage);\n }\n }\n\n /**\n * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason or using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n _revert(returndata, errorMessage);\n }\n }\n\n function _revert(bytes memory returndata, string memory errorMessage) private pure {\n // Look for revert reason and bubble it up if present\n if (returndata.length > 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n /// @solidity memory-safe-assembly\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n}\n"
},
"@openzeppelin/contracts/utils/Context.sol": {
"content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.4) (utils/Context.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract Context {\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n function _contextSuffixLength() internal view virtual returns (uint256) {\n return 0;\n }\n}\n"
},
"@openzeppelin/contracts/utils/introspection/ERC165.sol": {
"content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC165.sol\";\n\n/**\n * @dev Implementation of the {IERC165} interface.\n *\n * Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check\n * for the additional interface id that will be supported. For example:\n *\n * ```solidity\n * function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n * return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId);\n * }\n * ```\n *\n * Alternatively, {ERC165Storage} provides an easier to use but more expensive implementation.\n */\nabstract contract ERC165 is IERC165 {\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n return interfaceId == type(IERC165).interfaceId;\n }\n}\n"
},
"@openzeppelin/contracts/utils/introspection/IERC165.sol": {
"content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC165 standard, as defined in the\n * https://eips.ethereum.org/EIPS/eip-165[EIP].\n *\n * Implementers can declare support of contract interfaces, which can then be\n * queried by others ({ERC165Checker}).\n *\n * For an implementation, see {ERC165}.\n */\ninterface IERC165 {\n /**\n * @dev Returns true if this contract implements the interface defined by\n * `interfaceId`. See the corresponding\n * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]\n * to learn more about how these ids are created.\n *\n * This function call must use less than 30 000 gas.\n */\n function supportsInterface(bytes4 interfaceId) external view returns (bool);\n}\n"
},
"@openzeppelin/contracts/utils/math/Math.sol": {
"content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/math/Math.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Standard math utilities missing in the Solidity language.\n */\nlibrary Math {\n enum Rounding {\n Down, // Toward negative infinity\n Up, // Toward infinity\n Zero // Toward zero\n }\n\n /**\n * @dev Returns the largest of two numbers.\n */\n function max(uint256 a, uint256 b) internal pure returns (uint256) {\n return a > b ? a : b;\n }\n\n /**\n * @dev Returns the smallest of two numbers.\n */\n function min(uint256 a, uint256 b) internal pure returns (uint256) {\n return a < b ? a : b;\n }\n\n /**\n * @dev Returns the average of two numbers. The result is rounded towards\n * zero.\n */\n function average(uint256 a, uint256 b) internal pure returns (uint256) {\n // (a + b) / 2 can overflow.\n return (a & b) + (a ^ b) / 2;\n }\n\n /**\n * @dev Returns the ceiling of the division of two numbers.\n *\n * This differs from standard division with `/` in that it rounds up instead\n * of rounding down.\n */\n function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) {\n // (a + b - 1) / b can overflow on addition, so we distribute.\n return a == 0 ? 0 : (a - 1) / b + 1;\n }\n\n /**\n * @notice Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or denominator == 0\n * @dev Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv)\n * with further edits by Uniswap Labs also under MIT license.\n */\n function mulDiv(uint256 x, uint256 y, uint256 denominator) internal pure returns (uint256 result) {\n unchecked {\n // 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use\n // use the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256\n // variables such that product = prod1 * 2^256 + prod0.\n uint256 prod0; // Least significant 256 bits of the product\n uint256 prod1; // Most significant 256 bits of the product\n assembly {\n let mm := mulmod(x, y, not(0))\n prod0 := mul(x, y)\n prod1 := sub(sub(mm, prod0), lt(mm, prod0))\n }\n\n // Handle non-overflow cases, 256 by 256 division.\n if (prod1 == 0) {\n // Solidity will revert if denominator == 0, unlike the div opcode on its own.\n // The surrounding unchecked block does not change this fact.\n // See https://docs.soliditylang.org/en/latest/control-structures.html#checked-or-unchecked-arithmetic.\n return prod0 / denominator;\n }\n\n // Make sure the result is less than 2^256. Also prevents denominator == 0.\n require(denominator > prod1, \"Math: mulDiv overflow\");\n\n ///////////////////////////////////////////////\n // 512 by 256 division.\n ///////////////////////////////////////////////\n\n // Make division exact by subtracting the remainder from [prod1 prod0].\n uint256 remainder;\n assembly {\n // Compute remainder using mulmod.\n remainder := mulmod(x, y, denominator)\n\n // Subtract 256 bit number from 512 bit number.\n prod1 := sub(prod1, gt(remainder, prod0))\n prod0 := sub(prod0, remainder)\n }\n\n // Factor powers of two out of denominator and compute largest power of two divisor of denominator. Always >= 1.\n // See https://cs.stackexchange.com/q/138556/92363.\n\n // Does not overflow because the denominator cannot be zero at this stage in the function.\n uint256 twos = denominator & (~denominator + 1);\n assembly {\n // Divide denominator by twos.\n denominator := div(denominator, twos)\n\n // Divide [prod1 prod0] by twos.\n prod0 := div(prod0, twos)\n\n // Flip twos such that it is 2^256 / twos. If twos is zero, then it becomes one.\n twos := add(div(sub(0, twos), twos), 1)\n }\n\n // Shift in bits from prod1 into prod0.\n prod0 |= prod1 * twos;\n\n // Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such\n // that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for\n // four bits. That is, denominator * inv = 1 mod 2^4.\n uint256 inverse = (3 * denominator) ^ 2;\n\n // Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also works\n // in modular arithmetic, doubling the correct bits in each step.\n inverse *= 2 - denominator * inverse; // inverse mod 2^8\n inverse *= 2 - denominator * inverse; // inverse mod 2^16\n inverse *= 2 - denominator * inverse; // inverse mod 2^32\n inverse *= 2 - denominator * inverse; // inverse mod 2^64\n inverse *= 2 - denominator * inverse; // inverse mod 2^128\n inverse *= 2 - denominator * inverse; // inverse mod 2^256\n\n // Because the division is now exact we can divide by multiplying with the modular inverse of denominator.\n // This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is\n // less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1\n // is no longer required.\n result = prod0 * inverse;\n return result;\n }\n }\n\n /**\n * @notice Calculates x * y / denominator with full precision, following the selected rounding direction.\n */\n function mulDiv(uint256 x, uint256 y, uint256 denominator, Rounding rounding) internal pure returns (uint256) {\n uint256 result = mulDiv(x, y, denominator);\n if (rounding == Rounding.Up && mulmod(x, y, denominator) > 0) {\n result += 1;\n }\n return result;\n }\n\n /**\n * @dev Returns the square root of a number. If the number is not a perfect square, the value is rounded down.\n *\n * Inspired by Henry S. Warren, Jr.'s \"Hacker's Delight\" (Chapter 11).\n */\n function sqrt(uint256 a) internal pure returns (uint256) {\n if (a == 0) {\n return 0;\n }\n\n // For our first guess, we get the biggest power of 2 which is smaller than the square root of the target.\n //\n // We know that the \"msb\" (most significant bit) of our target number `a` is a power of 2 such that we have\n // `msb(a) <= a < 2*msb(a)`. This value can be written `msb(a)=2**k` with `k=log2(a)`.\n //\n // This can be rewritten `2**log2(a) <= a < 2**(log2(a) + 1)`\n // → `sqrt(2**k) <= sqrt(a) < sqrt(2**(k+1))`\n // → `2**(k/2) <= sqrt(a) < 2**((k+1)/2) <= 2**(k/2 + 1)`\n //\n // Consequently, `2**(log2(a) / 2)` is a good first approximation of `sqrt(a)` with at least 1 correct bit.\n uint256 result = 1 << (log2(a) >> 1);\n\n // At this point `result` is an estimation with one bit of precision. We know the true value is a uint128,\n // since it is the square root of a uint256. Newton's method converges quadratically (precision doubles at\n // every iteration). We thus need at most 7 iteration to turn our partial result with one bit of precision\n // into the expected uint128 result.\n unchecked {\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n return min(result, a / result);\n }\n }\n\n /**\n * @notice Calculates sqrt(a), following the selected rounding direction.\n */\n function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) {\n unchecked {\n uint256 result = sqrt(a);\n return result + (rounding == Rounding.Up && result * result < a ? 1 : 0);\n }\n }\n\n /**\n * @dev Return the log in base 2, rounded down, of a positive value.\n * Returns 0 if given 0.\n */\n function log2(uint256 value) internal pure returns (uint256) {\n uint256 result = 0;\n unchecked {\n if (value >> 128 > 0) {\n value >>= 128;\n result += 128;\n }\n if (value >> 64 > 0) {\n value >>= 64;\n result += 64;\n }\n if (value >> 32 > 0) {\n value >>= 32;\n result += 32;\n }\n if (value >> 16 > 0) {\n value >>= 16;\n result += 16;\n }\n if (value >> 8 > 0) {\n value >>= 8;\n result += 8;\n }\n if (value >> 4 > 0) {\n value >>= 4;\n result += 4;\n }\n if (value >> 2 > 0) {\n value >>= 2;\n result += 2;\n }\n if (value >> 1 > 0) {\n result += 1;\n }\n }\n return result;\n }\n\n /**\n * @dev Return the log in base 2, following the selected rounding direction, of a positive value.\n * Returns 0 if given 0.\n */\n function log2(uint256 value, Rounding rounding) internal pure returns (uint256) {\n unchecked {\n uint256 result = log2(value);\n return result + (rounding == Rounding.Up && 1 << result < value ? 1 : 0);\n }\n }\n\n /**\n * @dev Return the log in base 10, rounded down, of a positive value.\n * Returns 0 if given 0.\n */\n function log10(uint256 value) internal pure returns (uint256) {\n uint256 result = 0;\n unchecked {\n if (value >= 10 ** 64) {\n value /= 10 ** 64;\n result += 64;\n }\n if (value >= 10 ** 32) {\n value /= 10 ** 32;\n result += 32;\n }\n if (value >= 10 ** 16) {\n value /= 10 ** 16;\n result += 16;\n }\n if (value >= 10 ** 8) {\n value /= 10 ** 8;\n result += 8;\n }\n if (value >= 10 ** 4) {\n value /= 10 ** 4;\n result += 4;\n }\n if (value >= 10 ** 2) {\n value /= 10 ** 2;\n result += 2;\n }\n if (value >= 10 ** 1) {\n result += 1;\n }\n }\n return result;\n }\n\n /**\n * @dev Return the log in base 10, following the selected rounding direction, of a positive value.\n * Returns 0 if given 0.\n */\n function log10(uint256 value, Rounding rounding) internal pure returns (uint256) {\n unchecked {\n uint256 result = log10(value);\n return result + (rounding == Rounding.Up && 10 ** result < value ? 1 : 0);\n }\n }\n\n /**\n * @dev Return the log in base 256, rounded down, of a positive value.\n * Returns 0 if given 0.\n *\n * Adding one to the result gives the number of pairs of hex symbols needed to represent `value` as a hex string.\n */\n function log256(uint256 value) internal pure returns (uint256) {\n uint256 result = 0;\n unchecked {\n if (value >> 128 > 0) {\n value >>= 128;\n result += 16;\n }\n if (value >> 64 > 0) {\n value >>= 64;\n result += 8;\n }\n if (value >> 32 > 0) {\n value >>= 32;\n result += 4;\n }\n if (value >> 16 > 0) {\n value >>= 16;\n result += 2;\n }\n if (value >> 8 > 0) {\n result += 1;\n }\n }\n return result;\n }\n\n /**\n * @dev Return the log in base 256, following the selected rounding direction, of a positive value.\n * Returns 0 if given 0.\n */\n function log256(uint256 value, Rounding rounding) internal pure returns (uint256) {\n unchecked {\n uint256 result = log256(value);\n return result + (rounding == Rounding.Up && 1 << (result << 3) < value ? 1 : 0);\n }\n }\n}\n"
},
"@openzeppelin/contracts/utils/math/SafeCast.sol": {
"content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.8.0) (utils/math/SafeCast.sol)\n// This file was procedurally generated from scripts/generate/templates/SafeCast.js.\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Wrappers over Solidity's uintXX/intXX casting operators with added overflow\n * checks.\n *\n * Downcasting from uint256/int256 in Solidity does not revert on overflow. This can\n * easily result in undesired exploitation or bugs, since developers usually\n * assume that overflows raise errors. `SafeCast` restores this intuition by\n * reverting the transaction when such an operation overflows.\n *\n * Using this library instead of the unchecked operations eliminates an entire\n * class of bugs, so it's recommended to use it always.\n *\n * Can be combined with {SafeMath} and {SignedSafeMath} to extend it to smaller types, by performing\n * all math on `uint256` and `int256` and then downcasting.\n */\nlibrary SafeCast {\n /**\n * @dev Returns the downcasted uint248 from uint256, reverting on\n * overflow (when the input is greater than largest uint248).\n *\n * Counterpart to Solidity's `uint248` operator.\n *\n * Requirements:\n *\n * - input must fit into 248 bits\n *\n * _Available since v4.7._\n */\n function toUint248(uint256 value) internal pure returns (uint248) {\n require(value <= type(uint248).max, \"SafeCast: value doesn't fit in 248 bits\");\n return uint248(value);\n }\n\n /**\n * @dev Returns the downcasted uint240 from uint256, reverting on\n * overflow (when the input is greater than largest uint240).\n *\n * Counterpart to Solidity's `uint240` operator.\n *\n * Requirements:\n *\n * - input must fit into 240 bits\n *\n * _Available since v4.7._\n */\n function toUint240(uint256 value) internal pure returns (uint240) {\n require(value <= type(uint240).max, \"SafeCast: value doesn't fit in 240 bits\");\n return uint240(value);\n }\n\n /**\n * @dev Returns the downcasted uint232 from uint256, reverting on\n * overflow (when the input is greater than largest uint232).\n *\n * Counterpart to Solidity's `uint232` operator.\n *\n * Requirements:\n *\n * - input must fit into 232 bits\n *\n * _Available since v4.7._\n */\n function toUint232(uint256 value) internal pure returns (uint232) {\n require(value <= type(uint232).max, \"SafeCast: value doesn't fit in 232 bits\");\n return uint232(value);\n }\n\n /**\n * @dev Returns the downcasted uint224 from uint256, reverting on\n * overflow (when the input is greater than largest uint224).\n *\n * Counterpart to Solidity's `uint224` operator.\n *\n * Requirements:\n *\n * - input must fit into 224 bits\n *\n * _Available since v4.2._\n */\n function toUint224(uint256 value) internal pure returns (uint224) {\n require(value <= type(uint224).max, \"SafeCast: value doesn't fit in 224 bits\");\n return uint224(value);\n }\n\n /**\n * @dev Returns the downcasted uint216 from uint256, reverting on\n * overflow (when the input is greater than largest uint216).\n *\n * Counterpart to Solidity's `uint216` operator.\n *\n * Requirements:\n *\n * - input must fit into 216 bits\n *\n * _Available since v4.7._\n */\n function toUint216(uint256 value) internal pure returns (uint216) {\n require(value <= type(uint216).max, \"SafeCast: value doesn't fit in 216 bits\");\n return uint216(value);\n }\n\n /**\n * @dev Returns the downcasted uint208 from uint256, reverting on\n * overflow (when the input is greater than largest uint208).\n *\n * Counterpart to Solidity's `uint208` operator.\n *\n * Requirements:\n *\n * - input must fit into 208 bits\n *\n * _Available since v4.7._\n */\n function toUint208(uint256 value) internal pure returns (uint208) {\n require(value <= type(uint208).max, \"SafeCast: value doesn't fit in 208 bits\");\n return uint208(value);\n }\n\n /**\n * @dev Returns the downcasted uint200 from uint256, reverting on\n * overflow (when the input is greater than largest uint200).\n *\n * Counterpart to Solidity's `uint200` operator.\n *\n * Requirements:\n *\n * - input must fit into 200 bits\n *\n * _Available since v4.7._\n */\n function toUint200(uint256 value) internal pure returns (uint200) {\n require(value <= type(uint200).max, \"SafeCast: value doesn't fit in 200 bits\");\n return uint200(value);\n }\n\n /**\n * @dev Returns the downcasted uint192 from uint256, reverting on\n * overflow (when the input is greater than largest uint192).\n *\n * Counterpart to Solidity's `uint192` operator.\n *\n * Requirements:\n *\n * - input must fit into 192 bits\n *\n * _Available since v4.7._\n */\n function toUint192(uint256 value) internal pure returns (uint192) {\n require(value <= type(uint192).max, \"SafeCast: value doesn't fit in 192 bits\");\n return uint192(value);\n }\n\n /**\n * @dev Returns the downcasted uint184 from uint256, reverting on\n * overflow (when the input is greater than largest uint184).\n *\n * Counterpart to Solidity's `uint184` operator.\n *\n * Requirements:\n *\n * - input must fit into 184 bits\n *\n * _Available since v4.7._\n */\n function toUint184(uint256 value) internal pure returns (uint184) {\n require(value <= type(uint184).max, \"SafeCast: value doesn't fit in 184 bits\");\n return uint184(value);\n }\n\n /**\n * @dev Returns the downcasted uint176 from uint256, reverting on\n * overflow (when the input is greater than largest uint176).\n *\n * Counterpart to Solidity's `uint176` operator.\n *\n * Requirements:\n *\n * - input must fit into 176 bits\n *\n * _Available since v4.7._\n */\n function toUint176(uint256 value) internal pure returns (uint176) {\n require(value <= type(uint176).max, \"SafeCast: value doesn't fit in 176 bits\");\n return uint176(value);\n }\n\n /**\n * @dev Returns the downcasted uint168 from uint256, reverting on\n * overflow (when the input is greater than largest uint168).\n *\n * Counterpart to Solidity's `uint168` operator.\n *\n * Requirements:\n *\n * - input must fit into 168 bits\n *\n * _Available since v4.7._\n */\n function toUint168(uint256 value) internal pure returns (uint168) {\n require(value <= type(uint168).max, \"SafeCast: value doesn't fit in 168 bits\");\n return uint168(value);\n }\n\n /**\n * @dev Returns the downcasted uint160 from uint256, reverting on\n * overflow (when the input is greater than largest uint160).\n *\n * Counterpart to Solidity's `uint160` operator.\n *\n * Requirements:\n *\n * - input must fit into 160 bits\n *\n * _Available since v4.7._\n */\n function toUint160(uint256 value) internal pure returns (uint160) {\n require(value <= type(uint160).max, \"SafeCast: value doesn't fit in 160 bits\");\n return uint160(value);\n }\n\n /**\n * @dev Returns the downcasted uint152 from uint256, reverting on\n * overflow (when the input is greater than largest uint152).\n *\n * Counterpart to Solidity's `uint152` operator.\n *\n * Requirements:\n *\n * - input must fit into 152 bits\n *\n * _Available since v4.7._\n */\n function toUint152(uint256 value) internal pure returns (uint152) {\n require(value <= type(uint152).max, \"SafeCast: value doesn't fit in 152 bits\");\n return uint152(value);\n }\n\n /**\n * @dev Returns the downcasted uint144 from uint256, reverting on\n * overflow (when the input is greater than largest uint144).\n *\n * Counterpart to Solidity's `uint144` operator.\n *\n * Requirements:\n *\n * - input must fit into 144 bits\n *\n * _Available since v4.7._\n */\n function toUint144(uint256 value) internal pure returns (uint144) {\n require(value <= type(uint144).max, \"SafeCast: value doesn't fit in 144 bits\");\n return uint144(value);\n }\n\n /**\n * @dev Returns the downcasted uint136 from uint256, reverting on\n * overflow (when the input is greater than largest uint136).\n *\n * Counterpart to Solidity's `uint136` operator.\n *\n * Requirements:\n *\n * - input must fit into 136 bits\n *\n * _Available since v4.7._\n */\n function toUint136(uint256 value) internal pure returns (uint136) {\n require(value <= type(uint136).max, \"SafeCast: value doesn't fit in 136 bits\");\n return uint136(value);\n }\n\n /**\n * @dev Returns the downcasted uint128 from uint256, reverting on\n * overflow (when the input is greater than largest uint128).\n *\n * Counterpart to Solidity's `uint128` operator.\n *\n * Requirements:\n *\n * - input must fit into 128 bits\n *\n * _Available since v2.5._\n */\n function toUint128(uint256 value) internal pure returns (uint128) {\n require(value <= type(uint128).max, \"SafeCast: value doesn't fit in 128 bits\");\n return uint128(value);\n }\n\n /**\n * @dev Returns the downcasted uint120 from uint256, reverting on\n * overflow (when the input is greater than largest uint120).\n *\n * Counterpart to Solidity's `uint120` operator.\n *\n * Requirements:\n *\n * - input must fit into 120 bits\n *\n * _Available since v4.7._\n */\n function toUint120(uint256 value) internal pure returns (uint120) {\n require(value <= type(uint120).max, \"SafeCast: value doesn't fit in 120 bits\");\n return uint120(value);\n }\n\n /**\n * @dev Returns the downcasted uint112 from uint256, reverting on\n * overflow (when the input is greater than largest uint112).\n *\n * Counterpart to Solidity's `uint112` operator.\n *\n * Requirements:\n *\n * - input must fit into 112 bits\n *\n * _Available since v4.7._\n */\n function toUint112(uint256 value) internal pure returns (uint112) {\n require(value <= type(uint112).max, \"SafeCast: value doesn't fit in 112 bits\");\n return uint112(value);\n }\n\n /**\n * @dev Returns the downcasted uint104 from uint256, reverting on\n * overflow (when the input is greater than largest uint104).\n *\n * Counterpart to Solidity's `uint104` operator.\n *\n * Requirements:\n *\n * - input must fit into 104 bits\n *\n * _Available since v4.7._\n */\n function toUint104(uint256 value) internal pure returns (uint104) {\n require(value <= type(uint104).max, \"SafeCast: value doesn't fit in 104 bits\");\n return uint104(value);\n }\n\n /**\n * @dev Returns the downcasted uint96 from uint256, reverting on\n * overflow (when the input is greater than largest uint96).\n *\n * Counterpart to Solidity's `uint96` operator.\n *\n * Requirements:\n *\n * - input must fit into 96 bits\n *\n * _Available since v4.2._\n */\n function toUint96(uint256 value) internal pure returns (uint96) {\n require(value <= type(uint96).max, \"SafeCast: value doesn't fit in 96 bits\");\n return uint96(value);\n }\n\n /**\n * @dev Returns the downcasted uint88 from uint256, reverting on\n * overflow (when the input is greater than largest uint88).\n *\n * Counterpart to Solidity's `uint88` operator.\n *\n * Requirements:\n *\n * - input must fit into 88 bits\n *\n * _Available since v4.7._\n */\n function toUint88(uint256 value) internal pure returns (uint88) {\n require(value <= type(uint88).max, \"SafeCast: value doesn't fit in 88 bits\");\n return uint88(value);\n }\n\n /**\n * @dev Returns the downcasted uint80 from uint256, reverting on\n * overflow (when the input is greater than largest uint80).\n *\n * Counterpart to Solidity's `uint80` operator.\n *\n * Requirements:\n *\n * - input must fit into 80 bits\n *\n * _Available since v4.7._\n */\n function toUint80(uint256 value) internal pure returns (uint80) {\n require(value <= type(uint80).max, \"SafeCast: value doesn't fit in 80 bits\");\n return uint80(value);\n }\n\n /**\n * @dev Returns the downcasted uint72 from uint256, reverting on\n * overflow (when the input is greater than largest uint72).\n *\n * Counterpart to Solidity's `uint72` operator.\n *\n * Requirements:\n *\n * - input must fit into 72 bits\n *\n * _Available since v4.7._\n */\n function toUint72(uint256 value) internal pure returns (uint72) {\n require(value <= type(uint72).max, \"SafeCast: value doesn't fit in 72 bits\");\n return uint72(value);\n }\n\n /**\n * @dev Returns the downcasted uint64 from uint256, reverting on\n * overflow (when the input is greater than largest uint64).\n *\n * Counterpart to Solidity's `uint64` operator.\n *\n * Requirements:\n *\n * - input must fit into 64 bits\n *\n * _Available since v2.5._\n */\n function toUint64(uint256 value) internal pure returns (uint64) {\n require(value <= type(uint64).max, \"SafeCast: value doesn't fit in 64 bits\");\n return uint64(value);\n }\n\n /**\n * @dev Returns the downcasted uint56 from uint256, reverting on\n * overflow (when the input is greater than largest uint56).\n *\n * Counterpart to Solidity's `uint56` operator.\n *\n * Requirements:\n *\n * - input must fit into 56 bits\n *\n * _Available since v4.7._\n */\n function toUint56(uint256 value) internal pure returns (uint56) {\n require(value <= type(uint56).max, \"SafeCast: value doesn't fit in 56 bits\");\n return uint56(value);\n }\n\n /**\n * @dev Returns the downcasted uint48 from uint256, reverting on\n * overflow (when the input is greater than largest uint48).\n *\n * Counterpart to Solidity's `uint48` operator.\n *\n * Requirements:\n *\n * - input must fit into 48 bits\n *\n * _Available since v4.7._\n */\n function toUint48(uint256 value) internal pure returns (uint48) {\n require(value <= type(uint48).max, \"SafeCast: value doesn't fit in 48 bits\");\n return uint48(value);\n }\n\n /**\n * @dev Returns the downcasted uint40 from uint256, reverting on\n * overflow (when the input is greater than largest uint40).\n *\n * Counterpart to Solidity's `uint40` operator.\n *\n * Requirements:\n *\n * - input must fit into 40 bits\n *\n * _Available since v4.7._\n */\n function toUint40(uint256 value) internal pure returns (uint40) {\n require(value <= type(uint40).max, \"SafeCast: value doesn't fit in 40 bits\");\n return uint40(value);\n }\n\n /**\n * @dev Returns the downcasted uint32 from uint256, reverting on\n * overflow (when the input is greater than largest uint32).\n *\n * Counterpart to Solidity's `uint32` operator.\n *\n * Requirements:\n *\n * - input must fit into 32 bits\n *\n * _Available since v2.5._\n */\n function toUint32(uint256 value) internal pure returns (uint32) {\n require(value <= type(uint32).max, \"SafeCast: value doesn't fit in 32 bits\");\n return uint32(value);\n }\n\n /**\n * @dev Returns the downcasted uint24 from uint256, reverting on\n * overflow (when the input is greater than largest uint24).\n *\n * Counterpart to Solidity's `uint24` operator.\n *\n * Requirements:\n *\n * - input must fit into 24 bits\n *\n * _Available since v4.7._\n */\n function toUint24(uint256 value) internal pure returns (uint24) {\n require(value <= type(uint24).max, \"SafeCast: value doesn't fit in 24 bits\");\n return uint24(value);\n }\n\n /**\n * @dev Returns the downcasted uint16 from uint256, reverting on\n * overflow (when the input is greater than largest uint16).\n *\n * Counterpart to Solidity's `uint16` operator.\n *\n * Requirements:\n *\n * - input must fit into 16 bits\n *\n * _Available since v2.5._\n */\n function toUint16(uint256 value) internal pure returns (uint16) {\n require(value <= type(uint16).max, \"SafeCast: value doesn't fit in 16 bits\");\n return uint16(value);\n }\n\n /**\n * @dev Returns the downcasted uint8 from uint256, reverting on\n * overflow (when the input is greater than largest uint8).\n *\n * Counterpart to Solidity's `uint8` operator.\n *\n * Requirements:\n *\n * - input must fit into 8 bits\n *\n * _Available since v2.5._\n */\n function toUint8(uint256 value) internal pure returns (uint8) {\n require(value <= type(uint8).max, \"SafeCast: value doesn't fit in 8 bits\");\n return uint8(value);\n }\n\n /**\n * @dev Converts a signed int256 into an unsigned uint256.\n *\n * Requirements:\n *\n * - input must be greater than or equal to 0.\n *\n * _Available since v3.0._\n */\n function toUint256(int256 value) internal pure returns (uint256) {\n require(value >= 0, \"SafeCast: value must be positive\");\n return uint256(value);\n }\n\n /**\n * @dev Returns the downcasted int248 from int256, reverting on\n * overflow (when the input is less than smallest int248 or\n * greater than largest int248).\n *\n * Counterpart to Solidity's `int248` operator.\n *\n * Requirements:\n *\n * - input must fit into 248 bits\n *\n * _Available since v4.7._\n */\n function toInt248(int256 value) internal pure returns (int248 downcasted) {\n downcasted = int248(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 248 bits\");\n }\n\n /**\n * @dev Returns the downcasted int240 from int256, reverting on\n * overflow (when the input is less than smallest int240 or\n * greater than largest int240).\n *\n * Counterpart to Solidity's `int240` operator.\n *\n * Requirements:\n *\n * - input must fit into 240 bits\n *\n * _Available since v4.7._\n */\n function toInt240(int256 value) internal pure returns (int240 downcasted) {\n downcasted = int240(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 240 bits\");\n }\n\n /**\n * @dev Returns the downcasted int232 from int256, reverting on\n * overflow (when the input is less than smallest int232 or\n * greater than largest int232).\n *\n * Counterpart to Solidity's `int232` operator.\n *\n * Requirements:\n *\n * - input must fit into 232 bits\n *\n * _Available since v4.7._\n */\n function toInt232(int256 value) internal pure returns (int232 downcasted) {\n downcasted = int232(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 232 bits\");\n }\n\n /**\n * @dev Returns the downcasted int224 from int256, reverting on\n * overflow (when the input is less than smallest int224 or\n * greater than largest int224).\n *\n * Counterpart to Solidity's `int224` operator.\n *\n * Requirements:\n *\n * - input must fit into 224 bits\n *\n * _Available since v4.7._\n */\n function toInt224(int256 value) internal pure returns (int224 downcasted) {\n downcasted = int224(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 224 bits\");\n }\n\n /**\n * @dev Returns the downcasted int216 from int256, reverting on\n * overflow (when the input is less than smallest int216 or\n * greater than largest int216).\n *\n * Counterpart to Solidity's `int216` operator.\n *\n * Requirements:\n *\n * - input must fit into 216 bits\n *\n * _Available since v4.7._\n */\n function toInt216(int256 value) internal pure returns (int216 downcasted) {\n downcasted = int216(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 216 bits\");\n }\n\n /**\n * @dev Returns the downcasted int208 from int256, reverting on\n * overflow (when the input is less than smallest int208 or\n * greater than largest int208).\n *\n * Counterpart to Solidity's `int208` operator.\n *\n * Requirements:\n *\n * - input must fit into 208 bits\n *\n * _Available since v4.7._\n */\n function toInt208(int256 value) internal pure returns (int208 downcasted) {\n downcasted = int208(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 208 bits\");\n }\n\n /**\n * @dev Returns the downcasted int200 from int256, reverting on\n * overflow (when the input is less than smallest int200 or\n * greater than largest int200).\n *\n * Counterpart to Solidity's `int200` operator.\n *\n * Requirements:\n *\n * - input must fit into 200 bits\n *\n * _Available since v4.7._\n */\n function toInt200(int256 value) internal pure returns (int200 downcasted) {\n downcasted = int200(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 200 bits\");\n }\n\n /**\n * @dev Returns the downcasted int192 from int256, reverting on\n * overflow (when the input is less than smallest int192 or\n * greater than largest int192).\n *\n * Counterpart to Solidity's `int192` operator.\n *\n * Requirements:\n *\n * - input must fit into 192 bits\n *\n * _Available since v4.7._\n */\n function toInt192(int256 value) internal pure returns (int192 downcasted) {\n downcasted = int192(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 192 bits\");\n }\n\n /**\n * @dev Returns the downcasted int184 from int256, reverting on\n * overflow (when the input is less than smallest int184 or\n * greater than largest int184).\n *\n * Counterpart to Solidity's `int184` operator.\n *\n * Requirements:\n *\n * - input must fit into 184 bits\n *\n * _Available since v4.7._\n */\n function toInt184(int256 value) internal pure returns (int184 downcasted) {\n downcasted = int184(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 184 bits\");\n }\n\n /**\n * @dev Returns the downcasted int176 from int256, reverting on\n * overflow (when the input is less than smallest int176 or\n * greater than largest int176).\n *\n * Counterpart to Solidity's `int176` operator.\n *\n * Requirements:\n *\n * - input must fit into 176 bits\n *\n * _Available since v4.7._\n */\n function toInt176(int256 value) internal pure returns (int176 downcasted) {\n downcasted = int176(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 176 bits\");\n }\n\n /**\n * @dev Returns the downcasted int168 from int256, reverting on\n * overflow (when the input is less than smallest int168 or\n * greater than largest int168).\n *\n * Counterpart to Solidity's `int168` operator.\n *\n * Requirements:\n *\n * - input must fit into 168 bits\n *\n * _Available since v4.7._\n */\n function toInt168(int256 value) internal pure returns (int168 downcasted) {\n downcasted = int168(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 168 bits\");\n }\n\n /**\n * @dev Returns the downcasted int160 from int256, reverting on\n * overflow (when the input is less than smallest int160 or\n * greater than largest int160).\n *\n * Counterpart to Solidity's `int160` operator.\n *\n * Requirements:\n *\n * - input must fit into 160 bits\n *\n * _Available since v4.7._\n */\n function toInt160(int256 value) internal pure returns (int160 downcasted) {\n downcasted = int160(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 160 bits\");\n }\n\n /**\n * @dev Returns the downcasted int152 from int256, reverting on\n * overflow (when the input is less than smallest int152 or\n * greater than largest int152).\n *\n * Counterpart to Solidity's `int152` operator.\n *\n * Requirements:\n *\n * - input must fit into 152 bits\n *\n * _Available since v4.7._\n */\n function toInt152(int256 value) internal pure returns (int152 downcasted) {\n downcasted = int152(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 152 bits\");\n }\n\n /**\n * @dev Returns the downcasted int144 from int256, reverting on\n * overflow (when the input is less than smallest int144 or\n * greater than largest int144).\n *\n * Counterpart to Solidity's `int144` operator.\n *\n * Requirements:\n *\n * - input must fit into 144 bits\n *\n * _Available since v4.7._\n */\n function toInt144(int256 value) internal pure returns (int144 downcasted) {\n downcasted = int144(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 144 bits\");\n }\n\n /**\n * @dev Returns the downcasted int136 from int256, reverting on\n * overflow (when the input is less than smallest int136 or\n * greater than largest int136).\n *\n * Counterpart to Solidity's `int136` operator.\n *\n * Requirements:\n *\n * - input must fit into 136 bits\n *\n * _Available since v4.7._\n */\n function toInt136(int256 value) internal pure returns (int136 downcasted) {\n downcasted = int136(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 136 bits\");\n }\n\n /**\n * @dev Returns the downcasted int128 from int256, reverting on\n * overflow (when the input is less than smallest int128 or\n * greater than largest int128).\n *\n * Counterpart to Solidity's `int128` operator.\n *\n * Requirements:\n *\n * - input must fit into 128 bits\n *\n * _Available since v3.1._\n */\n function toInt128(int256 value) internal pure returns (int128 downcasted) {\n downcasted = int128(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 128 bits\");\n }\n\n /**\n * @dev Returns the downcasted int120 from int256, reverting on\n * overflow (when the input is less than smallest int120 or\n * greater than largest int120).\n *\n * Counterpart to Solidity's `int120` operator.\n *\n * Requirements:\n *\n * - input must fit into 120 bits\n *\n * _Available since v4.7._\n */\n function toInt120(int256 value) internal pure returns (int120 downcasted) {\n downcasted = int120(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 120 bits\");\n }\n\n /**\n * @dev Returns the downcasted int112 from int256, reverting on\n * overflow (when the input is less than smallest int112 or\n * greater than largest int112).\n *\n * Counterpart to Solidity's `int112` operator.\n *\n * Requirements:\n *\n * - input must fit into 112 bits\n *\n * _Available since v4.7._\n */\n function toInt112(int256 value) internal pure returns (int112 downcasted) {\n downcasted = int112(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 112 bits\");\n }\n\n /**\n * @dev Returns the downcasted int104 from int256, reverting on\n * overflow (when the input is less than smallest int104 or\n * greater than largest int104).\n *\n * Counterpart to Solidity's `int104` operator.\n *\n * Requirements:\n *\n * - input must fit into 104 bits\n *\n * _Available since v4.7._\n */\n function toInt104(int256 value) internal pure returns (int104 downcasted) {\n downcasted = int104(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 104 bits\");\n }\n\n /**\n * @dev Returns the downcasted int96 from int256, reverting on\n * overflow (when the input is less than smallest int96 or\n * greater than largest int96).\n *\n * Counterpart to Solidity's `int96` operator.\n *\n * Requirements:\n *\n * - input must fit into 96 bits\n *\n * _Available since v4.7._\n */\n function toInt96(int256 value) internal pure returns (int96 downcasted) {\n downcasted = int96(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 96 bits\");\n }\n\n /**\n * @dev Returns the downcasted int88 from int256, reverting on\n * overflow (when the input is less than smallest int88 or\n * greater than largest int88).\n *\n * Counterpart to Solidity's `int88` operator.\n *\n * Requirements:\n *\n * - input must fit into 88 bits\n *\n * _Available since v4.7._\n */\n function toInt88(int256 value) internal pure returns (int88 downcasted) {\n downcasted = int88(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 88 bits\");\n }\n\n /**\n * @dev Returns the downcasted int80 from int256, reverting on\n * overflow (when the input is less than smallest int80 or\n * greater than largest int80).\n *\n * Counterpart to Solidity's `int80` operator.\n *\n * Requirements:\n *\n * - input must fit into 80 bits\n *\n * _Available since v4.7._\n */\n function toInt80(int256 value) internal pure returns (int80 downcasted) {\n downcasted = int80(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 80 bits\");\n }\n\n /**\n * @dev Returns the downcasted int72 from int256, reverting on\n * overflow (when the input is less than smallest int72 or\n * greater than largest int72).\n *\n * Counterpart to Solidity's `int72` operator.\n *\n * Requirements:\n *\n * - input must fit into 72 bits\n *\n * _Available since v4.7._\n */\n function toInt72(int256 value) internal pure returns (int72 downcasted) {\n downcasted = int72(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 72 bits\");\n }\n\n /**\n * @dev Returns the downcasted int64 from int256, reverting on\n * overflow (when the input is less than smallest int64 or\n * greater than largest int64).\n *\n * Counterpart to Solidity's `int64` operator.\n *\n * Requirements:\n *\n * - input must fit into 64 bits\n *\n * _Available since v3.1._\n */\n function toInt64(int256 value) internal pure returns (int64 downcasted) {\n downcasted = int64(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 64 bits\");\n }\n\n /**\n * @dev Returns the downcasted int56 from int256, reverting on\n * overflow (when the input is less than smallest int56 or\n * greater than largest int56).\n *\n * Counterpart to Solidity's `int56` operator.\n *\n * Requirements:\n *\n * - input must fit into 56 bits\n *\n * _Available since v4.7._\n */\n function toInt56(int256 value) internal pure returns (int56 downcasted) {\n downcasted = int56(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 56 bits\");\n }\n\n /**\n * @dev Returns the downcasted int48 from int256, reverting on\n * overflow (when the input is less than smallest int48 or\n * greater than largest int48).\n *\n * Counterpart to Solidity's `int48` operator.\n *\n * Requirements:\n *\n * - input must fit into 48 bits\n *\n * _Available since v4.7._\n */\n function toInt48(int256 value) internal pure returns (int48 downcasted) {\n downcasted = int48(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 48 bits\");\n }\n\n /**\n * @dev Returns the downcasted int40 from int256, reverting on\n * overflow (when the input is less than smallest int40 or\n * greater than largest int40).\n *\n * Counterpart to Solidity's `int40` operator.\n *\n * Requirements:\n *\n * - input must fit into 40 bits\n *\n * _Available since v4.7._\n */\n function toInt40(int256 value) internal pure returns (int40 downcasted) {\n downcasted = int40(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 40 bits\");\n }\n\n /**\n * @dev Returns the downcasted int32 from int256, reverting on\n * overflow (when the input is less than smallest int32 or\n * greater than largest int32).\n *\n * Counterpart to Solidity's `int32` operator.\n *\n * Requirements:\n *\n * - input must fit into 32 bits\n *\n * _Available since v3.1._\n */\n function toInt32(int256 value) internal pure returns (int32 downcasted) {\n downcasted = int32(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 32 bits\");\n }\n\n /**\n * @dev Returns the downcasted int24 from int256, reverting on\n * overflow (when the input is less than smallest int24 or\n * greater than largest int24).\n *\n * Counterpart to Solidity's `int24` operator.\n *\n * Requirements:\n *\n * - input must fit into 24 bits\n *\n * _Available since v4.7._\n */\n function toInt24(int256 value) internal pure returns (int24 downcasted) {\n downcasted = int24(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 24 bits\");\n }\n\n /**\n * @dev Returns the downcasted int16 from int256, reverting on\n * overflow (when the input is less than smallest int16 or\n * greater than largest int16).\n *\n * Counterpart to Solidity's `int16` operator.\n *\n * Requirements:\n *\n * - input must fit into 16 bits\n *\n * _Available since v3.1._\n */\n function toInt16(int256 value) internal pure returns (int16 downcasted) {\n downcasted = int16(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 16 bits\");\n }\n\n /**\n * @dev Returns the downcasted int8 from int256, reverting on\n * overflow (when the input is less than smallest int8 or\n * greater than largest int8).\n *\n * Counterpart to Solidity's `int8` operator.\n *\n * Requirements:\n *\n * - input must fit into 8 bits\n *\n * _Available since v3.1._\n */\n function toInt8(int256 value) internal pure returns (int8 downcasted) {\n downcasted = int8(value);\n require(downcasted == value, \"SafeCast: value doesn't fit in 8 bits\");\n }\n\n /**\n * @dev Converts an unsigned uint256 into a signed int256.\n *\n * Requirements:\n *\n * - input must be less than or equal to maxInt256.\n *\n * _Available since v3.0._\n */\n function toInt256(uint256 value) internal pure returns (int256) {\n // Note: Unsafe cast below is okay because `type(int256).max` is guaranteed to be positive\n require(value <= uint256(type(int256).max), \"SafeCast: value doesn't fit in an int256\");\n return int256(value);\n }\n}\n"
},
"@openzeppelin/contracts/utils/math/SignedMath.sol": {
"content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.8.0) (utils/math/SignedMath.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Standard signed math utilities missing in the Solidity language.\n */\nlibrary SignedMath {\n /**\n * @dev Returns the largest of two signed numbers.\n */\n function max(int256 a, int256 b) internal pure returns (int256) {\n return a > b ? a : b;\n }\n\n /**\n * @dev Returns the smallest of two signed numbers.\n */\n function min(int256 a, int256 b) internal pure returns (int256) {\n return a < b ? a : b;\n }\n\n /**\n * @dev Returns the average of two signed numbers without overflow.\n * The result is rounded towards zero.\n */\n function average(int256 a, int256 b) internal pure returns (int256) {\n // Formula from the book \"Hacker's Delight\"\n int256 x = (a & b) + ((a ^ b) >> 1);\n return x + (int256(uint256(x) >> 255) & (a ^ b));\n }\n\n /**\n * @dev Returns the absolute unsigned value of a signed value.\n */\n function abs(int256 n) internal pure returns (uint256) {\n unchecked {\n // must be unchecked in order to support `n = type(int256).min`\n return uint256(n >= 0 ? n : -n);\n }\n }\n}\n"
},
"@openzeppelin/contracts/utils/StorageSlot.sol": {
"content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/StorageSlot.sol)\n// This file was procedurally generated from scripts/generate/templates/StorageSlot.js.\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Library for reading and writing primitive types to specific storage slots.\n *\n * Storage slots are often used to avoid storage conflict when dealing with upgradeable contracts.\n * This library helps with reading and writing to such slots without the need for inline assembly.\n *\n * The functions in this library return Slot structs that contain a `value` member that can be used to read or write.\n *\n * Example usage to set ERC1967 implementation slot:\n * ```solidity\n * contract ERC1967 {\n * bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\n *\n * function _getImplementation() internal view returns (address) {\n * return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value;\n * }\n *\n * function _setImplementation(address newImplementation) internal {\n * require(Address.isContract(newImplementation), \"ERC1967: new implementation is not a contract\");\n * StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation;\n * }\n * }\n * ```\n *\n * _Available since v4.1 for `address`, `bool`, `bytes32`, `uint256`._\n * _Available since v4.9 for `string`, `bytes`._\n */\nlibrary StorageSlot {\n struct AddressSlot {\n address value;\n }\n\n struct BooleanSlot {\n bool value;\n }\n\n struct Bytes32Slot {\n bytes32 value;\n }\n\n struct Uint256Slot {\n uint256 value;\n }\n\n struct StringSlot {\n string value;\n }\n\n struct BytesSlot {\n bytes value;\n }\n\n /**\n * @dev Returns an `AddressSlot` with member `value` located at `slot`.\n */\n function getAddressSlot(bytes32 slot) internal pure returns (AddressSlot storage r) {\n /// @solidity memory-safe-assembly\n assembly {\n r.slot := slot\n }\n }\n\n /**\n * @dev Returns an `BooleanSlot` with member `value` located at `slot`.\n */\n function getBooleanSlot(bytes32 slot) internal pure returns (BooleanSlot storage r) {\n /// @solidity memory-safe-assembly\n assembly {\n r.slot := slot\n }\n }\n\n /**\n * @dev Returns an `Bytes32Slot` with member `value` located at `slot`.\n */\n function getBytes32Slot(bytes32 slot) internal pure returns (Bytes32Slot storage r) {\n /// @solidity memory-safe-assembly\n assembly {\n r.slot := slot\n }\n }\n\n /**\n * @dev Returns an `Uint256Slot` with member `value` located at `slot`.\n */\n function getUint256Slot(bytes32 slot) internal pure returns (Uint256Slot storage r) {\n /// @solidity memory-safe-assembly\n assembly {\n r.slot := slot\n }\n }\n\n /**\n * @dev Returns an `StringSlot` with member `value` located at `slot`.\n */\n function getStringSlot(bytes32 slot) internal pure returns (StringSlot storage r) {\n /// @solidity memory-safe-assembly\n assembly {\n r.slot := slot\n }\n }\n\n /**\n * @dev Returns an `StringSlot` representation of the string storage pointer `store`.\n */\n function getStringSlot(string storage store) internal pure returns (StringSlot storage r) {\n /// @solidity memory-safe-assembly\n assembly {\n r.slot := store.slot\n }\n }\n\n /**\n * @dev Returns an `BytesSlot` with member `value` located at `slot`.\n */\n function getBytesSlot(bytes32 slot) internal pure returns (BytesSlot storage r) {\n /// @solidity memory-safe-assembly\n assembly {\n r.slot := slot\n }\n }\n\n /**\n * @dev Returns an `BytesSlot` representation of the bytes storage pointer `store`.\n */\n function getBytesSlot(bytes storage store) internal pure returns (BytesSlot storage r) {\n /// @solidity memory-safe-assembly\n assembly {\n r.slot := store.slot\n }\n }\n}\n"
},
"@openzeppelin/contracts/utils/Strings.sol": {
"content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/Strings.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./math/Math.sol\";\nimport \"./math/SignedMath.sol\";\n\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _SYMBOLS = \"0123456789abcdef\";\n uint8 private constant _ADDRESS_LENGTH = 20;\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n unchecked {\n uint256 length = Math.log10(value) + 1;\n string memory buffer = new string(length);\n uint256 ptr;\n /// @solidity memory-safe-assembly\n assembly {\n ptr := add(buffer, add(32, length))\n }\n while (true) {\n ptr--;\n /// @solidity memory-safe-assembly\n assembly {\n mstore8(ptr, byte(mod(value, 10), _SYMBOLS))\n }\n value /= 10;\n if (value == 0) break;\n }\n return buffer;\n }\n }\n\n /**\n * @dev Converts a `int256` to its ASCII `string` decimal representation.\n */\n function toString(int256 value) internal pure returns (string memory) {\n return string(abi.encodePacked(value < 0 ? \"-\" : \"\", toString(SignedMath.abs(value))));\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n unchecked {\n return toHexString(value, Math.log256(value) + 1);\n }\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i > 1; --i) {\n buffer[i] = _SYMBOLS[value & 0xf];\n value >>= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n\n /**\n * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation.\n */\n function toHexString(address addr) internal pure returns (string memory) {\n return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);\n }\n\n /**\n * @dev Returns true if the two strings are equal.\n */\n function equal(string memory a, string memory b) internal pure returns (bool) {\n return keccak256(bytes(a)) == keccak256(bytes(b));\n }\n}\n"
},
"@venusprotocol/isolated-pools/contracts/InterestRateModel.sol": {
"content": "// SPDX-License-Identifier: BSD-3-Clause\npragma solidity 0.8.25;\n\n/**\n * @title Compound's InterestRateModel Interface\n * @author Compound\n */\nabstract contract InterestRateModel {\n /**\n * @notice Calculates the current borrow interest rate per slot (block or second)\n * @param cash The total amount of cash the market has\n * @param borrows The total amount of borrows the market has outstanding\n * @param reserves The total amount of reserves the market has\n * @param badDebt The amount of badDebt in the market\n * @return The borrow rate percentage per slot (block or second) as a mantissa (scaled by EXP_SCALE)\n */\n function getBorrowRate(\n uint256 cash,\n uint256 borrows,\n uint256 reserves,\n uint256 badDebt\n ) external view virtual returns (uint256);\n\n /**\n * @notice Calculates the current supply interest rate per slot (block or second)\n * @param cash The total amount of cash the market has\n * @param borrows The total amount of borrows the market has outstanding\n * @param reserves The total amount of reserves the market has\n * @param reserveFactorMantissa The current reserve factor the market has\n * @param badDebt The amount of badDebt in the market\n * @return The supply rate percentage per slot (block or second) as a mantissa (scaled by EXP_SCALE)\n */\n function getSupplyRate(\n uint256 cash,\n uint256 borrows,\n uint256 reserves,\n uint256 reserveFactorMantissa,\n uint256 badDebt\n ) external view virtual returns (uint256);\n\n /**\n * @notice Indicator that this is an InterestRateModel contract (for inspection)\n * @return Always true\n */\n function isInterestRateModel() external pure virtual returns (bool) {\n return true;\n }\n}\n"
},
"@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"
},
"@venusprotocol/venus-protocol/contracts/InterestRateModels/InterestRateModelV8.sol": {
"content": "pragma solidity 0.8.25;\n\n/**\n * @title Venus's InterestRateModelV8 Interface\n * @author Venus\n */\nabstract contract InterestRateModelV8 {\n /// @notice Indicator that this is an InterestRateModel contract (for inspection)\n bool public constant isInterestRateModel = true;\n\n /**\n * @notice Calculates the current borrow interest rate per block\n * @param cash The total amount of cash the market has\n * @param borrows The total amount of borrows the market has outstanding\n * @param reserves The total amnount of reserves the market has\n * @return The borrow rate per block (as a percentage, and scaled by 1e18)\n */\n function getBorrowRate(uint256 cash, uint256 borrows, uint256 reserves) external view virtual returns (uint256);\n\n /**\n * @notice Calculates the current supply interest rate per block\n * @param cash The total amount of cash the market has\n * @param borrows The total amount of borrows the market has outstanding\n * @param reserves The total amnount of reserves the market has\n * @param reserveFactorMantissa The current reserve factor the market has\n * @return The supply rate per block (as a percentage, and scaled by 1e18)\n */\n function getSupplyRate(\n uint256 cash,\n uint256 borrows,\n uint256 reserves,\n uint256 reserveFactorMantissa\n ) external view virtual returns (uint256);\n}\n"
},
"contracts/Cross-chain/BaseOmnichainControllerDest.sol": {
"content": "// SPDX-License-Identifier: BSD-3-Clause\n\npragma solidity 0.8.25;\n\nimport { NonblockingLzApp } from \"@layerzerolabs/solidity-examples/contracts/lzApp/NonblockingLzApp.sol\";\nimport { Pausable } from \"@openzeppelin/contracts/security/Pausable.sol\";\nimport { ensureNonzeroAddress } from \"@venusprotocol/solidity-utilities/contracts/validators.sol\";\n\n/**\n * @title BaseOmnichainControllerDest\n * @author Venus\n * @dev This contract is the base for the Omnichain controller destination contract\n * It provides functionality related to daily command limits and pausability\n * @custom:security-contact https://github.com/VenusProtocol/governance-contracts#discussion\n */\n\nabstract contract BaseOmnichainControllerDest is NonblockingLzApp, Pausable {\n /**\n * @notice Maximum daily limit for receiving commands from Binance chain\n */\n uint256 public maxDailyReceiveLimit;\n\n /**\n * @notice Total received commands within the last 24-hour window from Binance chain\n */\n uint256 public last24HourCommandsReceived;\n\n /**\n * @notice Timestamp when the last 24-hour window started from Binance chain\n */\n uint256 public last24HourReceiveWindowStart;\n\n /**\n * @notice Emitted when the maximum daily limit for receiving command from Binance chain is modified\n */\n event SetMaxDailyReceiveLimit(uint256 oldMaxLimit, uint256 newMaxLimit);\n\n constructor(address endpoint_) NonblockingLzApp(endpoint_) {\n ensureNonzeroAddress(endpoint_);\n }\n\n /**\n * @notice Sets the maximum daily limit for receiving commands\n * @param limit_ Number of commands\n * @custom:access Only Owner\n * @custom:event Emits SetMaxDailyReceiveLimit with old and new limit\n */\n function setMaxDailyReceiveLimit(uint256 limit_) external onlyOwner {\n emit SetMaxDailyReceiveLimit(maxDailyReceiveLimit, limit_);\n maxDailyReceiveLimit = limit_;\n }\n\n /**\n * @notice Triggers the paused state of the controller\n * @custom:access Only owner\n */\n function pause() external onlyOwner {\n _pause();\n }\n\n /**\n * @notice Triggers the resume state of the controller\n * @custom:access Only owner\n */\n function unpause() external onlyOwner {\n _unpause();\n }\n\n /**\n * @notice Empty implementation of renounce ownership to avoid any mishappening\n */\n function renounceOwnership() public override {}\n\n /**\n * @notice Check eligibility to receive commands\n * @param noOfCommands_ Number of commands to be received\n */\n function _isEligibleToReceive(uint256 noOfCommands_) internal {\n uint256 currentBlockTimestamp = block.timestamp;\n\n // Load values for the 24-hour window checks for receiving\n uint256 receivedInWindow = last24HourCommandsReceived;\n\n // Check if the time window has changed (more than 24 hours have passed)\n if (currentBlockTimestamp - last24HourReceiveWindowStart > 1 days) {\n receivedInWindow = noOfCommands_;\n last24HourReceiveWindowStart = currentBlockTimestamp;\n } else {\n receivedInWindow += noOfCommands_;\n }\n\n // Revert if the received amount exceeds the daily limit\n require(receivedInWindow <= maxDailyReceiveLimit, \"Daily Transaction Limit Exceeded\");\n\n // Update the received amount for the 24-hour window\n last24HourCommandsReceived = receivedInWindow;\n }\n}\n"
},
"contracts/Cross-chain/BaseOmnichainControllerSrc.sol": {
"content": "// SPDX-License-Identifier: BSD-3-Clause\n\npragma solidity 0.8.25;\n\nimport { Pausable } from \"@openzeppelin/contracts/security/Pausable.sol\";\nimport { Ownable } from \"@openzeppelin/contracts/access/Ownable.sol\";\nimport { ensureNonzeroAddress } from \"@venusprotocol/solidity-utilities/contracts/validators.sol\";\nimport { IAccessControlManagerV8 } from \"./../Governance/IAccessControlManagerV8.sol\";\n\n/**\n * @title BaseOmnichainControllerSrc\n * @dev This contract is the base for the Omnichain controller source contracts.\n * It provides functionality related to daily command limits and pausability.\n * @custom:security-contact https://github.com/VenusProtocol/governance-contracts#discussion\n */\n\ncontract BaseOmnichainControllerSrc is Ownable, Pausable {\n /**\n * @notice ACM (Access Control Manager) contract address\n */\n address public accessControlManager;\n\n /**\n * @notice Maximum daily limit for commands from the local chain\n */\n mapping(uint16 => uint256) public chainIdToMaxDailyLimit;\n\n /**\n * @notice Total commands transferred within the last 24-hour window from the local chain\n */\n mapping(uint16 => uint256) public chainIdToLast24HourCommandsSent;\n\n /**\n * @notice Timestamp when the last 24-hour window started from the local chain\n */\n mapping(uint16 => uint256) public chainIdToLast24HourWindowStart;\n /**\n * @notice Timestamp when the last proposal sent from the local chain to dest chain\n */\n mapping(uint16 => uint256) public chainIdToLastProposalSentTimestamp;\n\n /**\n * @notice Emitted when the maximum daily limit of commands from the local chain is modified\n */\n event SetMaxDailyLimit(uint16 indexed chainId, uint256 oldMaxLimit, uint256 newMaxLimit);\n\n /**\n * @notice Emitted when the address of ACM is updated\n */\n event NewAccessControlManager(address indexed oldAccessControlManager, address indexed newAccessControlManager);\n\n constructor(address accessControlManager_) {\n ensureNonzeroAddress(accessControlManager_);\n accessControlManager = accessControlManager_;\n }\n\n /**\n * @notice Sets the limit of daily (24 Hour) command amount\n * @param chainId_ Destination chain id\n * @param limit_ Number of commands\n * @custom:access Controlled by AccessControlManager\n * @custom:event Emits SetMaxDailyLimit with old and new limit and its corresponding chain id\n */\n function setMaxDailyLimit(uint16 chainId_, uint256 limit_) external {\n _ensureAllowed(\"setMaxDailyLimit(uint16,uint256)\");\n emit SetMaxDailyLimit(chainId_, chainIdToMaxDailyLimit[chainId_], limit_);\n chainIdToMaxDailyLimit[chainId_] = limit_;\n }\n\n /**\n * @notice Triggers the paused state of the controller\n * @custom:access Controlled by AccessControlManager\n */\n function pause() external {\n _ensureAllowed(\"pause()\");\n _pause();\n }\n\n /**\n * @notice Triggers the resume state of the controller\n * @custom:access Controlled by AccessControlManager\n */\n function unpause() external {\n _ensureAllowed(\"unpause()\");\n _unpause();\n }\n\n /**\n * @notice Sets the address of Access Control Manager (ACM)\n * @param accessControlManager_ The new address of the Access Control Manager\n * @custom:access Only owner\n * @custom:event Emits NewAccessControlManager with old and new access control manager addresses\n */\n function setAccessControlManager(address accessControlManager_) external onlyOwner {\n ensureNonzeroAddress(accessControlManager_);\n emit NewAccessControlManager(accessControlManager, accessControlManager_);\n accessControlManager = accessControlManager_;\n }\n\n /**\n * @notice Empty implementation of renounce ownership to avoid any mishap\n */\n function renounceOwnership() public override {}\n\n /**\n * @notice Check eligibility to send commands\n * @param dstChainId_ Destination chain id\n * @param noOfCommands_ Number of commands to send\n */\n function _isEligibleToSend(uint16 dstChainId_, uint256 noOfCommands_) internal {\n // Load values for the 24-hour window checks\n uint256 currentBlockTimestamp = block.timestamp;\n uint256 lastDayWindowStart = chainIdToLast24HourWindowStart[dstChainId_];\n uint256 commandsSentInWindow = chainIdToLast24HourCommandsSent[dstChainId_];\n uint256 maxDailyLimit = chainIdToMaxDailyLimit[dstChainId_];\n uint256 lastProposalSentTimestamp = chainIdToLastProposalSentTimestamp[dstChainId_];\n\n // Check if the time window has changed (more than 24 hours have passed)\n if (currentBlockTimestamp - lastDayWindowStart > 1 days) {\n commandsSentInWindow = noOfCommands_;\n chainIdToLast24HourWindowStart[dstChainId_] = currentBlockTimestamp;\n } else {\n commandsSentInWindow += noOfCommands_;\n }\n\n // Revert if the amount exceeds the daily limit\n require(commandsSentInWindow <= maxDailyLimit, \"Daily Transaction Limit Exceeded\");\n // Revert if the last proposal is already sent in current block i.e multiple proposals cannot be sent within the same block.timestamp\n require(lastProposalSentTimestamp != currentBlockTimestamp, \"Multiple bridging in a proposal\");\n\n // Update the amount for the 24-hour window\n chainIdToLast24HourCommandsSent[dstChainId_] = commandsSentInWindow;\n // Update the last sent proposal timestamp\n chainIdToLastProposalSentTimestamp[dstChainId_] = currentBlockTimestamp;\n }\n\n /**\n * @notice Ensure that the caller has permission to execute a specific function\n * @param functionSig_ Function signature to be checked for permission\n */\n function _ensureAllowed(string memory functionSig_) internal view {\n require(\n IAccessControlManagerV8(accessControlManager).isAllowedToCall(msg.sender, functionSig_),\n \"access denied\"\n );\n }\n}\n"
},
"contracts/Cross-chain/interfaces/IOmnichainGovernanceExecutor.sol": {
"content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.25;\n\ninterface IOmnichainGovernanceExecutor {\n /**\n * @notice Transfers ownership of the contract to the specified address\n * @param addr The address to which ownership will be transferred\n */\n function transferOwnership(address addr) external;\n\n /**\n * @notice Sets the source message sender address\n * @param srcChainId_ The LayerZero id of a source chain\n * @param srcAddress_ The address of the contract on the source chain\n */\n function setTrustedRemoteAddress(uint16 srcChainId_, bytes calldata srcAddress_) external;\n}\n"
},
"contracts/Cross-chain/interfaces/ITimelock.sol": {
"content": "// SPDX-License-Identifier: BSD-3-Clause\npragma solidity ^0.8.25;\n\n/**\n * @title ITimelock\n * @author Venus\n * @dev Interface for Timelock contract\n * @custom:security-contact https://github.com/VenusProtocol/governance-contracts#discussion\n */\ninterface ITimelock {\n /**\n * @notice Delay period for the transaction queue\n */\n function delay() external view returns (uint256);\n\n /**\n * @notice Required period to execute a proposal transaction\n */\n function GRACE_PERIOD() external view returns (uint256);\n\n /**\n * @notice Method for accepting a proposed admin\n */\n function acceptAdmin() external;\n\n /**\n * @notice Method to propose a new admin authorized to call timelock functions. This should be the Governor Contract.\n */\n function setPendingAdmin(address pendingAdmin) external;\n\n /**\n * @notice Show mapping of queued transactions\n * @param hash Transaction hash\n */\n function queuedTransactions(bytes32 hash) external view returns (bool);\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 */\n function queueTransaction(\n address target,\n uint256 value,\n string calldata signature,\n bytes calldata data,\n uint256 eta\n ) external returns (bytes32);\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 */\n function cancelTransaction(\n address target,\n uint256 value,\n string calldata signature,\n bytes calldata data,\n uint256 eta\n ) external;\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 */\n function executeTransaction(\n address target,\n uint256 value,\n string calldata signature,\n bytes calldata data,\n uint256 eta\n ) external payable returns (bytes memory);\n}\n"
},
"contracts/Cross-chain/OmnichainExecutorOwner.sol": {
"content": "// SPDX-License-Identifier: BSD-3-Clause\npragma solidity 0.8.25;\n\nimport { AccessControlledV8 } from \"../Governance/AccessControlledV8.sol\";\nimport { IOmnichainGovernanceExecutor } from \"./interfaces/IOmnichainGovernanceExecutor.sol\";\nimport { ensureNonzeroAddress } from \"@venusprotocol/solidity-utilities/contracts/validators.sol\";\n\n/**\n * @title OmnichainExecutorOwner\n * @author Venus\n * @notice OmnichainProposalSender contract acts as a governance and access control mechanism,\n * allowing owner to upsert signature of OmnichainGovernanceExecutor contract,\n * also contains function to transfer the ownership of contract as well.\n * @custom:security-contact https://github.com/VenusProtocol/governance-contracts#discussion\n */\n\ncontract OmnichainExecutorOwner is AccessControlledV8 {\n /**\n * @custom:oz-upgrades-unsafe-allow state-variable-immutable\n */\n IOmnichainGovernanceExecutor public immutable OMNICHAIN_GOVERNANCE_EXECUTOR;\n\n /**\n * @notice Stores function signature corresponding to their 4 bytes hash value\n */\n mapping(bytes4 => string) public functionRegistry;\n\n /**\n * @notice Event emitted when function registry updated\n */\n event FunctionRegistryChanged(string indexed signature, bool active);\n\n /// @custom:oz-upgrades-unsafe-allow constructor\n constructor(address omnichainGovernanceExecutor_) {\n require(omnichainGovernanceExecutor_ != address(0), \"Address must not be zero\");\n OMNICHAIN_GOVERNANCE_EXECUTOR = IOmnichainGovernanceExecutor(omnichainGovernanceExecutor_);\n _disableInitializers();\n }\n\n /**\n * @notice Initialize the contract\n * @param accessControlManager_ Address of access control manager\n */\n function initialize(address accessControlManager_) external initializer {\n require(accessControlManager_ != address(0), \"Address must not be zero\");\n __AccessControlled_init(accessControlManager_);\n }\n\n /**\n * @notice Sets the source message sender address\n * @param srcChainId_ The LayerZero id of a source chain\n * @param srcAddress_ The address of the contract on the source chain\n * @custom:access Controlled by AccessControlManager\n * @custom:event Emits SetTrustedRemoteAddress with source chain Id and source address\n */\n function setTrustedRemoteAddress(uint16 srcChainId_, bytes calldata srcAddress_) external {\n _checkAccessAllowed(\"setTrustedRemoteAddress(uint16,bytes)\");\n require(srcChainId_ != 0, \"ChainId must not be zero\");\n ensureNonzeroAddress(address(uint160(bytes20(srcAddress_))));\n require(srcAddress_.length == 20, \"Source address must be 20 bytes long\");\n OMNICHAIN_GOVERNANCE_EXECUTOR.setTrustedRemoteAddress(srcChainId_, srcAddress_);\n }\n\n /**\n * @notice Invoked when called function does not exist in the contract\n * @param data_ Calldata containing the encoded function call\n * @return Result of function call\n * @custom:access Controlled by Access Control Manager\n */\n fallback(bytes calldata data_) external returns (bytes memory) {\n string memory fun = functionRegistry[msg.sig];\n require(bytes(fun).length != 0, \"Function not found\");\n _checkAccessAllowed(fun);\n (bool ok, bytes memory res) = address(OMNICHAIN_GOVERNANCE_EXECUTOR).call(data_);\n require(ok, \"call failed\");\n return res;\n }\n\n /**\n * @notice A registry of functions that are allowed to be executed from proposals\n * @param signatures_ Function signature to be added or removed\n * @param active_ bool value, should be true to add function\n * @custom:access Only owner\n */\n function upsertSignature(string[] calldata signatures_, bool[] calldata active_) external onlyOwner {\n uint256 signatureLength = signatures_.length;\n require(signatureLength == active_.length, \"Input arrays must have the same length\");\n for (uint256 i; i < signatureLength; ++i) {\n bytes4 sigHash = bytes4(keccak256(bytes(signatures_[i])));\n bytes memory signature = bytes(functionRegistry[sigHash]);\n if (active_[i] && signature.length == 0) {\n functionRegistry[sigHash] = signatures_[i];\n emit FunctionRegistryChanged(signatures_[i], true);\n } else if (!active_[i] && signature.length != 0) {\n delete functionRegistry[sigHash];\n emit FunctionRegistryChanged(signatures_[i], false);\n }\n }\n }\n\n /**\n * @notice This function transfer the ownership of the executor from this contract to new owner\n * @param newOwner_ New owner of the governanceExecutor\n * @custom:access Controlled by AccessControlManager\n */\n\n function transferBridgeOwnership(address newOwner_) external {\n _checkAccessAllowed(\"transferBridgeOwnership(address)\");\n require(newOwner_ != address(0), \"Address must not be zero\");\n OMNICHAIN_GOVERNANCE_EXECUTOR.transferOwnership(newOwner_);\n }\n\n /**\n * @notice Empty implementation of renounce ownership to avoid any mishappening\n */\n function renounceOwnership() public virtual override {}\n}\n"
},
"contracts/Cross-chain/OmnichainGovernanceExecutor.sol": {
"content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.25;\n\nimport { ReentrancyGuard } from \"@openzeppelin/contracts/security/ReentrancyGuard.sol\";\nimport { BytesLib } from \"@layerzerolabs/solidity-examples/contracts/libraries/BytesLib.sol\";\nimport { ExcessivelySafeCall } from \"@layerzerolabs/solidity-examples/contracts/libraries/ExcessivelySafeCall.sol\";\nimport { ensureNonzeroAddress } from \"@venusprotocol/solidity-utilities/contracts/validators.sol\";\nimport { BaseOmnichainControllerDest } from \"./BaseOmnichainControllerDest.sol\";\nimport { ITimelock } from \"./interfaces/ITimelock.sol\";\n\n/**\n * @title OmnichainGovernanceExecutor\n * @notice Executes the proposal transactions sent from the main chain\n * @dev The owner of this contract controls LayerZero configuration. When used in production the owner will be OmnichainExecutor\n * This implementation is non-blocking, meaning the failed messages will not block the future messages from the source.\n * For the blocking behavior, derive the contract from LzApp.\n * @custom:security-contact https://github.com/VenusProtocol/governance-contracts#discussion\n */\ncontract OmnichainGovernanceExecutor is ReentrancyGuard, BaseOmnichainControllerDest {\n using BytesLib for bytes;\n using ExcessivelySafeCall for address;\n\n enum ProposalType {\n NORMAL,\n FASTTRACK,\n CRITICAL\n }\n\n struct Proposal {\n /** Unique id for looking up a proposal */\n uint256 id;\n /** The timestamp that the proposal will be available for execution, set once the vote succeeds */\n uint256 eta;\n /** The ordered list of target addresses for calls to be made */\n address[] targets;\n /** The ordered list of values (i.e. msg.value) to be passed to the calls to be made */\n uint256[] values;\n /** The ordered list of function signatures to be called */\n string[] signatures;\n /** The ordered list of calldata to be passed to each call */\n bytes[] calldatas;\n /** Flag marking whether the proposal has been canceled */\n bool canceled;\n /** Flag marking whether the proposal has been executed */\n bool executed;\n /** The type of the proposal */\n uint8 proposalType;\n }\n /*\n * @notice Possible states that a proposal may be in\n */\n enum ProposalState {\n Canceled,\n Queued,\n Executed\n }\n\n /**\n * @notice A privileged role that can cancel any proposal\n */\n address public guardian;\n\n /**\n * @notice Stores BNB chain layerzero endpoint id\n */\n uint16 public srcChainId;\n\n /**\n * @notice Last proposal count received\n */\n uint256 public lastProposalReceived;\n\n /**\n * @notice The official record of all proposals ever proposed\n */\n mapping(uint256 => Proposal) public proposals;\n\n /**\n * @notice Mapping containing Timelock addresses for each proposal type\n */\n mapping(uint256 => ITimelock) public proposalTimelocks;\n\n /**\n * @notice Represents queue state of proposal\n */\n mapping(uint256 => bool) public queued;\n\n /**\n * @notice Emitted when proposal is received\n */\n event ProposalReceived(\n uint256 indexed proposalId,\n address[] targets,\n uint256[] values,\n string[] signatures,\n bytes[] calldatas,\n uint8 proposalType\n );\n\n /**\n * @notice Emitted when proposal is queued\n */\n event ProposalQueued(uint256 indexed id, uint256 eta);\n\n /**\n * Emitted when proposal executed\n */\n event ProposalExecuted(uint256 indexed id);\n\n /**\n * @notice Emitted when proposal failed\n */\n event ReceivePayloadFailed(uint16 indexed srcChainId, bytes indexed srcAddress, uint64 nonce, bytes reason);\n\n /**\n * @notice Emitted when proposal is canceled\n */\n event ProposalCanceled(uint256 indexed id);\n\n /**\n * @notice Emitted when timelock added\n */\n event TimelockAdded(uint8 routeType, address indexed oldTimelock, address indexed newTimelock);\n\n /**\n * @notice Emitted when source layerzero endpoint id is updated\n */\n event SetSrcChainId(uint16 indexed oldSrcChainId, uint16 indexed newSrcChainId);\n\n /**\n * @notice Emitted when new guardian address is set\n */\n event NewGuardian(address indexed oldGuardian, address indexed newGuardian);\n\n /**\n * @notice Emitted when pending admin of Timelock is updated\n */\n event SetTimelockPendingAdmin(address, uint8);\n\n /**\n * @notice Thrown when proposal ID is invalid\n */\n error InvalidProposalId();\n\n constructor(address endpoint_, address guardian_, uint16 srcChainId_) BaseOmnichainControllerDest(endpoint_) {\n ensureNonzeroAddress(guardian_);\n guardian = guardian_;\n srcChainId = srcChainId_;\n }\n\n /**\n * @notice Update source layerzero endpoint id\n * @param srcChainId_ The new source chain id to be set\n * @custom:event Emit SetSrcChainId with old and new source id\n * @custom:access Only owner\n */\n function setSrcChainId(uint16 srcChainId_) external onlyOwner {\n emit SetSrcChainId(srcChainId, srcChainId_);\n srcChainId = srcChainId_;\n }\n\n /**\n * @notice Sets the new executor guardian\n * @param newGuardian The address of the new guardian\n * @custom:access Must be call by guardian or owner\n * @custom:event Emit NewGuardian with old and new guardian address\n */\n function setGuardian(address newGuardian) external {\n require(\n msg.sender == guardian || msg.sender == owner(),\n \"OmnichainGovernanceExecutor::setGuardian: owner or guardian only\"\n );\n ensureNonzeroAddress(newGuardian);\n emit NewGuardian(guardian, newGuardian);\n guardian = newGuardian;\n }\n\n /**\n * @notice Add timelocks to the ProposalTimelocks mapping\n * @param timelocks_ Array of addresses of all 3 timelocks\n * @custom:access Only owner\n * @custom:event Emits TimelockAdded with old and new timelock and route type\n */\n function addTimelocks(ITimelock[] memory timelocks_) external onlyOwner {\n uint8 length = uint8(type(ProposalType).max) + 1;\n require(\n timelocks_.length == length,\n \"OmnichainGovernanceExecutor::addTimelocks:number of timelocks should match the number of governance routes\"\n );\n for (uint8 i; i < length; ++i) {\n ensureNonzeroAddress(address(timelocks_[i]));\n emit TimelockAdded(i, address(proposalTimelocks[i]), address(timelocks_[i]));\n proposalTimelocks[i] = timelocks_[i];\n }\n }\n\n /**\n * @notice Executes a queued proposal if eta has passed\n * @param proposalId_ Id of proposal that is to be executed\n * @custom:event Emits ProposalExecuted with proposal id of executed proposal\n */\n function execute(uint256 proposalId_) external nonReentrant {\n require(\n state(proposalId_) == ProposalState.Queued,\n \"OmnichainGovernanceExecutor::execute: proposal can only be executed if it is queued\"\n );\n\n Proposal storage proposal = proposals[proposalId_];\n proposal.executed = true;\n ITimelock timelock = proposalTimelocks[proposal.proposalType];\n uint256 eta = proposal.eta;\n uint256 length = proposal.targets.length;\n\n emit ProposalExecuted(proposalId_);\n\n for (uint256 i; i < length; ++i) {\n timelock.executeTransaction(\n proposal.targets[i],\n proposal.values[i],\n proposal.signatures[i],\n proposal.calldatas[i],\n eta\n );\n }\n delete queued[proposalId_];\n }\n\n /**\n * @notice Cancels a proposal only if sender is the guardian and proposal is not executed\n * @param proposalId_ Id of proposal that is to be canceled\n * @custom:access Sender must be the guardian\n * @custom:event Emits ProposalCanceled with proposal id of the canceled proposal\n */\n function cancel(uint256 proposalId_) external {\n require(\n state(proposalId_) == ProposalState.Queued,\n \"OmnichainGovernanceExecutor::cancel: proposal should be queued and not executed\"\n );\n Proposal storage proposal = proposals[proposalId_];\n require(msg.sender == guardian, \"OmnichainGovernanceExecutor::cancel: sender must be guardian\");\n\n proposal.canceled = true;\n ITimelock timelock = proposalTimelocks[proposal.proposalType];\n uint256 eta = proposal.eta;\n uint256 length = proposal.targets.length;\n\n emit ProposalCanceled(proposalId_);\n\n for (uint256 i; i < length; ++i) {\n timelock.cancelTransaction(\n proposal.targets[i],\n proposal.values[i],\n proposal.signatures[i],\n proposal.calldatas[i],\n eta\n );\n }\n delete queued[proposalId_];\n }\n\n /**\n * @notice Sets the new pending admin of the Timelock\n * @param pendingAdmin_ Address of new pending admin\n * @param proposalType_ Type of proposal\n * @custom:access Only owner\n * @custom:event Emits SetTimelockPendingAdmin with new pending admin and proposal type\n */\n function setTimelockPendingAdmin(address pendingAdmin_, uint8 proposalType_) external onlyOwner {\n uint8 proposalTypeLength = uint8(type(ProposalType).max) + 1;\n require(\n proposalType_ < proposalTypeLength,\n \"OmnichainGovernanceExecutor::setTimelockPendingAdmin: invalid proposal type\"\n );\n\n proposalTimelocks[proposalType_].setPendingAdmin(pendingAdmin_);\n emit SetTimelockPendingAdmin(pendingAdmin_, proposalType_);\n }\n\n /**\n * @notice Resends a previously failed message\n * @param srcChainId_ Source chain Id\n * @param srcAddress_ Source address => local app address + remote app address\n * @param nonce_ Nonce to identify failed message\n * @param payload_ The payload of the message to be retried\n * @custom:access Only owner\n */\n function retryMessage(\n uint16 srcChainId_,\n bytes calldata srcAddress_,\n uint64 nonce_,\n bytes calldata payload_\n ) public payable override onlyOwner nonReentrant {\n require(\n keccak256(trustedRemoteLookup[srcChainId_]) == keccak256(srcAddress_),\n \"OmnichainGovernanceExecutor::retryMessage: not a trusted remote\"\n );\n super.retryMessage(srcChainId_, srcAddress_, nonce_, payload_);\n }\n\n /**\n * @notice Gets the state of a proposal\n * @param proposalId_ The id of the proposal\n * @return Proposal state\n */\n function state(uint256 proposalId_) public view returns (ProposalState) {\n Proposal storage proposal = proposals[proposalId_];\n if (proposal.canceled) {\n return ProposalState.Canceled;\n } else if (proposal.executed) {\n return ProposalState.Executed;\n } else if (queued[proposalId_]) {\n // queued only when proposal is received\n return ProposalState.Queued;\n } else {\n revert InvalidProposalId();\n }\n }\n\n /**\n * @notice Process blocking LayerZero receive request\n * @param srcChainId_ Source chain Id\n * @param srcAddress_ Source address from which payload is received\n * @param nonce_ Nonce associated with the payload to prevent replay attacks\n * @param payload_ Encoded payload containing proposal information\n * @custom:event Emit ReceivePayloadFailed if call fails\n */\n function _blockingLzReceive(\n uint16 srcChainId_,\n bytes memory srcAddress_,\n uint64 nonce_,\n bytes memory payload_\n ) internal virtual override {\n require(srcChainId_ == srcChainId, \"OmnichainGovernanceExecutor::_blockingLzReceive: invalid source chain id\");\n bytes32 hashedPayload = keccak256(payload_);\n bytes memory callData = abi.encodeCall(this.nonblockingLzReceive, (srcChainId_, srcAddress_, nonce_, payload_));\n\n (bool success, bytes memory reason) = address(this).excessivelySafeCall(gasleft() - 30000, 150, callData);\n // try-catch all errors/exceptions\n if (!success) {\n failedMessages[srcChainId_][srcAddress_][nonce_] = hashedPayload;\n emit ReceivePayloadFailed(srcChainId_, srcAddress_, nonce_, reason); // Retrieve payload from the src side tx if needed to clear\n }\n }\n\n /**\n * @notice Process non blocking LayerZero receive request\n * @param payload_ Encoded payload containing proposal information\n * @custom:event Emit ProposalReceived\n */\n function _nonblockingLzReceive(\n uint16,\n bytes memory,\n uint64,\n bytes memory payload_\n ) internal virtual override whenNotPaused {\n (bytes memory payload, uint256 pId) = abi.decode(payload_, (bytes, uint256));\n (\n address[] memory targets,\n uint256[] memory values,\n string[] memory signatures,\n bytes[] memory calldatas,\n uint8 pType\n ) = abi.decode(payload, (address[], uint256[], string[], bytes[], uint8));\n require(proposals[pId].id == 0, \"OmnichainGovernanceExecutor::_nonblockingLzReceive: duplicate proposal\");\n require(\n targets.length == values.length &&\n targets.length == signatures.length &&\n targets.length == calldatas.length,\n \"OmnichainGovernanceExecutor::_nonblockingLzReceive: proposal function information arity mismatch\"\n );\n require(\n pType < uint8(type(ProposalType).max) + 1,\n \"OmnichainGovernanceExecutor::_nonblockingLzReceive: invalid proposal type\"\n );\n _isEligibleToReceive(targets.length);\n\n Proposal memory newProposal = Proposal({\n id: pId,\n eta: 0,\n targets: targets,\n values: values,\n signatures: signatures,\n calldatas: calldatas,\n canceled: false,\n executed: false,\n proposalType: pType\n });\n\n proposals[pId] = newProposal;\n lastProposalReceived = pId;\n\n emit ProposalReceived(newProposal.id, targets, values, signatures, calldatas, pType);\n _queue(pId);\n }\n\n /**\n * @notice Queue proposal for execution\n * @param proposalId_ Proposal to be queued\n * @custom:event Emit ProposalQueued with proposal id and eta\n */\n function _queue(uint256 proposalId_) internal {\n Proposal storage proposal = proposals[proposalId_];\n uint256 eta = block.timestamp + proposalTimelocks[proposal.proposalType].delay();\n\n proposal.eta = eta;\n queued[proposalId_] = true;\n uint8 proposalType = proposal.proposalType;\n uint256 length = proposal.targets.length;\n emit ProposalQueued(proposalId_, eta);\n\n for (uint256 i; i < length; ++i) {\n _queueOrRevertInternal(\n proposal.targets[i],\n proposal.values[i],\n proposal.signatures[i],\n proposal.calldatas[i],\n eta,\n proposalType\n );\n }\n }\n\n /**\n * @notice Check for unique 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 * @param proposalType_ Type of proposal\n */\n function _queueOrRevertInternal(\n address target_,\n uint256 value_,\n string memory signature_,\n bytes memory data_,\n uint256 eta_,\n uint8 proposalType_\n ) internal {\n require(\n !proposalTimelocks[proposalType_].queuedTransactions(\n keccak256(abi.encode(target_, value_, signature_, data_, eta_))\n ),\n \"OmnichainGovernanceExecutor::queueOrRevertInternal: identical proposal action already queued at eta\"\n );\n\n proposalTimelocks[proposalType_].queueTransaction(target_, value_, signature_, data_, eta_);\n }\n}\n"
},
"contracts/Cross-chain/OmnichainProposalSender.sol": {
"content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.8.25;\n\nimport { ReentrancyGuard } from \"@openzeppelin/contracts/security/ReentrancyGuard.sol\";\nimport { ILayerZeroEndpoint } from \"@layerzerolabs/solidity-examples/contracts/lzApp/interfaces/ILayerZeroEndpoint.sol\";\nimport { ensureNonzeroAddress } from \"@venusprotocol/solidity-utilities/contracts/validators.sol\";\nimport { BaseOmnichainControllerSrc } from \"./BaseOmnichainControllerSrc.sol\";\n\n/**\n * @title OmnichainProposalSender\n * @author Venus\n * @notice OmnichainProposalSender contract builds upon the functionality of its parent contract , BaseOmnichainControllerSrc\n * It sends a proposal's data to remote chains for execution after the proposal passes on the main chain\n * when used with GovernorBravo, the owner of this contract must be set to the Timelock contract\n * @custom:security-contact https://github.com/VenusProtocol/governance-contracts#discussion\n */\n\ncontract OmnichainProposalSender is ReentrancyGuard, BaseOmnichainControllerSrc {\n /**\n * @notice Stores the total number of remote proposals\n */\n uint256 public proposalCount;\n\n /**\n * @notice Execution hashes of failed messages\n * @dev [proposalId] -> [executionHash]\n */\n mapping(uint256 => bytes32) public storedExecutionHashes;\n\n /**\n * @notice LayerZero endpoint for sending messages to remote chains\n */\n ILayerZeroEndpoint public immutable LZ_ENDPOINT;\n\n /**\n * @notice Specifies the allowed path for sending messages (remote chainId => remote app address + local app address)\n */\n mapping(uint16 => bytes) public trustedRemoteLookup;\n\n /**\n * @notice Emitted when a remote message receiver is set for the remote chain\n */\n event SetTrustedRemoteAddress(uint16 indexed remoteChainId, bytes oldRemoteAddress, bytes newRemoteAddress);\n\n /**\n * @notice Event emitted when trusted remote sets to empty\n */\n event TrustedRemoteRemoved(uint16 indexed chainId);\n\n /**\n * @notice Emitted when a proposal execution request is sent to the remote chain\n */\n event ExecuteRemoteProposal(uint16 indexed remoteChainId, uint256 proposalId, bytes payload);\n\n /**\n * @notice Emitted when a previously failed message is successfully sent to the remote chain\n */\n event ClearPayload(uint256 indexed proposalId, bytes32 executionHash);\n\n /**\n * @notice Emitted when an execution hash of a failed message is saved\n */\n event StorePayload(\n uint256 indexed proposalId,\n uint16 indexed remoteChainId,\n bytes payload,\n bytes adapterParams,\n uint256 value,\n bytes reason\n );\n /**\n * @notice Emitted while fallback withdraw\n */\n event FallbackWithdraw(address indexed receiver, uint256 value);\n\n constructor(\n ILayerZeroEndpoint lzEndpoint_,\n address accessControlManager_\n ) BaseOmnichainControllerSrc(accessControlManager_) {\n ensureNonzeroAddress(address(lzEndpoint_));\n LZ_ENDPOINT = lzEndpoint_;\n }\n\n /**\n * @notice Estimates LayerZero fees for cross-chain message delivery to the remote chain\n * @dev The estimated fees are the minimum required; it's recommended to increase the fees amount when sending a message. The unused amount will be refunded\n * @param remoteChainId_ The LayerZero id of a remote chain\n * @param payload_ The payload to be sent to the remote chain. It's computed as follows:\n * payload = abi.encode(abi.encode(targets, values, signatures, calldatas, proposalType), pId)\n * @param useZro_ Bool that indicates whether to pay in ZRO tokens or not\n * @param adapterParams_ The params used to specify the custom amount of gas required for the execution on the destination\n * @return nativeFee The amount of fee in the native gas token (e.g. ETH)\n * @return zroFee The amount of fee in ZRO token\n */\n function estimateFees(\n uint16 remoteChainId_,\n bytes calldata payload_,\n bool useZro_,\n bytes calldata adapterParams_\n ) external view returns (uint256, uint256) {\n return LZ_ENDPOINT.estimateFees(remoteChainId_, address(this), payload_, useZro_, adapterParams_);\n }\n\n /**\n * @notice Remove trusted remote from storage\n * @param remoteChainId_ The chain's id corresponds to setting the trusted remote to empty\n * @custom:access Controlled by Access Control Manager\n * @custom:event Emit TrustedRemoteRemoved with remote chain id\n */\n function removeTrustedRemote(uint16 remoteChainId_) external {\n _ensureAllowed(\"removeTrustedRemote(uint16)\");\n require(trustedRemoteLookup[remoteChainId_].length != 0, \"OmnichainProposalSender: trusted remote not found\");\n delete trustedRemoteLookup[remoteChainId_];\n emit TrustedRemoteRemoved(remoteChainId_);\n }\n\n /**\n * @notice Sends a message to execute a remote proposal\n * @dev Stores the hash of the execution parameters if sending fails (e.g., due to insufficient fees)\n * @param remoteChainId_ The LayerZero id of the remote chain\n * @param payload_ The payload to be sent to the remote chain\n * It's computed as follows: payload = abi.encode(targets, values, signatures, calldatas, proposalType)\n * @param adapterParams_ The params used to specify the custom amount of gas required for the execution on the destination\n * @param zroPaymentAddress_ The address of the ZRO token holder who would pay for the transaction. This must be either address(this) or tx.origin\n * @custom:event Emits ExecuteRemoteProposal with remote chain id, proposal ID and payload on success\n * @custom:event Emits StorePayload with last stored payload proposal ID ,remote chain id , payload, adapter params , values and reason for failure\n * @custom:access Controlled by Access Control Manager\n */\n function execute(\n uint16 remoteChainId_,\n bytes calldata payload_,\n bytes calldata adapterParams_,\n address zroPaymentAddress_\n ) external payable whenNotPaused {\n _ensureAllowed(\"execute(uint16,bytes,bytes,address)\");\n\n // A zero value will result in a failed message; therefore, a positive value is required to send a message across the chain.\n require(msg.value > 0, \"OmnichainProposalSender: value cannot be zero\");\n require(payload_.length != 0, \"OmnichainProposalSender: empty payload\");\n\n bytes memory trustedRemote = trustedRemoteLookup[remoteChainId_];\n require(trustedRemote.length != 0, \"OmnichainProposalSender: destination chain is not a trusted source\");\n _validateProposal(remoteChainId_, payload_);\n uint256 _pId = ++proposalCount;\n bytes memory payload = abi.encode(payload_, _pId);\n\n try\n LZ_ENDPOINT.send{ value: msg.value }(\n remoteChainId_,\n trustedRemote,\n payload,\n payable(msg.sender),\n zroPaymentAddress_,\n adapterParams_\n )\n {\n emit ExecuteRemoteProposal(remoteChainId_, _pId, payload);\n } catch (bytes memory reason) {\n storedExecutionHashes[_pId] = keccak256(abi.encode(remoteChainId_, payload, adapterParams_, msg.value));\n emit StorePayload(_pId, remoteChainId_, payload, adapterParams_, msg.value, reason);\n }\n }\n\n /**\n * @notice Resends a previously failed message\n * @dev Allows providing more fees if needed. The extra fees will be refunded to the caller\n * @param pId_ The proposal ID to identify a failed message\n * @param remoteChainId_ The LayerZero id of the remote chain\n * @param payload_ The payload to be sent to the remote chain\n * It's computed as follows: payload = abi.encode(abi.encode(targets, values, signatures, calldatas, proposalType), pId)\n * @param adapterParams_ The params used to specify the custom amount of gas required for the execution on the destination\n * @param zroPaymentAddress_ The address of the ZRO token holder who would pay for the transaction.\n * @param originalValue_ The msg.value passed when execute() function was called\n * @custom:event Emits ClearPayload with proposal ID and hash\n * @custom:access Controlled by Access Control Manager\n */\n function retryExecute(\n uint256 pId_,\n uint16 remoteChainId_,\n bytes calldata payload_,\n bytes calldata adapterParams_,\n address zroPaymentAddress_,\n uint256 originalValue_\n ) external payable whenNotPaused nonReentrant {\n _ensureAllowed(\"retryExecute(uint256,uint16,bytes,bytes,address,uint256)\");\n bytes memory trustedRemote = trustedRemoteLookup[remoteChainId_];\n require(trustedRemote.length != 0, \"OmnichainProposalSender: destination chain is not a trusted source\");\n bytes32 hash = storedExecutionHashes[pId_];\n require(hash != bytes32(0), \"OmnichainProposalSender: no stored payload\");\n require(payload_.length != 0, \"OmnichainProposalSender: empty payload\");\n (bytes memory payload, ) = abi.decode(payload_, (bytes, uint256));\n _validateProposal(remoteChainId_, payload);\n\n require(\n keccak256(abi.encode(remoteChainId_, payload_, adapterParams_, originalValue_)) == hash,\n \"OmnichainProposalSender: invalid execution params\"\n );\n\n delete storedExecutionHashes[pId_];\n\n emit ClearPayload(pId_, hash);\n\n LZ_ENDPOINT.send{ value: originalValue_ + msg.value }(\n remoteChainId_,\n trustedRemote,\n payload_,\n payable(msg.sender),\n zroPaymentAddress_,\n adapterParams_\n );\n }\n\n /**\n * @notice Clear previously failed message\n * @param to_ Address of the receiver\n * @param pId_ The proposal ID to identify a failed message\n * @param remoteChainId_ The LayerZero id of the remote chain\n * @param payload_ The payload to be sent to the remote chain\n * It's computed as follows: payload = abi.encode(abi.encode(targets, values, signatures, calldatas, proposalType), pId)\n * @param adapterParams_ The params used to specify the custom amount of gas required for the execution on the destination\n * @param originalValue_ The msg.value passed when execute() function was called\n * @custom:access Only owner\n * @custom:event Emits ClearPayload with proposal ID and hash\n * @custom:event Emits FallbackWithdraw with receiver and amount\n */\n function fallbackWithdraw(\n address to_,\n uint256 pId_,\n uint16 remoteChainId_,\n bytes calldata payload_,\n bytes calldata adapterParams_,\n uint256 originalValue_\n ) external onlyOwner nonReentrant {\n ensureNonzeroAddress(to_);\n require(originalValue_ > 0, \"OmnichainProposalSender: invalid native amount\");\n require(payload_.length != 0, \"OmnichainProposalSender: empty payload\");\n\n bytes32 hash = storedExecutionHashes[pId_];\n require(hash != bytes32(0), \"OmnichainProposalSender: no stored payload\");\n\n bytes memory execution = abi.encode(remoteChainId_, payload_, adapterParams_, originalValue_);\n require(keccak256(execution) == hash, \"OmnichainProposalSender: invalid execution params\");\n\n delete storedExecutionHashes[pId_];\n\n emit FallbackWithdraw(to_, originalValue_);\n emit ClearPayload(pId_, hash);\n\n // Transfer the native to the `to_` address\n (bool sent, ) = to_.call{ value: originalValue_ }(\"\");\n require(sent, \"Call failed\");\n }\n\n /**\n * @notice Sets the remote message receiver address\n * @param remoteChainId_ The LayerZero id of a remote chain\n * @param newRemoteAddress_ The address of the contract on the remote chain to receive messages sent by this contract\n * @custom:access Controlled by AccessControlManager\n * @custom:event Emits SetTrustedRemoteAddress with remote chain Id and remote address\n */\n function setTrustedRemoteAddress(uint16 remoteChainId_, bytes calldata newRemoteAddress_) external {\n _ensureAllowed(\"setTrustedRemoteAddress(uint16,bytes)\");\n require(remoteChainId_ != 0, \"OmnichainProposalSender: chainId must not be zero\");\n ensureNonzeroAddress(address(uint160(bytes20(newRemoteAddress_))));\n require(newRemoteAddress_.length == 20, \"OmnichainProposalSender: remote address must be 20 bytes long\");\n bytes memory oldRemoteAddress = trustedRemoteLookup[remoteChainId_];\n trustedRemoteLookup[remoteChainId_] = abi.encodePacked(newRemoteAddress_, address(this));\n emit SetTrustedRemoteAddress(remoteChainId_, oldRemoteAddress, trustedRemoteLookup[remoteChainId_]);\n }\n\n /**\n * @notice Sets the configuration of the LayerZero messaging library of the specified version\n * @param version_ Messaging library version\n * @param chainId_ The LayerZero chainId for the pending config change\n * @param configType_ The type of configuration. Every messaging library has its own convention\n * @param config_ The configuration in bytes. It can encode arbitrary content\n * @custom:access Controlled by AccessControlManager\n */\n function setConfig(uint16 version_, uint16 chainId_, uint256 configType_, bytes calldata config_) external {\n _ensureAllowed(\"setConfig(uint16,uint16,uint256,bytes)\");\n LZ_ENDPOINT.setConfig(version_, chainId_, configType_, config_);\n }\n\n /**\n * @notice Sets the configuration of the LayerZero messaging library of the specified version\n * @param version_ New messaging library version\n * @custom:access Controlled by AccessControlManager\n */\n function setSendVersion(uint16 version_) external {\n _ensureAllowed(\"setSendVersion(uint16)\");\n LZ_ENDPOINT.setSendVersion(version_);\n }\n\n /**\n * @notice Gets the configuration of the LayerZero messaging library of the specified version\n * @param version_ Messaging library version\n * @param chainId_ The LayerZero chainId\n * @param configType_ Type of configuration. Every messaging library has its own convention\n */\n function getConfig(uint16 version_, uint16 chainId_, uint256 configType_) external view returns (bytes memory) {\n return LZ_ENDPOINT.getConfig(version_, chainId_, address(this), configType_);\n }\n\n function _validateProposal(uint16 remoteChainId_, bytes memory payload_) internal {\n (\n address[] memory targets,\n uint256[] memory values,\n string[] memory signatures,\n bytes[] memory calldatas,\n\n ) = abi.decode(payload_, (address[], uint[], string[], bytes[], uint8));\n require(\n targets.length == values.length &&\n targets.length == signatures.length &&\n targets.length == calldatas.length,\n \"OmnichainProposalSender: proposal function information arity mismatch\"\n );\n _isEligibleToSend(remoteChainId_, targets.length);\n }\n}\n"
},
"contracts/Governance/AccessControlledV8.sol": {
"content": "// SPDX-License-Identifier: BSD-3-Clause\npragma solidity 0.8.25;\n\nimport \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/access/Ownable2StepUpgradeable.sol\";\n\nimport \"./IAccessControlManagerV8.sol\";\n\n/**\n * @title AccessControlledV8\n * @author Venus\n * @notice This contract is helper between access control manager and actual contract. This contract further inherited by other contract (using solidity 0.8.13)\n * to integrate access controlled mechanism. It provides initialise methods and verifying access methods.\n */\nabstract contract AccessControlledV8 is Initializable, Ownable2StepUpgradeable {\n /// @notice Access control manager contract\n IAccessControlManagerV8 internal _accessControlManager;\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n\n /// @notice Emitted when access control manager contract address is changed\n event NewAccessControlManager(address oldAccessControlManager, address newAccessControlManager);\n\n /// @notice Thrown when the action is prohibited by AccessControlManager\n error Unauthorized(address sender, address calledContract, string methodSignature);\n\n function __AccessControlled_init(address accessControlManager_) internal onlyInitializing {\n __Ownable2Step_init();\n __AccessControlled_init_unchained(accessControlManager_);\n }\n\n function __AccessControlled_init_unchained(address accessControlManager_) internal onlyInitializing {\n _setAccessControlManager(accessControlManager_);\n }\n\n /**\n * @notice Sets the address of AccessControlManager\n * @dev Admin function to set address of AccessControlManager\n * @param accessControlManager_ The new address of the AccessControlManager\n * @custom:event Emits NewAccessControlManager event\n * @custom:access Only Governance\n */\n function setAccessControlManager(address accessControlManager_) external onlyOwner {\n _setAccessControlManager(accessControlManager_);\n }\n\n /**\n * @notice Returns the address of the access control manager contract\n */\n function accessControlManager() external view returns (IAccessControlManagerV8) {\n return _accessControlManager;\n }\n\n /**\n * @dev Internal function to set address of AccessControlManager\n * @param accessControlManager_ The new address of the AccessControlManager\n */\n function _setAccessControlManager(address accessControlManager_) internal {\n require(address(accessControlManager_) != address(0), \"invalid acess control manager address\");\n address oldAccessControlManager = address(_accessControlManager);\n _accessControlManager = IAccessControlManagerV8(accessControlManager_);\n emit NewAccessControlManager(oldAccessControlManager, accessControlManager_);\n }\n\n /**\n * @notice Reverts if the call is not allowed by AccessControlManager\n * @param signature Method signature\n */\n function _checkAccessAllowed(string memory signature) internal view {\n bool isAllowedToCall = _accessControlManager.isAllowedToCall(msg.sender, signature);\n\n if (!isAllowedToCall) {\n revert Unauthorized(msg.sender, address(this), signature);\n }\n }\n}\n"
},
"contracts/Governance/AccessControlManager.sol": {
"content": "// SPDX-License-Identifier: BSD-3-Clause\npragma solidity 0.8.25;\nimport \"@openzeppelin/contracts/access/AccessControl.sol\";\nimport \"./IAccessControlManagerV8.sol\";\n\n/**\n * @title AccessControlManager\n * @author Venus\n * @dev This contract is a wrapper of OpenZeppelin AccessControl extending it in a way to standartize access control within Venus Smart Contract Ecosystem.\n * @notice Access control plays a crucial role in the Venus governance model. It is used to restrict functions so that they can only be called from one\n * account or list of accounts (EOA or Contract Accounts).\n *\n * The implementation of `AccessControlManager`(https://github.com/VenusProtocol/governance-contracts/blob/main/contracts/Governance/AccessControlManager.sol)\n * inherits the [Open Zeppelin AccessControl](https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/access/AccessControl.sol)\n * contract as a base for role management logic. There are two role types: admin and granular permissions.\n * \n * ## Granular Roles\n * \n * Granular roles are built by hashing the contract address and its function signature. For example, given contract `Foo` with function `Foo.bar()` which\n * is guarded by ACM, calling `giveRolePermission` for account B do the following:\n * \n * 1. Compute `keccak256(contractFooAddress,functionSignatureBar)`\n * 1. Add the computed role to the roles of account B\n * 1. Account B now can call `ContractFoo.bar()`\n * \n * ## Admin Roles\n * \n * Admin roles allow for an address to call a function signature on any contract guarded by the `AccessControlManager`. This is particularly useful for\n * contracts created by factories.\n * \n * For Admin roles a null address is hashed in place of the contract address (`keccak256(0x0000000000000000000000000000000000000000,functionSignatureBar)`.\n * \n * In the previous example, giving account B the admin role, account B will have permissions to call the `bar()` function on any contract that is guarded by\n * ACM, not only contract A.\n * \n * ## Protocol Integration\n * \n * All restricted functions in Venus Protocol use a hook to ACM in order to check if the caller has the right permission to call the guarded function.\n * `AccessControlledV5` and `AccessControlledV8` abstract contract makes this integration easier. They call ACM's external method\n * `isAllowedToCall(address caller, string functionSig)`. Here is an example of how `setCollateralFactor` function in `Comptroller` is integrated with ACM:\n\n```\n contract Comptroller is [...] AccessControlledV8 {\n [...]\n function setCollateralFactor(VToken vToken, uint256 newCollateralFactorMantissa, uint256 newLiquidationThresholdMantissa) external {\n _checkAccessAllowed(\"setCollateralFactor(address,uint256,uint256)\");\n [...]\n }\n }\n```\n */\ncontract AccessControlManager is AccessControl, IAccessControlManagerV8 {\n /// @notice Emitted when an account is given a permission to a certain contract function\n /// @dev If contract address is 0x000..0 this means that the account is a default admin of this function and\n /// can call any contract function with this signature\n event PermissionGranted(address account, address contractAddress, string functionSig);\n\n /// @notice Emitted when an account is revoked a permission to a certain contract function\n event PermissionRevoked(address account, address contractAddress, string functionSig);\n\n constructor() {\n // Grant the contract deployer the default admin role: it will be able\n // to grant and revoke any roles\n _setupRole(DEFAULT_ADMIN_ROLE, msg.sender);\n }\n\n /**\n * @notice Gives a function call permission to one single account\n * @dev this function can be called only from Role Admin or DEFAULT_ADMIN_ROLE\n * @param contractAddress address of contract for which call permissions will be granted\n * @dev if contractAddress is zero address, the account can access the specified function\n * on **any** contract managed by this ACL\n * @param functionSig signature e.g. \"functionName(uint256,bool)\"\n * @param accountToPermit account that will be given access to the contract function\n * @custom:event Emits a {RoleGranted} and {PermissionGranted} events.\n */\n function giveCallPermission(address contractAddress, string calldata functionSig, address accountToPermit) public {\n bytes32 role = keccak256(abi.encodePacked(contractAddress, functionSig));\n grantRole(role, accountToPermit);\n emit PermissionGranted(accountToPermit, contractAddress, functionSig);\n }\n\n /**\n * @notice Revokes an account's permission to a particular function call\n * @dev this function can be called only from Role Admin or DEFAULT_ADMIN_ROLE\n * \t\tMay emit a {RoleRevoked} event.\n * @param contractAddress address of contract for which call permissions will be revoked\n * @param functionSig signature e.g. \"functionName(uint256,bool)\"\n * @custom:event Emits {RoleRevoked} and {PermissionRevoked} events.\n */\n function revokeCallPermission(\n address contractAddress,\n string calldata functionSig,\n address accountToRevoke\n ) public {\n bytes32 role = keccak256(abi.encodePacked(contractAddress, functionSig));\n revokeRole(role, accountToRevoke);\n emit PermissionRevoked(accountToRevoke, contractAddress, functionSig);\n }\n\n /**\n * @notice Verifies if the given account can call a contract's guarded function\n * @dev Since restricted contracts using this function as a permission hook, we can get contracts address with msg.sender\n * @param account for which call permissions will be checked\n * @param functionSig restricted function signature e.g. \"functionName(uint256,bool)\"\n * @return false if the user account cannot call the particular contract function\n *\n */\n function isAllowedToCall(address account, string calldata functionSig) public view returns (bool) {\n bytes32 role = keccak256(abi.encodePacked(msg.sender, functionSig));\n\n if (hasRole(role, account)) {\n return true;\n } else {\n role = keccak256(abi.encodePacked(address(0), functionSig));\n return hasRole(role, account);\n }\n }\n\n /**\n * @notice Verifies if the given account can call a contract's guarded function\n * @dev This function is used as a view function to check permissions rather than contract hook for access restriction check.\n * @param account for which call permissions will be checked against\n * @param contractAddress address of the restricted contract\n * @param functionSig signature of the restricted function e.g. \"functionName(uint256,bool)\"\n * @return false if the user account cannot call the particular contract function\n */\n function hasPermission(\n address account,\n address contractAddress,\n string calldata functionSig\n ) public view returns (bool) {\n bytes32 role = keccak256(abi.encodePacked(contractAddress, functionSig));\n return hasRole(role, account);\n }\n}\n"
},
"contracts/Governance/IAccessControlManagerV8.sol": {
"content": "// SPDX-License-Identifier: BSD-3-Clause\npragma solidity ^0.8.25;\n\nimport \"@openzeppelin/contracts/access/IAccessControl.sol\";\n\n/**\n * @title IAccessControlManagerV8\n * @author Venus\n * @notice Interface implemented by the `AccessControlManagerV8` contract.\n */\ninterface IAccessControlManagerV8 is IAccessControl {\n function giveCallPermission(address contractAddress, string calldata functionSig, address accountToPermit) external;\n\n function revokeCallPermission(\n address contractAddress,\n string calldata functionSig,\n address accountToRevoke\n ) external;\n\n function isAllowedToCall(address account, string calldata functionSig) external view returns (bool);\n\n function hasPermission(\n address account,\n address contractAddress,\n string calldata functionSig\n ) external view returns (bool);\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/interfaces/ICorePoolComptroller.sol": {
"content": "// SPDX-License-Identifier: BSD-3-Clause\npragma solidity 0.8.25;\n\ninterface ICorePoolComptroller {\n function borrowCaps(address) external view returns (uint256);\n\n function supplyCaps(address) external view returns (uint256);\n\n function _setMarketSupplyCaps(address[] calldata, uint256[] calldata) external;\n\n function _setMarketBorrowCaps(address[] calldata, uint256[] calldata) external;\n\n function setMarketSupplyCaps(address[] calldata, uint256[] calldata) external;\n\n function setMarketBorrowCaps(address[] calldata, uint256[] calldata) external;\n\n function getAllMarkets() external view returns (address[] memory);\n\n function setCollateralFactor(\n uint96 poolId,\n address vToken,\n uint256 newCollateralFactorMantissa,\n uint256 newLiquidizationThresholdMantissa\n ) external returns (uint256);\n\n function setCollateralFactor(\n address vToken,\n uint256 newCollateralFactorMantissa,\n uint256 newLiquidationThresholdMantissa\n ) external returns (uint256);\n\n function markets(\n address\n )\n external\n view\n returns (\n bool isListed,\n uint256 collateralFactorMantissa,\n bool isVenus,\n uint256 liquidationThresholdMantissa,\n uint256 liquidationIncentiveMantissa,\n uint96 marketPoolId,\n bool isBorrowAllowed\n );\n\n function poolMarkets(\n uint96 poolId,\n address vToken\n )\n external\n view\n returns (\n bool isListed,\n uint256 collateralFactorMantissa,\n bool isVenus,\n uint256 liquidationThresholdMantissa,\n uint256 liquidationIncentiveMantissa,\n uint96 marketPoolId,\n bool isBorrowAllowed\n );\n}\n"
},
"contracts/interfaces/ICorePoolVToken.sol": {
"content": "// SPDX-License-Identifier: BSD-3-Clause\npragma solidity 0.8.25;\n\nimport { InterestRateModelV8 } from \"@venusprotocol/venus-protocol/contracts/InterestRateModels/InterestRateModelV8.sol\";\n\ninterface ICorePoolVToken {\n function comptroller() external view returns (address);\n\n function interestRateModel() external view returns (address);\n\n function _setInterestRateModel(InterestRateModelV8 newInterestRateModel) external returns (uint256);\n}\n"
},
"contracts/interfaces/IIsolatedPoolsComptroller.sol": {
"content": "// SPDX-License-Identifier: BSD-3-Clause\npragma solidity 0.8.25;\n\ninterface IIsolatedPoolsComptroller {\n function borrowCaps(address) external view returns (uint256);\n\n function supplyCaps(address) external view returns (uint256);\n\n function setMarketSupplyCaps(address[] calldata, uint256[] calldata) external;\n\n function setMarketBorrowCaps(address[] calldata, uint256[] calldata) external;\n\n function getAllMarkets() external view returns (address[] memory);\n\n function setCollateralFactor(\n address vToken,\n uint256 newCollateralFactorMantissa,\n uint256 newLiquidationThresholdMantissa\n ) external;\n\n function markets(\n address vToken\n ) external view returns (bool isListed, uint256 collateralFactorMantissa, uint256 liquidationThresholdMantissa);\n}\n"
},
"contracts/interfaces/IIsolatedPoolVToken.sol": {
"content": "// SPDX-License-Identifier: BSD-3-Clause\npragma solidity 0.8.25;\n\nimport { InterestRateModel } from \"@venusprotocol/isolated-pools/contracts/InterestRateModel.sol\";\n\ninterface IIsolatedPoolVToken {\n function comptroller() external view returns (address);\n\n function interestRateModel() external view returns (address);\n\n function setInterestRateModel(InterestRateModel newInterestRateModel) external;\n}\n"
},
"contracts/RiskSteward/BaseRiskSteward.sol": {
"content": "// SPDX-License-Identifier: BSD-3-Clause\npragma solidity 0.8.25;\n\nimport { AccessControlledV8 } from \"../Governance/AccessControlledV8.sol\";\nimport { IRiskSteward } from \"./Interfaces/IRiskSteward.sol\";\n\n/**\n * @title BaseRiskSteward\n * @author Venus\n * @notice Abstract base contract for Risk Steward contracts providing common functionality\n * @custom:security-contact https://github.com/VenusProtocol/governance-contracts#discussion\n */\nabstract contract BaseRiskSteward is IRiskSteward, AccessControlledV8 {\n /// @dev Max basis points i.e., 100%\n uint256 internal constant MAX_BPS = 10000;\n\n /**\n * @notice The safe delta threshold in basis points.\n * @notice Updates within this delta are considered safe and require no timelock. Updates exceeding this delta require timelock.\n * @dev This is only used by contracts that implement safe delta checks (e.g., MarketCapsRiskSteward, CollateralFactorsRiskSteward)\n */\n uint256 public safeDeltaBps;\n\n /**\n * @notice Thrown when trying to renounce ownership\n */\n error RenounceOwnershipNotAllowed();\n\n /**\n * @notice Disables renounceOwnership function\n * @custom:error Throws RenounceOwnershipNotAllowed\n */\n function renounceOwnership() public pure override {\n revert RenounceOwnershipNotAllowed();\n }\n\n /**\n * @notice Checks if the difference between new and current values is within the safe delta threshold.\n * @param newValue The new value to check\n * @param currentValue The current value to compare against\n * @return True if the difference is within the safe delta, false otherwise\n */\n function _isWithinSafeDelta(uint256 newValue, uint256 currentValue) internal view returns (bool) {\n uint256 diff = newValue > currentValue ? newValue - currentValue : currentValue - newValue;\n uint256 maxDiff = (safeDeltaBps * currentValue) / MAX_BPS;\n return diff <= maxDiff;\n }\n}\n"
},
"contracts/RiskSteward/CollateralFactorsRiskSteward.sol": {
"content": "// SPDX-License-Identifier: BSD-3-Clause\npragma solidity 0.8.25;\n\nimport { RiskParameterUpdate } from \"./Interfaces/IRiskOracle.sol\";\nimport { ICorePoolVToken } from \"../interfaces/ICorePoolVToken.sol\";\nimport { ICorePoolComptroller } from \"../interfaces/ICorePoolComptroller.sol\";\nimport { IIsolatedPoolsComptroller } from \"../interfaces/IIsolatedPoolsComptroller.sol\";\nimport { IRiskStewardReceiver } from \"./Interfaces/IRiskStewardReceiver.sol\";\nimport { BaseRiskSteward } from \"./BaseRiskSteward.sol\";\nimport { ensureNonzeroAddress } from \"@venusprotocol/solidity-utilities/contracts/validators.sol\";\n\n/**\n * @title CollateralFactorsRiskSteward\n * @author Venus\n * @notice Contract that can update collateral factors and liquidation thresholds received from `RiskStewardReceiver`.\n * @custom:security-contact https://github.com/VenusProtocol/governance-contracts#discussion\n */\ncontract CollateralFactorsRiskSteward is BaseRiskSteward {\n /**\n * @notice The update type for collateral factor and liquidation threshold.\n */\n string public constant COLLATERAL_FACTORS = \"collateralFactors\";\n\n /**\n * @notice The update type key for collateral factors (keccak256 hash of COLLATERAL_FACTORS)\n */\n bytes32 public constant COLLATERAL_FACTORS_KEY = keccak256(bytes(COLLATERAL_FACTORS));\n\n /**\n * @notice Address of the BNB Core Pool Comptroller.\n * @dev This comptroller is specific to the BNB Core Pool, which uses a different ABI\n * than isolated pools. It is used solely to detect and handle BNB Core Pool\n * markets, and would not be used for remote-chain (isolated pool) deployments.\n */\n ICorePoolComptroller public immutable CORE_POOL_COMPTROLLER;\n\n /**\n * @notice Address of the `RiskStewardReceiver` used to validate and dispatch incoming updates.\n */\n IRiskStewardReceiver public immutable RISK_STEWARD_RECEIVER;\n\n /**\n * @dev Storage gap for upgradeability.\n */\n uint256[49] private __gap;\n\n /**\n * @notice Emitted when collateral factors are updated.\n */\n event CollateralFactorsUpdated(\n uint256 indexed updateId,\n address indexed market,\n uint256 newCollateralFactor,\n uint256 newLiquidationThreshold\n );\n\n /**\n * @notice Emitted when the safe delta bps is updated.\n */\n event SafeDeltaBpsUpdated(uint256 oldSafeDeltaBps, uint256 newSafeDeltaBps);\n\n /**\n * @notice Thrown when a `safeDeltaBps` value is greater than `MAX_BPS`.\n */\n error InvalidSafeDeltaBps();\n\n /**\n * @notice Thrown when Core Pool Comptroller.setCollateralFactor fails.\n */\n error SetCollateralFactorFailed(uint256 errorCode);\n\n /**\n * @notice Thrown when an update type that is not supported is operated on.\n */\n error UnsupportedUpdateType();\n\n /**\n * @notice Thrown when the update is not coming from the `RiskStewardReceiver`.\n */\n error OnlyRiskStewardReceiver();\n\n /**\n * @notice Thrown when the two uint256 data length is invalid\n */\n error InvalidTwoUintLength();\n\n /**\n * @notice Thrown when attempting to apply a redundant value (no-op change).\n */\n error RedundantValue();\n\n /**\n * @notice Sets the immutable `CORE_POOL_COMPTROLLER` and `RISK_STEWARD_RECEIVER` addresses and disables initializers.\n * @param corePoolComptroller_ The address of the Core Pool Comptroller\n * @param riskStewardReceiver_ The address of the `RiskStewardReceiver`\n * @custom:error Throws ZeroAddressNotAllowed if any of the addresses are zero\n * @custom:oz-upgrades-unsafe-allow constructor\n */\n constructor(address corePoolComptroller_, address riskStewardReceiver_) {\n ensureNonzeroAddress(riskStewardReceiver_);\n CORE_POOL_COMPTROLLER = ICorePoolComptroller(corePoolComptroller_);\n RISK_STEWARD_RECEIVER = IRiskStewardReceiver(riskStewardReceiver_);\n _disableInitializers();\n }\n\n /**\n * @notice Initializes the contract as ownable and access controlled.\n * @param accessControlManager_ The address of the access control manager\n */\n function initialize(address accessControlManager_) external initializer {\n __AccessControlled_init(accessControlManager_);\n }\n\n /**\n * @notice Sets the safe delta bps.\n * @param safeDeltaBps_ The new safe delta bps\n * @custom:access Controlled by AccessControlManager\n * @custom:event Emits SafeDeltaBpsUpdated with the old and new safe delta bps\n * @custom:error Throws InvalidSafeDeltaBps if the safe delta bps is greater than MAX_BPS\n */\n function setSafeDeltaBps(uint256 safeDeltaBps_) external {\n _checkAccessAllowed(\"setSafeDeltaBps(uint256)\");\n if (safeDeltaBps_ > MAX_BPS) {\n revert InvalidSafeDeltaBps();\n }\n uint256 oldSafeDeltaBps = safeDeltaBps;\n\n if (safeDeltaBps_ == oldSafeDeltaBps) {\n revert InvalidSafeDeltaBps();\n }\n safeDeltaBps = safeDeltaBps_;\n emit SafeDeltaBpsUpdated(oldSafeDeltaBps, safeDeltaBps_);\n }\n\n /**\n * @notice Checks if an update is safe for direct execution (no timelock required).\n * @param update The update to check.\n * @return True if update is safe for direct execution, false if timelock is required\n * @custom:error Throws UnsupportedUpdateType if the update type is not supported\n */\n function isSafeForDirectExecution(RiskParameterUpdate calldata update) external view returns (bool) {\n if (update.updateTypeKey == COLLATERAL_FACTORS_KEY) {\n // eMode-style updates always require timelock (not safe for direct execution)\n if (update.poolId != 0) return false;\n\n address comptroller = ICorePoolVToken(update.market).comptroller();\n\n (uint256 newCF, uint256 newLT) = _decodeAbiEncodedTwoUint256(update.newValue);\n (uint256 currCF, uint256 currLT) = _getCurrentCollateralFactors(comptroller, update.market);\n\n // Revert on redundant updates only when both CF and LT are unchanged.\n if (newCF == currCF && newLT == currLT) {\n revert RedundantValue();\n }\n\n // If current values are zero, update always requires timelock\n if (currCF == 0 || currLT == 0) return false;\n\n return _isWithinSafeDelta(newCF, currCF) && _isWithinSafeDelta(newLT, currLT);\n }\n\n revert UnsupportedUpdateType();\n }\n\n /**\n * @notice Applies a collateral parameter update from the `RiskStewardReceiver`.\n * Delta validation and timelock checks are already performed by `RiskStewardReceiver` before execution.\n * @param update RiskParameterUpdate update to apply\n * @custom:access Only callable by the `RiskStewardReceiver`\n * @custom:event Emits CollateralFactorsUpdated with updateId\n * @custom:error Throws OnlyRiskStewardReceiver if the sender is not the `RiskStewardReceiver`\n * @custom:error Throws UnsupportedUpdateType if the update type is not supported\n */\n function applyUpdate(RiskParameterUpdate calldata update) external {\n if (msg.sender != address(RISK_STEWARD_RECEIVER)) {\n revert OnlyRiskStewardReceiver();\n }\n\n address comptroller = ICorePoolVToken(update.market).comptroller();\n uint96 poolId = update.poolId;\n\n if (update.updateTypeKey == COLLATERAL_FACTORS_KEY) {\n _updateCollateralFactors(update.updateId, comptroller, update.market, poolId, update.newValue);\n } else {\n revert UnsupportedUpdateType();\n }\n }\n\n /**\n * @notice Updates the collateral factors for the given market.\n * @dev Updates both collateral factor and liquidation threshold together (same setter).\n * @param updateId The update ID from the Risk Oracle\n * @param comptroller The comptroller address\n * @param market The market to update the collateral factors for\n * @param poolId The pool identifier for eMode updates (0 for regular market updates)\n * @param newValue Encoded new collateral factors: `abi.encode(uint256 newCollateralFactor, uint256 newLiquidationThreshold)`\n * @custom:error Throws SetCollateralFactorFailed if the core pool comptroller call to setCollateralFactor returns a non‑zero error code\n * @custom:error Throws UnsupportedUpdateType if a non‑core comptroller is used together with a non‑zero poolId\n * @custom:event Emits CollateralFactorsUpdated with updateId\n */\n function _updateCollateralFactors(\n uint256 updateId,\n address comptroller,\n address market,\n uint96 poolId,\n bytes memory newValue\n ) internal {\n (uint256 newCollateralFactor, uint256 newLiquidationThreshold) = _decodeAbiEncodedTwoUint256(newValue);\n\n if (comptroller == address(CORE_POOL_COMPTROLLER)) {\n uint256 errorCode = ICorePoolComptroller(comptroller).setCollateralFactor(\n poolId,\n market,\n newCollateralFactor,\n newLiquidationThreshold\n );\n if (errorCode != 0) revert SetCollateralFactorFailed(errorCode);\n } else {\n if (poolId != 0) revert UnsupportedUpdateType();\n\n IIsolatedPoolsComptroller(comptroller).setCollateralFactor(\n market,\n newCollateralFactor,\n newLiquidationThreshold\n );\n }\n\n emit CollateralFactorsUpdated(updateId, market, newCollateralFactor, newLiquidationThreshold);\n }\n\n /**\n * @notice Returns the current collateral factors for a market on a given comptroller.\n * @dev Returns both collateral factor and liquidation threshold (updated together via the same setter).\n * @param comptroller The comptroller address\n * @param market The market whose collateral factors are being queried\n * @return currentCollateralFactor The current collateral factor\n * @return currentLiquidationThreshold The current liquidation threshold\n */\n function _getCurrentCollateralFactors(\n address comptroller,\n address market\n ) internal view returns (uint256 currentCollateralFactor, uint256 currentLiquidationThreshold) {\n if (comptroller == address(CORE_POOL_COMPTROLLER)) {\n (, currentCollateralFactor, , currentLiquidationThreshold, , , ) = ICorePoolComptroller(comptroller)\n .markets(market);\n } else {\n (, currentCollateralFactor, currentLiquidationThreshold) = IIsolatedPoolsComptroller(comptroller).markets(\n market\n );\n }\n }\n\n /**\n * @notice Decodes ABI-encoded bytes into two uint256 values.\n * @dev Expects exactly 64 bytes as produced by abi.encode(uint256,uint256).\n * @param data ABI-encoded (uint256, uint256) payload\n * @return a First uint256\n * @return b Second uint256\n */\n function _decodeAbiEncodedTwoUint256(bytes memory data) internal pure returns (uint256 a, uint256 b) {\n if (data.length != 64) {\n revert InvalidTwoUintLength();\n }\n\n (a, b) = abi.decode(data, (uint256, uint256));\n }\n}\n"
},
"contracts/RiskSteward/DestinationStewardReceiver.sol": {
"content": "// SPDX-License-Identifier: BSD-3-Clause\npragma solidity 0.8.25;\n\nimport { OwnableUpgradeable } from \"@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol\";\nimport { Ownable2StepUpgradeable } from \"@openzeppelin/contracts-upgradeable/access/Ownable2StepUpgradeable.sol\";\nimport { IDestinationStewardReceiver } from \"./Interfaces/IDestinationStewardReceiver.sol\";\nimport { RiskParameterUpdate } from \"./Interfaces/IRiskOracle.sol\";\nimport { IRiskSteward } from \"./Interfaces/IRiskSteward.sol\";\nimport { ensureNonzeroAddress } from \"@venusprotocol/solidity-utilities/contracts/validators.sol\";\nimport { AccessControlledV8 } from \"../Governance/AccessControlledV8.sol\";\nimport { IIsolatedPoolsComptroller } from \"../interfaces/IIsolatedPoolsComptroller.sol\";\nimport { OAppUpgradeable, Origin } from \"@layerzerolabs/oapp-evm-upgradeable/contracts/oapp/OAppUpgradeable.sol\";\n\n/**\n * @title DestinationStewardReceiver\n * @author Venus\n * @notice Destination‑chain contract that receives bridged updates from `RiskStewardReceiver` via LayerZero,\n * enforces a fixed remote delay, and then executes the updates on the configured `IRiskSteward` contracts.\n * @custom:security-contact https://github.com/VenusProtocol/governance-contracts#discussion\n */\ncontract DestinationStewardReceiver is IDestinationStewardReceiver, AccessControlledV8, OAppUpgradeable {\n /**\n * @notice Time before a bridged update is considered stale on the destination chain\n */\n uint256 public constant REMOTE_UPDATE_EXPIRATION_TIME = 2 days;\n\n /**\n * @notice Destination chain LayerZero endpoint ID\n */\n uint32 public immutable LAYER_ZERO_EID;\n\n /**\n * @notice Delay before a bridged update can be executed on the destination chain\n */\n uint256 public remoteDelay;\n\n /**\n * @notice Mapping of supported risk configurations per update type (hashed updateType string)\n */\n mapping(bytes32 => RiskParamConfig) public riskParameterConfigs;\n\n /**\n * @notice Master storage of all bridged updates by update ID\n */\n mapping(uint256 updateId => DestinationUpdate) public updates;\n\n /**\n * @notice Mapping from (updateType, market) to currently registered remote update ID\n */\n mapping(bytes32 => mapping(address market => uint256)) public lastRegisteredUpdateId;\n\n /**\n * @notice Track last executed update timestamp per (updateType, market)\n */\n mapping(bytes32 => mapping(address market => uint256)) public lastExecutedAt;\n\n /**\n * @notice Mapping from executor address to whitelist status\n */\n mapping(address => bool) public whitelistedExecutors;\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[44] private __gap;\n\n /**\n * @notice Modifier that ensures only whitelisted executors can call the function\n * @custom:error NotAnExecutor if the caller is not a whitelisted executor\n */\n modifier onlyWhitelistedExecutors() {\n if (!whitelistedExecutors[msg.sender]) {\n revert NotAnExecutor();\n }\n _;\n }\n\n /**\n * @notice Disables initializers and sets immutable values.\n * @param endpoint_ Local LayerZero endpoint on this chain\n * @param layerZeroEid_ LayerZero endpoint ID for this destination chain\n * @custom:oz-upgrades-unsafe-allow constructor\n */\n constructor(address endpoint_, uint32 layerZeroEid_) OAppUpgradeable(endpoint_) {\n _disableInitializers();\n ensureNonzeroAddress(endpoint_);\n if (layerZeroEid_ == 0) revert InvalidLayerZeroEid();\n\n LAYER_ZERO_EID = layerZeroEid_;\n }\n\n /**\n * @notice Initializes the contract with the Access Control Manager and owner.\n * @param accessControlManager_ The address of the access control manager\n * @param delegate_ The owner (and LayerZero delegate) of this contract\n */\n function initialize(address accessControlManager_, address delegate_) external initializer {\n __AccessControlled_init(accessControlManager_);\n __OApp_init(delegate_);\n remoteDelay = 6 hours; // Default value\n emit RemoteDelaySet(remoteDelay);\n }\n\n /**\n * @notice Sets the risk parameter config for a given update type on the destination chain.\n * @param updateType The type of update to configure (e.g., \"supplyCap\", \"borrowCap\")\n * @param riskSteward The address for the risk steward contract responsible for processing the update\n * @param debounce The debounce period for updates of this type on the destination (anti‑DoS)\n * @custom:access Controlled by AccessControlManager\n * @custom:event Emits RiskParameterConfigUpdated (with previousTimelock and timelock always emitted as 0)\n * @custom:error InvalidUpdateType if the update type string is empty\n * @custom:error InvalidDebounce if the debounce is 0\n */\n function setRiskParameterConfig(string calldata updateType, address riskSteward, uint256 debounce) external {\n _checkAccessAllowed(\"setRiskParameterConfig(string,address,uint256)\");\n ensureNonzeroAddress(riskSteward);\n\n if (bytes(updateType).length == 0 || bytes(updateType).length > 64) {\n revert InvalidUpdateType();\n }\n\n if (debounce == 0) {\n revert InvalidDebounce();\n }\n\n bytes32 key = keccak256(bytes(updateType));\n RiskParamConfig storage previousConfig = riskParameterConfigs[key];\n\n riskParameterConfigs[key] = RiskParamConfig({ active: true, debounce: debounce, riskSteward: riskSteward });\n\n emit RiskParameterConfigUpdated(\n key,\n updateType,\n previousConfig.riskSteward,\n riskSteward,\n previousConfig.debounce,\n debounce,\n previousConfig.active,\n true\n );\n }\n\n /**\n * @notice Sets the active status of a risk parameter config\n * @param updateType The type of update to configure\n * @param active The active status to set\n * @custom:access Controlled by AccessControlManager\n * @custom:event Emits ConfigActiveUpdated with the update type hash, update type, previous active status, and the active status\n * @custom:error Throws UnsupportedUpdateType if the update type is not supported\n * @custom:error Throws ConfigStatusUnchanged if the active status is already set to the desired value\n */\n function setConfigActive(string calldata updateType, bool active) external {\n _checkAccessAllowed(\"setConfigActive(string,bool)\");\n bytes32 key = keccak256(bytes(updateType));\n\n if (riskParameterConfigs[key].riskSteward == address(0)) {\n revert UnsupportedUpdateType();\n }\n\n bool previousActive = riskParameterConfigs[key].active;\n if (previousActive == active) {\n revert ConfigStatusUnchanged();\n }\n\n riskParameterConfigs[key].active = active;\n emit ConfigActiveUpdated(key, updateType, previousActive, active);\n }\n\n /**\n * @notice Sets the remote delay before bridged updates can be executed on the destination chain.\n * @param newRemoteDelay The new remote delay in seconds\n * @custom:access Controlled by AccessControlManager\n * @custom:event Emits RemoteDelaySet with the new remote delay value\n * @custom:error InvalidRemoteDelay if the delay is 0 or greater than or equal to the remote update expiration time\n * @custom:error RemoteDelayUnchanged if the new delay is equal to the current delay\n */\n function setRemoteDelay(uint256 newRemoteDelay) external {\n _checkAccessAllowed(\"setRemoteDelay(uint256)\");\n\n if (newRemoteDelay == 0 || newRemoteDelay >= REMOTE_UPDATE_EXPIRATION_TIME) {\n revert InvalidRemoteDelay();\n }\n\n uint256 previousDelay = remoteDelay;\n if (previousDelay == newRemoteDelay) {\n revert RemoteDelayUnchanged();\n }\n\n remoteDelay = newRemoteDelay;\n emit RemoteDelaySet(newRemoteDelay);\n }\n\n /**\n * @notice Sets the whitelist status of an executor on the destination chain.\n * @param executor The address of the executor\n * @param approved The whitelist status to set (true to whitelist, false to remove)\n * @custom:access Controlled by AccessControlManager\n * @custom:event Emits ExecutorStatusUpdated with the executor address, previous approval status, and new approval status\n * @custom:error Throws ZeroAddressNotAllowed if the executor address is zero\n * @custom:error Throws ExecutorStatusUnchanged if the executor whitelist status is already set to the desired value\n */\n function setWhitelistedExecutor(address executor, bool approved) external {\n _checkAccessAllowed(\"setWhitelistedExecutor(address,bool)\");\n ensureNonzeroAddress(executor);\n bool previousApproved = whitelistedExecutors[executor];\n if (previousApproved == approved) {\n revert ExecutorStatusUnchanged();\n }\n\n whitelistedExecutors[executor] = approved;\n emit ExecutorStatusUpdated(executor, previousApproved, approved);\n }\n\n /**\n * @notice Executes a bridged update after its remote delay has passed.\n * @param updateId The bridged update ID to execute\n * @custom:access Only whitelisted executors can execute updates\n * @custom:event Emits RemoteUpdateExecuted with the executed update ID\n * @custom:error NotAnExecutor if the caller is not a whitelisted executor\n * @custom:error ConfigNotActive if the configuration for the update type is not active\n * @custom:error UpdateNotFound if the update is not pending for the given (updateType, market)\n * @custom:error UpdateNotUnlocked if the remote delay has not elapsed\n * @custom:error UpdateIsExpired if the bridged update has expired on the destination\n * @custom:error UpdateTooFrequent if the debounce period has not passed since the last execution\n */\n function executeUpdate(uint256 updateId) external onlyWhitelistedExecutors {\n DestinationUpdate storage destUpdate = updates[updateId];\n RiskParameterUpdate memory update = destUpdate.update;\n bytes32 updateTypeKey = update.updateTypeKey;\n RiskParamConfig storage config = riskParameterConfigs[updateTypeKey];\n uint256 currentTime = block.timestamp;\n\n if (!config.active) {\n revert ConfigNotActive();\n }\n\n if (destUpdate.status != UpdateStatus.Pending) {\n revert UpdateNotFound();\n }\n\n if (currentTime < destUpdate.arrivalTime + remoteDelay) {\n revert UpdateNotUnlocked();\n }\n\n if (update.timestamp + REMOTE_UPDATE_EXPIRATION_TIME < currentTime) {\n revert UpdateIsExpired();\n }\n\n // Destination-side debounce based on last execution for this (updateType, market)\n uint256 lastExecutionTime = lastExecutedAt[updateTypeKey][update.market];\n if (lastExecutionTime != 0 && (lastExecutionTime + config.debounce > currentTime)) {\n revert UpdateTooFrequent();\n }\n\n lastExecutedAt[updateTypeKey][update.market] = currentTime;\n destUpdate.status = UpdateStatus.Executed;\n destUpdate.executor = msg.sender;\n\n IRiskSteward(config.riskSteward).applyUpdate(update);\n\n emit RemoteUpdateExecuted(updateId);\n }\n\n /**\n * @notice Rejects a registered remote update on the destination chain.\n * @param updateId The oracle update ID of the update to reject\n * @custom:access Only whitelisted executors can reject updates\n * @custom:event Emits UpdateRejected with the rejected update ID\n * @custom:error NotAnExecutor if the caller is not a whitelisted executor\n * @custom:error UpdateNotFound if there is no pending update with the given ID\n */\n function rejectUpdate(uint256 updateId) external onlyWhitelistedExecutors {\n DestinationUpdate storage destUpdate = updates[updateId];\n\n if (destUpdate.status != UpdateStatus.Pending) {\n revert UpdateNotFound();\n }\n\n destUpdate.status = UpdateStatus.Rejected;\n emit UpdateRejected(updateId);\n }\n\n /**\n * @notice Returns executable updates for a given update type and comptroller.\n * @param updateType The human‑readable identifier of the update type to filter by\n * @param comptroller The address of the Isolated Pools Comptroller that manages the markets\n * @return executableUpdates Array of update IDs that are ready to be executed\n */\n function getExecutableUpdates(\n string calldata updateType,\n address comptroller\n ) external view returns (uint256[] memory executableUpdates) {\n bytes32 updateTypeKey = keccak256(bytes(updateType));\n address[] memory markets = IIsolatedPoolsComptroller(comptroller).getAllMarkets();\n uint256 maxUpdates = markets.length;\n uint256[] memory tempArray = new uint256[](maxUpdates);\n uint256 count = 0;\n RiskParamConfig storage config = riskParameterConfigs[updateTypeKey];\n\n if (!config.active) return new uint256[](0);\n\n for (uint256 i = 0; i < maxUpdates; ++i) {\n address market = markets[i];\n uint256 registeredUpdateId = lastRegisteredUpdateId[updateTypeKey][market];\n DestinationUpdate storage destUpdate = updates[registeredUpdateId];\n\n if (!_checkPendingUpdate(registeredUpdateId)) continue;\n\n // Validate Remote Delay\n if (block.timestamp < destUpdate.arrivalTime + remoteDelay) continue;\n\n // Debounce: skip if last execution for this (updateType, market) is too recent\n uint256 lastExecutionTime = lastExecutedAt[updateTypeKey][market];\n if (lastExecutionTime != 0 && (lastExecutionTime + config.debounce > block.timestamp)) continue;\n\n tempArray[count] = registeredUpdateId;\n count++;\n }\n\n executableUpdates = new uint256[](count);\n for (uint256 i = 0; i < count; ++i) {\n executableUpdates[i] = tempArray[i];\n }\n }\n\n /**\n * @notice Returns the risk parameter configuration for a given update type\n * @param updateType The human-readable identifier of the update type\n * @return The risk parameter configuration\n */\n function getRiskParameterConfig(string calldata updateType) external view returns (RiskParamConfig memory) {\n bytes32 key = keccak256(bytes(updateType));\n return riskParameterConfigs[key];\n }\n\n /**\n * @notice Returns the registered update for a given update type and market\n * @param updateType The human-readable identifier of the update type\n * @param market The address of the market\n * @return The registered update\n */\n function getRegisteredUpdate(\n string calldata updateType,\n address market\n ) external view returns (DestinationUpdate memory) {\n bytes32 key = keccak256(bytes(updateType));\n uint256 updateId = lastRegisteredUpdateId[key][market];\n return updates[updateId];\n }\n\n /**\n * @notice Returns the last executed timestamp for a given update type and market\n * @param updateType The human-readable identifier of the update type\n * @param market The address of the market\n * @return The last executed timestamp\n */\n function getLastExecutedAt(string calldata updateType, address market) external view returns (uint256) {\n bytes32 key = keccak256(bytes(updateType));\n return lastExecutedAt[key][market];\n }\n\n /**\n * @dev Overrides OwnableUpgradeable and Ownable2StepUpgradeable to resolve\n * the multiple inheritance ownership transfer conflict.\n */\n function transferOwnership(\n address newOwner\n ) public override(OwnableUpgradeable, Ownable2StepUpgradeable) onlyOwner {\n Ownable2StepUpgradeable.transferOwnership(newOwner);\n }\n\n /**\n * @dev Internal hook to finalize ownership transfer, resolving the\n * OwnableUpgradeable and Ownable2StepUpgradeable inheritance conflict.\n */\n function _transferOwnership(address newOwner) internal override(OwnableUpgradeable, Ownable2StepUpgradeable) {\n Ownable2StepUpgradeable._transferOwnership(newOwner);\n }\n\n /**\n * @notice Internal LayerZero receive hook that handles bridged updates from the source-chain `RiskStewardReceiver`.\n * @dev Emits `DuplicateUpdateReceived`, `RegisteredPendingUpdateExist`, or `RemoteUpdateRegistered`\n * depending on whether the update ID was already seen or a non‑expired pending update exists.\n * @param payload Encoded `RiskParameterUpdate` sent from the source chain\n */\n function _lzReceive(Origin calldata, bytes32, bytes calldata payload, address, bytes calldata) internal override {\n RiskParameterUpdate memory update = abi.decode(payload, (RiskParameterUpdate));\n uint256 newId = update.updateId;\n uint256 arrivalTime = block.timestamp;\n\n // If this update ID was already stored, treat as a duplicate and do not overwrite\n if (updates[newId].status != UpdateStatus.None) {\n emit DuplicateUpdateReceived(newId, arrivalTime, update.updateType, update.market);\n return;\n }\n\n // If already an update in Process do not override the registered update\n uint256 currentRegisteredId = lastRegisteredUpdateId[update.updateTypeKey][update.market];\n if (_checkPendingUpdate(currentRegisteredId)) {\n emit RegisteredPendingUpdateExist(currentRegisteredId, arrivalTime, update.updateType, update.market);\n return;\n }\n\n DestinationUpdate storage destUpdate = updates[newId];\n destUpdate.update = update;\n destUpdate.status = UpdateStatus.Pending;\n destUpdate.arrivalTime = arrivalTime;\n lastRegisteredUpdateId[update.updateTypeKey][update.market] = newId;\n emit RemoteUpdateRegistered(newId, arrivalTime, update.updateType, update.market);\n }\n\n /**\n * @notice Checks whether a given registered update ID corresponds to a pending, non‑expired update.\n * @param currentRegisteredId The currently registered update ID for a specific (updateType, market) pair\n * @return True if currentRegisteredId is non‑zero, the update status is Pending, and it has not expired; otherwise false\n */\n function _checkPendingUpdate(uint256 currentRegisteredId) internal view returns (bool) {\n if (currentRegisteredId == 0) return false; // no registered update\n\n DestinationUpdate storage current = updates[currentRegisteredId];\n\n if (current.status != UpdateStatus.Pending) return false;\n\n // Check expiration\n return current.update.timestamp + REMOTE_UPDATE_EXPIRATION_TIME >= block.timestamp;\n }\n\n /**\n * @notice Disables renounceOwnership function\n * @custom:error Throws RenounceOwnershipNotAllowed\n */\n function renounceOwnership() public pure override {\n revert RenounceOwnershipNotAllowed();\n }\n}\n"
},
"contracts/RiskSteward/Interfaces/IDestinationStewardReceiver.sol": {
"content": "// SPDX-License-Identifier: BSD-3-Clause\npragma solidity 0.8.25;\n\nimport { RiskParameterUpdate } from \"./IRiskOracle.sol\";\n\ninterface IDestinationStewardReceiver {\n /**\n * @notice Local status of an update on the destination chain\n */\n enum UpdateStatus {\n None,\n Pending,\n Executed,\n Rejected\n }\n\n /**\n * @notice Configuration for a risk parameter update type on the destination chain.\n * @param active Whether this update type configuration is currently active\n * @param debounce Minimum delay between consecutive executions for the same (updateType, market) pair\n * @param riskSteward Address of the risk steward contract responsible for processing this update type\n */\n struct RiskParamConfig {\n bool active;\n uint256 debounce;\n address riskSteward;\n }\n\n /**\n * @notice Destination-side storage for a bridged risk parameter update.\n * @param update The full risk parameter update payload received from the source chain\n * @param status Current local status of the bridged update (Pending, Executed, Rejected)\n * @param arrivalTime Timestamp when the update was received on this chain\n * @param executor Address of the executor who executed this update on the destination (address(0) not executed yet)\n * @dev Unlock time is derived as `arrivalTime + remoteDelay` instead of being stored separately.\n */\n struct DestinationUpdate {\n RiskParameterUpdate update;\n UpdateStatus status;\n uint256 arrivalTime;\n address executor;\n }\n\n /**\n * @notice Emitted when a risk parameter config is updated for an update type\n */\n event RiskParameterConfigUpdated(\n bytes32 indexed updateTypeHash,\n string updateType,\n address indexed previousRiskSteward,\n address indexed riskSteward,\n uint256 previousDebounce,\n uint256 debounce,\n bool previousActive,\n bool active\n );\n\n /**\n * @notice Emitted when a bridged update is registered on the destination\n */\n event RemoteUpdateRegistered(\n uint256 indexed updateId,\n uint256 arrivalTime,\n string indexed updateType,\n address indexed market\n );\n\n /**\n * @notice Emitted when a new bridged update arrives but a pending update is already registered for the same (updateType, market).\n */\n event RegisteredPendingUpdateExist(\n uint256 indexed updateId,\n uint256 arrivalTime,\n string indexed updateType,\n address indexed market\n );\n\n /**\n * @notice Emitted when a duplicate bridged update (same updateId) is received.\n */\n event DuplicateUpdateReceived(\n uint256 indexed updateId,\n uint256 arrivalTime,\n string indexed updateType,\n address indexed market\n );\n\n /**\n * @notice Emitted when a bridged update is executed on the destination\n */\n event RemoteUpdateExecuted(uint256 indexed updateId);\n\n /**\n * @notice Emitted when an executor status is set on the destination\n */\n event ExecutorStatusUpdated(address indexed executor, bool previousApproved, bool approved);\n\n /**\n * @notice Emitted when a risk parameter config active status is updated\n */\n event ConfigActiveUpdated(\n bytes32 indexed updateTypeHash,\n string updateType,\n bool previousActive,\n bool indexed active\n );\n\n /**\n * @notice Emitted when an update is rejected on the destination\n */\n event UpdateRejected(uint256 indexed updateId);\n\n /**\n * @notice Emitted when the remote delay is set in the constructor\n */\n event RemoteDelaySet(uint256 remoteDelay);\n\n /**\n * @notice Thrown when trying to operate on an update that was never registered\n */\n error UpdateNotFound();\n\n /**\n * @notice Thrown when trying to execute an update before its unlock time\n */\n error UpdateNotUnlocked();\n\n /**\n * @notice Thrown when config for an update type is not active or not configured\n */\n error ConfigNotActive();\n\n /**\n * @notice Thrown when a bridged update has expired on the destination\n */\n error UpdateIsExpired();\n\n /**\n * @notice Thrown when the debounce period hasn't passed for applying an update to a specific market / update type\n */\n error UpdateTooFrequent();\n\n /**\n * @notice Thrown when an empty update type string is provided\n */\n error InvalidUpdateType();\n\n /**\n * @notice Thrown when an update type is not supported\n */\n error UnsupportedUpdateType();\n\n /**\n * @notice Thrown when a debounce value of 0 is set\n */\n error InvalidDebounce();\n\n /**\n * @notice Thrown when an address is not a whitelisted executor\n */\n error NotAnExecutor();\n\n /**\n * @notice Thrown when an invalid LayerZero endpoint ID is provided\n */\n error InvalidLayerZeroEid();\n\n /**\n * @notice Thrown when an invalid remote delay is provided\n */\n error InvalidRemoteDelay();\n\n /**\n * @notice Thrown when trying to set the same remote delay value\n */\n error RemoteDelayUnchanged();\n\n /**\n * @notice Thrown when trying to renounce ownership\n */\n error RenounceOwnershipNotAllowed();\n\n /**\n * @notice Thrown when trying to set the same config active status\n */\n error ConfigStatusUnchanged();\n\n /**\n * @notice Thrown when trying to set the same executor whitelist status\n */\n error ExecutorStatusUnchanged();\n\n function setRiskParameterConfig(string calldata updateType, address riskSteward, uint256 debounce) external;\n\n function setConfigActive(string calldata updateType, bool active) external;\n\n function setWhitelistedExecutor(address executor, bool approved) external;\n\n function setRemoteDelay(uint256 newRemoteDelay) external;\n\n function executeUpdate(uint256 updateId) external;\n\n function rejectUpdate(uint256 updateId) external;\n\n function getExecutableUpdates(\n string calldata updateType,\n address comptroller\n ) external view returns (uint256[] memory executableUpdates);\n\n function getRiskParameterConfig(string calldata updateType) external view returns (RiskParamConfig memory);\n\n function getRegisteredUpdate(\n string calldata updateType,\n address market\n ) external view returns (DestinationUpdate memory);\n\n function getLastExecutedAt(string calldata updateType, address market) external view returns (uint256);\n}\n"
},
"contracts/RiskSteward/Interfaces/IRiskOracle.sol": {
"content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.25;\n\n/**\n * @notice Struct representing a risk parameter update published by the Risk Oracle\n * @param referenceId External reference ID, potentially linking to a document or off-chain data\n * @param updateId Unique identifier for this specific update\n * @param market Address of the market for which the parameter update applies\n * @param updateType Classification of the update type for validation purposes (human-readable)\n * @param updateTypeKey Keccak256 hash of updateType for efficient comparisons\n * @param newValue Encoded new value of the risk parameter, flexible for various data types\n * @param previousValue Previous value of the parameter for historical comparison\n * @param timestamp Block timestamp when the update was published\n * @param publisher Address of the account that published this update\n * @param poolId Pool identifier for eMode-style collateral configuration (0 for regular markets)\n * @param destLzEid LayerZero endpoint ID of the destination chain (0 for local execution)\n * @param additionalData Additional metadata or data associated with the update\n */\nstruct RiskParameterUpdate {\n string referenceId;\n uint256 updateId;\n address market;\n string updateType;\n bytes32 updateTypeKey;\n bytes newValue;\n bytes previousValue;\n uint256 timestamp;\n address publisher;\n uint96 poolId;\n uint32 destLzEid;\n bytes additionalData;\n}\n\n/**\n * @title IRiskOracle\n * @author Venus\n * @notice Interface for Risk Oracle contract that manages and publishes risk parameter updates\n */\ninterface IRiskOracle {\n /// @notice Event emitted when a risk parameter update is published\n event UpdatePublished(\n string referenceId,\n uint256 indexed updateId,\n address indexed market,\n string indexed updateType,\n bytes newValue,\n bytes previousValue,\n uint256 timestamp,\n address publisher,\n bytes additionalData\n );\n\n /// @notice Event emitted when a new authorized sender is added\n event AuthorizedSenderAdded(address indexed sender);\n\n /// @notice Event emitted when an authorized sender is removed\n event AuthorizedSenderRemoved(address indexed sender);\n\n /// @notice Event emitted when a new update type is added\n event UpdateTypeAdded(string indexed updateType);\n\n /// @notice Event emitted when an update type's active status is changed\n event UpdateTypeActiveStatusChanged(string indexed updateType, bool previousActive, bool active);\n\n /// @notice Thrown when sender is not authorized\n error SenderNotAuthorized();\n\n /// @notice Thrown when sender is already authorized\n error SenderAlreadyAuthorized();\n\n /// @notice Thrown when update type string is invalid\n error InvalidUpdateTypeString();\n\n /// @notice Thrown when update type already exists\n error UpdateTypeAlreadyExists();\n\n /// @notice Thrown when update type doesn't exist\n error UpdateTypeNotFound();\n\n /// @notice Thrown when update type active status is already set to the desired value\n error UpdateTypeStatusUnchanged();\n\n /// @notice Thrown when update type is not active\n error UpdateTypeNotActive();\n\n /// @notice Thrown when no update is found\n error NoUpdateFound();\n\n /// @notice Thrown when update ID is invalid\n error InvalidUpdateId();\n\n /// @notice Thrown when array lengths don't match in bulk operations\n error ArrayLengthMismatch();\n\n /// @notice Thrown when trying to renounce ownership\n error RenounceOwnershipNotAllowed();\n\n /**\n * @notice Returns the update type string at the given index in the allUpdateTypes array\n * @param index The index in the allUpdateTypes array\n * @return The update type string at the specified index\n */\n function allUpdateTypes(uint256 index) external view returns (string memory);\n\n /**\n * @notice Returns the total number of update types in the allUpdateTypes array\n * @return The length of the allUpdateTypes array\n */\n function allUpdateTypesLength() external view returns (uint256);\n\n /**\n * @notice Returns all update types in the allUpdateTypes array\n * @return An array of all update type strings\n */\n function getAllUpdateTypes() external view returns (string[] memory);\n\n /**\n * @notice Checks if a given update type is currently active\n * @param updateType The update type string to check\n * @return True if the update type is active, false otherwise\n */\n function getActiveUpdateTypes(string memory updateType) external view returns (bool);\n\n /**\n * @notice Checks if a given update type is currently active\n * @param updateTypeKey The keccak256 hash of the update type string\n * @return True if the update type key is active, false otherwise\n */\n function activeUpdateTypes(bytes32 updateTypeKey) external view returns (bool);\n\n /**\n * @notice Checks if an address is authorized to publish updates\n * @param sender The address to check for authorization\n * @return True if the address is authorized, false otherwise\n */\n function authorizedSenders(address sender) external view returns (bool);\n\n /**\n * @notice Gets the latest update ID for a specific market and update type combination\n * @param updateTypeKey The keccak256 hash of the update type string\n * @param market The market address\n * @return The latest update ID for the given market and update type key, or 0 if none exists\n */\n function latestUpdateIdByMarketAndType(bytes32 updateTypeKey, address market) external view returns (uint256);\n\n /**\n * @notice Returns the total number of updates that have been published\n * @return The current update counter value\n */\n function updateCounter() external view returns (uint256);\n\n /**\n * @notice Fetches the most recent update for a specific parameter type in a specific market\n * @param updateType The update type identifier\n * @param market The market address\n * @return The most recent RiskParameterUpdate for the specified parameter and market\n * @custom:error NoUpdateFound Thrown if no update exists for the specified parameter and market\n */\n function getLatestUpdateByMarketAndType(\n string memory updateType,\n address market\n ) external view returns (RiskParameterUpdate memory);\n\n /**\n * @notice Gets the latest update ID for a specific market and update type (string) combination\n * @param updateType The update type identifier\n * @param market The market address\n * @return The latest update ID for the given market and update type, or 0 if none exists\n */\n function getLatestUpdateIdByMarketAndType(string memory updateType, address market) external view returns (uint256);\n\n /**\n * @notice Fetches the update for a provided update ID\n * @param updateId The unique update ID\n * @return The RiskParameterUpdate struct for the specified update ID\n * @custom:error InvalidUpdateId Thrown if updateId is 0 or greater than updateCounter\n */\n function getUpdateById(uint256 updateId) external view returns (RiskParameterUpdate memory);\n\n /**\n * @notice Adds a new address to the list of authorized senders who can publish updates\n * @param sender Address to be authorized\n * @custom:error ZeroAddressNotAllowed Thrown if sender is the zero address\n * @custom:error SenderAlreadyAuthorized Thrown if sender is already authorized\n * @custom:error Unauthorized Thrown if caller is not allowed by AccessControlManager\n * @custom:event AuthorizedSenderAdded Emitted when sender is successfully added\n */\n function addAuthorizedSender(address sender) external;\n\n /**\n * @notice Removes an address from the list of authorized senders\n * @param sender Address to be removed from authorization\n * @custom:error SenderNotAuthorized Thrown if sender is not currently authorized\n * @custom:error Unauthorized Thrown if caller is not allowed by AccessControlManager\n * @custom:event AuthorizedSenderRemoved Emitted when sender is successfully removed\n */\n function removeAuthorizedSender(address sender) external;\n\n /**\n * @notice Adds a new update type to the list of authorized update types\n * @param newUpdateType New update type string to allow (must be non-empty and <= 64 characters)\n * @custom:error InvalidUpdateTypeString Thrown if update type string is empty or exceeds 64 characters\n * @custom:error UpdateTypeAlreadyExists Thrown if update type already exists\n * @custom:error Unauthorized Thrown if caller is not allowed by AccessControlManager\n * @custom:event UpdateTypeAdded Emitted when update type is successfully added\n */\n function addUpdateType(string memory newUpdateType) external;\n\n /**\n * @notice Sets the active status of an existing update type\n * @param updateType The update type to set active status for\n * @param active True to activate the update type, false to deactivate it\n * @custom:error UpdateTypeNotFound Thrown if update type doesn't exist\n * @custom:error UpdateTypeStatusUnchanged Thrown if status is already set to the desired value\n * @custom:error Unauthorized Thrown if caller is not allowed by AccessControlManager\n * @custom:event UpdateTypeActiveStatusChanged Emitted when status is successfully changed\n */\n function setUpdateTypeActive(string memory updateType, bool active) external;\n\n /**\n * @notice Publishes a new risk parameter update.\n * @param referenceId An external reference ID associated with the update\n * @param newValue The new value of the risk parameter being updated (encoded as bytes)\n * @param updateType Type of update performed, must be an active update type\n * @param market Address of the market for which the parameter update applies\n * @param poolId Pool identifier for eMode-style collateral configuration (0 for regular markets)\n * @param dstEid Destination endpoint ID for cross-chain routing\n * @param additionalData Additional data or metadata for the update\n * @custom:error SenderNotAuthorized Thrown if caller is not an authorized sender\n * @custom:error UpdateTypeNotActive Thrown if update type is not active\n * @custom:error ZeroAddressNotAllowed Thrown if market is the zero address\n * @custom:event UpdatePublished Emitted when the update is successfully published\n */\n function publishRiskParameterUpdate(\n string memory referenceId,\n bytes memory newValue,\n string memory updateType,\n address market,\n uint96 poolId,\n uint32 dstEid,\n bytes memory additionalData\n ) external;\n\n /**\n * @notice Publishes multiple risk parameter updates in a single transaction.\n * @param referenceIds Array of external reference IDs, one for each update\n * @param newValues Array of new values for each update (encoded as bytes)\n * @param updateTypes Array of update types, all must be active update types\n * @param markets Array of market addresses for each update\n * @param poolIds Array of pool identifiers for eMode-style collateral configuration (0 for regular markets)\n * @param dstEid Array of destination endpoint IDs for cross-chain routing\n * @param additionalData Array of additional data for each update\n * @custom:error SenderNotAuthorized Thrown if caller is not an authorized sender\n * @custom:error ArrayLengthMismatch Thrown if all arrays don't have the same length\n * @custom:error UpdateTypeNotActive Thrown if any update type is not active\n * @custom:error ZeroAddressNotAllowed Thrown if any market is the zero address\n * @custom:event UpdatePublished Emitted for each successfully published update\n */\n function publishBulkRiskParameterUpdates(\n string[] memory referenceIds,\n bytes[] memory newValues,\n string[] memory updateTypes,\n address[] memory markets,\n uint96[] memory poolIds,\n uint32[] memory dstEid,\n bytes[] memory additionalData\n ) external;\n}\n"
},
"contracts/RiskSteward/Interfaces/IRiskSteward.sol": {
"content": "// SPDX-License-Identifier: BSD-3-Clause\npragma solidity 0.8.25;\n\nimport { RiskParameterUpdate } from \"./IRiskOracle.sol\";\nimport { IRiskStewardReceiver } from \"./IRiskStewardReceiver.sol\";\n\n/**\n * @title IRiskSteward\n * @author Venus\n * @notice Interface for risk stewards that validate and apply risk parameter updates\n */\ninterface IRiskSteward {\n /**\n * @notice Returns the `IRiskStewardReceiver` associated with this steward.\n * @return The risk steward receiver contract\n */\n function RISK_STEWARD_RECEIVER() external view returns (IRiskStewardReceiver);\n\n /**\n * @notice Checks whether an update is safe for direct execution (no timelock required).\n * @param update The risk parameter update to evaluate\n * @return True if update is safe for direct execution, false if timelock is required\n */\n function isSafeForDirectExecution(RiskParameterUpdate calldata update) external view returns (bool);\n\n /**\n * @notice Applies a validated risk parameter update.\n * @param update The risk parameter update to apply\n */\n function applyUpdate(RiskParameterUpdate calldata update) external;\n}\n"
},
"contracts/RiskSteward/Interfaces/IRiskStewardReceiver.sol": {
"content": "// SPDX-License-Identifier: BSD-3-Clause\npragma solidity 0.8.25;\n\ninterface IRiskStewardReceiver {\n /**\n * @notice Status of an update\n */\n enum UpdateStatus {\n None,\n Pending,\n Executed,\n Rejected,\n Expired,\n SENT_TO_DESTINATION\n }\n\n /**\n * @notice Configuration for a risk parameter update type\n * @param active Whether this update type configuration is currently active\n * @param debounce Minimum delay between consecutive update executions for the same (updateType, market) pair\n * @param timelock Period that must pass after registration before an update can be executed\n * @param riskSteward Address of the risk steward contract responsible for processing this update type\n */\n struct RiskParamConfig {\n bool active;\n uint256 debounce;\n uint256 timelock;\n address riskSteward;\n }\n\n /**\n * @notice Registered update structure with timelock and execution information\n * @param updateId Update ID from the Risk Oracle\n * @param unlockTime Timestamp when this update can be executed (calculated as registration time + timelock)\n * @param status Current status of the update (Pending, Executed, Rejected, Expired, etc.)\n * @param executor Address of the executor who executed this update (address(0) if not executed yet)\n * @param executedAt Timestamp when this update was executed (0 if not executed yet)\n */\n struct RegisteredUpdate {\n uint256 updateId;\n uint256 unlockTime;\n UpdateStatus status;\n address executor;\n uint256 executedAt;\n }\n\n /**\n * @notice Event emitted when a risk parameter config is set\n */\n event RiskParameterConfigUpdated(\n bytes32 indexed updateTypeHash,\n string updateType,\n address indexed previousRiskSteward,\n address indexed riskSteward,\n uint256 previousDebounce,\n uint256 debounce,\n uint256 previousTimelock,\n uint256 timelock,\n bool previousActive,\n bool active\n );\n\n /**\n * @notice Event emitted when a risk parameter config active status is set\n */\n event ConfigActiveUpdated(bytes32 indexed updateTypeHash, string updateType, bool previousActive, bool active);\n\n /**\n * @notice Event emitted when an update is successfully executed\n */\n event UpdateExecuted(uint256 indexed updateId);\n\n /**\n * @notice Event emitted when an update is rejected\n */\n event UpdateRejected(uint256 indexed updateId);\n\n /**\n * @notice Event emitted when an update is marked as expired\n */\n event UpdateExpired(uint256 indexed updateId);\n\n /**\n * @notice Event emitted when an executor status is set\n */\n event ExecutorStatusUpdated(address indexed executor, bool previousApproved, bool approved);\n\n /**\n * @notice Event emitted when an update is registered\n */\n event UpdateRegistered(uint256 indexed updateId, uint256 unlockTime, string updateType, address indexed market);\n\n /**\n * @notice Event emitted when an update is sent to a destination chain\n */\n event UpdateSentToDestination(\n uint256 updateId,\n uint32 indexed destLzEid,\n string indexed updateType,\n address indexed market\n );\n\n /**\n * @notice Event emitted when an update is resent to a destination chain\n */\n event UpdateResentToDestination(\n uint256 updateId,\n uint32 indexed destLzEid,\n string indexed updateType,\n address indexed market\n );\n\n /**\n * @notice Emitted when leftover native tokens are swept by owner\n */\n event SweepNative(address indexed receiver, uint256 amount);\n\n /**\n * @notice Event emitted when the pause status changes\n * @param previousPaused Previous pause state\n * @param paused Current pause state\n */\n event PauseStatusUpdated(bool previousPaused, bool paused);\n\n /**\n * @custom:error TransferFailed\n */\n error TransferFailed();\n\n /**\n * @notice Thrown if a submitted update is not active and therefore cannot be processed\n */\n error ConfigNotActive();\n\n /**\n * @notice Thrown when an update was not applied within the required time frame\n */\n error UpdateIsExpired();\n\n /**\n * @notice Thrown when an update has already been processed\n */\n error UpdateAlreadyResolved();\n\n /**\n * @notice Thrown when the debounce period hasn't passed for applying an update to a specific market / update type\n */\n error UpdateTooFrequent();\n\n /**\n * @notice Thrown when an update type that is not supported is operated on\n */\n error UnsupportedUpdateType();\n\n /**\n * @notice Thrown when an empty update type string is provided\n */\n error InvalidUpdateType();\n\n /**\n * @notice Thrown when a debounce value of 0 is set\n */\n error InvalidDebounce();\n\n /**\n * @notice Thrown when a timelock value is greater than or equal to the expiration time\n */\n error InvalidTimelock();\n\n /**\n * @notice Thrown when update unlock time has not been reached\n */\n error UpdateNotUnlocked();\n\n /**\n * @notice Thrown when trying to resolve an update that doesn't exist\n */\n error UpdateNotFound();\n\n /**\n * @notice Thrown when an address is not an executor\n */\n error NotAnExecutor();\n\n /**\n * @notice Thrown when there is a non-expired pending update of the same type for the market\n */\n error RegisteredUpdateTypeExist(uint256);\n\n /**\n * @notice Thrown when trying to resend an update that is not in SENT_TO_DESTINATION status\n */\n error InvalidUpdateToResend();\n\n /**\n * @notice Thrown when trying to execute an update that was never registered\n */\n error InvalidRegisteredUpdate();\n\n /**\n * @notice Thrown when attempting to call lzSend from an address other than this contract\n */\n error InvalidLzSendCaller();\n\n /**\n * @notice Thrown when trying to renounce ownership\n */\n error RenounceOwnershipNotAllowed();\n\n /**\n * @notice Thrown when trying to receive LayerZero messages\n */\n error LayerZeroReceiveNotAllowed();\n\n /**\n * @notice Thrown when processUpdate is called while the contract is paused\n */\n error PausedError();\n\n /**\n * @notice Thrown when an invalid LayerZero endpoint ID is provided\n */\n error InvalidLayerZeroEid();\n\n /**\n * @notice Thrown when trying to set the same pause status\n */\n error PauseStatusUnchanged();\n\n /**\n * @notice Thrown when trying to set the same config active status\n */\n error ConfigStatusUnchanged();\n\n /**\n * @notice Thrown when trying to set the same executor whitelist status\n */\n error ExecutorStatusUnchanged();\n\n /**\n * @notice Thrown when an update will expire before its timelock unlocks\n */\n error UpdateWillExpireBeforeUnlock();\n\n function getRiskParameterConfig(string calldata updateType) external view returns (RiskParamConfig memory);\n\n function getLastProcessedUpdate(string calldata updateType, address market) external view returns (uint256);\n\n function getLastRegisteredUpdate(string calldata updateType, address market) external view returns (uint256);\n\n function setRiskParameterConfig(\n string calldata updateType,\n address riskSteward,\n uint256 debounce,\n uint256 timelock\n ) external;\n\n function setConfigActive(string calldata updateType, bool active) external;\n\n function setWhitelistedExecutor(address executor, bool approved) external;\n\n function processUpdate(uint256 updateId) external;\n\n function executeRegisteredUpdate(uint256 updateId) external;\n\n function rejectUpdate(uint256 updateId) external;\n\n function resendRemoteUpdate(uint256 updateId, bytes calldata options) external payable;\n\n function getExecutableUpdates(\n string calldata updateType,\n address comptroller\n ) external view returns (uint256[] memory executableUpdates);\n\n function isUpdateExecutable(uint256 updateId) external view returns (bool);\n}\n"
},
"contracts/RiskSteward/IRMRiskSteward.sol": {
"content": "// SPDX-License-Identifier: BSD-3-Clause\npragma solidity 0.8.25;\n\nimport { RiskParameterUpdate } from \"./Interfaces/IRiskOracle.sol\";\nimport { ICorePoolVToken } from \"../interfaces/ICorePoolVToken.sol\";\nimport { IIsolatedPoolVToken } from \"../interfaces/IIsolatedPoolVToken.sol\";\nimport { InterestRateModel } from \"@venusprotocol/isolated-pools/contracts/InterestRateModel.sol\";\nimport { InterestRateModelV8 } from \"@venusprotocol/venus-protocol/contracts/InterestRateModels/InterestRateModelV8.sol\";\nimport { ICorePoolComptroller } from \"../interfaces/ICorePoolComptroller.sol\";\nimport { IRiskStewardReceiver } from \"./Interfaces/IRiskStewardReceiver.sol\";\nimport { BaseRiskSteward } from \"./BaseRiskSteward.sol\";\nimport { ensureNonzeroAddress } from \"@venusprotocol/solidity-utilities/contracts/validators.sol\";\n\n/**\n * @title IRMRiskSteward\n * @author Venus\n * @notice Contract that can update interest rate models updates received from RiskStewardReceiver.\n * @custom:security-contact https://github.com/VenusProtocol/governance-contracts#discussion\n */\ncontract IRMRiskSteward is BaseRiskSteward {\n /**\n * @notice The update type for interest rate model\n */\n string public constant INTEREST_RATE_MODEL = \"interestRateModel\";\n\n /**\n * @notice The update type key for interest rate model (keccak256 hash of INTEREST_RATE_MODEL)\n */\n bytes32 public constant INTEREST_RATE_MODEL_KEY = keccak256(bytes(INTEREST_RATE_MODEL));\n\n /**\n * @notice Address of the BNB Core Pool Comptroller.\n * @dev This comptroller is specific to the BNB Core Pool, which uses a different ABI\n * than isolated pools. It is used solely to detect and handle BNB Core Pool\n * markets, and would not be used for remote-chain (isolated pool) deployments.\n */\n ICorePoolComptroller public immutable CORE_POOL_COMPTROLLER;\n\n /**\n * @notice Address of the RiskStewardReceiver used to validate incoming updates\n */\n IRiskStewardReceiver public immutable RISK_STEWARD_RECEIVER;\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n\n /**\n * @notice Emitted when an interest rate model is updated\n */\n event InterestRateModelUpdated(\n uint256 indexed updateId,\n address indexed market,\n address indexed newInterestRateModel\n );\n\n /**\n * @notice Thrown when an update type that is not supported is operated on\n */\n error UnsupportedUpdateType();\n\n /**\n * @notice Thrown when attempting to apply a redundant IRM value (no-op change).\n */\n error RedundantValue();\n\n /**\n * @notice Thrown when the update is not coming from the RiskStewardReceiver\n */\n error OnlyRiskStewardReceiver();\n\n /**\n * @notice Thrown when the address length is invalid\n */\n error InvalidAddressLength();\n\n /**\n * @notice Thrown when Core Pool VToken._setInterestRateModel fails.\n */\n error SetInterestRateModelFailed(uint256 errorCode);\n\n /**\n * @notice Sets the immutable CORE_POOL_COMPTROLLER and RISK_STEWARD_RECEIVER addresses and disables initializers\n * @param corePoolComptroller_ The address of the Core Pool Comptroller\n * @param riskStewardReceiver_ The address of the RiskStewardReceiver\n * @custom:error Throws ZeroAddressNotAllowed if any of the addresses are zero\n * @custom:oz-upgrades-unsafe-allow constructor\n */\n constructor(address corePoolComptroller_, address riskStewardReceiver_) {\n ensureNonzeroAddress(riskStewardReceiver_);\n CORE_POOL_COMPTROLLER = ICorePoolComptroller(corePoolComptroller_);\n RISK_STEWARD_RECEIVER = IRiskStewardReceiver(riskStewardReceiver_);\n _disableInitializers();\n }\n\n /**\n * @notice Initializes the contract as ownable and access controlled.\n * @param accessControlManager_ The address of the access control manager\n */\n function initialize(address accessControlManager_) external initializer {\n __AccessControlled_init(accessControlManager_);\n }\n\n /**\n * @notice Applies an interest rate model update from the RiskStewardReceiver.\n * Directly updates the market interest rate model on the vToken.\n * @param update RiskParameterUpdate update to apply\n * @custom:error Throws OnlyRiskStewardReceiver if the sender is not the RiskStewardReceiver\n * @custom:error Throws UnsupportedUpdateType if the update type is not supported\n * @custom:event Emits InterestRateModelUpdated with the updateId, market and new IRM address\n * @custom:access Only callable by the RiskStewardReceiver\n */\n function applyUpdate(RiskParameterUpdate calldata update) external {\n if (msg.sender != address(RISK_STEWARD_RECEIVER)) {\n revert OnlyRiskStewardReceiver();\n }\n\n if (update.updateTypeKey == INTEREST_RATE_MODEL_KEY) {\n address newIRM = _decodeAbiEncodedAddress(update.newValue);\n _updateIRM(update.updateId, update.market, newIRM);\n } else {\n revert UnsupportedUpdateType();\n }\n }\n\n /**\n * @notice Checks if an update is safe for direct execution (no timelock required)\n * @param update The update to check\n * @return True if update is safe for direct execution, false if timelock is required\n * @custom:error Throws UnsupportedUpdateType if the update type is not supported\n * @dev For IRM updates, always returns false as we cannot compare IRM values\n */\n function isSafeForDirectExecution(RiskParameterUpdate calldata update) external view returns (bool) {\n if (update.updateTypeKey != INTEREST_RATE_MODEL_KEY) {\n revert UnsupportedUpdateType();\n }\n\n address newIRM = _decodeAbiEncodedAddress(update.newValue);\n address currentIRM = address(ICorePoolVToken(update.market).interestRateModel());\n\n // Revert on redundant updates\n if (newIRM == currentIRM) {\n revert RedundantValue();\n }\n\n // Always require timelock (not safe for direct execution)\n return false;\n }\n\n /**\n * @notice Updates the interest rate model for the given market.\n * @param updateId The update ID from the Risk Oracle\n * @param market The market to update the interest rate model for\n * @param newIRM The new interest rate model address\n * @custom:error Throws SetInterestRateModelFailed if the core pool vToken call to _setInterestRateModel returns a non-zero error code\n * @custom:event Emits InterestRateModelUpdated with the updateId, market and new IRM address\n */\n function _updateIRM(uint256 updateId, address market, address newIRM) internal {\n address comptroller = ICorePoolVToken(market).comptroller();\n\n if (comptroller == address(CORE_POOL_COMPTROLLER)) {\n uint256 errorCode = ICorePoolVToken(market)._setInterestRateModel(InterestRateModelV8(newIRM));\n if (errorCode != 0) revert SetInterestRateModelFailed(errorCode);\n } else {\n IIsolatedPoolVToken(market).setInterestRateModel(InterestRateModel(newIRM));\n }\n\n emit InterestRateModelUpdated(updateId, market, newIRM);\n }\n\n /**\n * @notice Decodes ABI-encoded bytes into an address.\n * @dev Expects exactly 32 bytes as produced by abi.encode(address).\n * @param data ABI-encoded address payload (32 bytes)\n * @return The decoded address\n * @custom:error Throws InvalidAddressLength if data length is not 32 bytes\n */\n function _decodeAbiEncodedAddress(bytes memory data) internal pure returns (address) {\n if (data.length != 32) revert InvalidAddressLength();\n return abi.decode(data, (address));\n }\n}\n"
},
"contracts/RiskSteward/MarketCapsRiskSteward.sol": {
"content": "// SPDX-License-Identifier: BSD-3-Clause\npragma solidity 0.8.25;\n\nimport { RiskParameterUpdate } from \"./Interfaces/IRiskOracle.sol\";\nimport { ICorePoolVToken } from \"../interfaces/ICorePoolVToken.sol\";\nimport { ICorePoolComptroller } from \"../interfaces/ICorePoolComptroller.sol\";\nimport { IRiskStewardReceiver } from \"./Interfaces/IRiskStewardReceiver.sol\";\nimport { BaseRiskSteward } from \"./BaseRiskSteward.sol\";\nimport { ensureNonzeroAddress } from \"@venusprotocol/solidity-utilities/contracts/validators.sol\";\n\n/**\n * @title MarketCapsRiskSteward\n * @author Venus\n * @notice Contract that can update supply and borrow caps updates received from RiskStewardReceiver.\n * @custom:security-contact https://github.com/VenusProtocol/governance-contracts#discussion\n */\ncontract MarketCapsRiskSteward is BaseRiskSteward {\n /**\n * @notice The update type for supply caps\n */\n string public constant SUPPLY_CAP = \"supplyCap\";\n\n /**\n * @notice The update type key for supply caps (keccak256 hash of SUPPLY_CAP)\n */\n bytes32 public constant SUPPLY_CAP_KEY = keccak256(bytes(SUPPLY_CAP));\n\n /**\n * @notice The update type for borrow caps\n */\n string public constant BORROW_CAP = \"borrowCap\";\n\n /**\n * @notice The update type key for borrow caps (keccak256 hash of BORROW_CAP)\n */\n bytes32 public constant BORROW_CAP_KEY = keccak256(bytes(BORROW_CAP));\n\n /**\n * @notice Address of the RiskStewardReceiver used to validate incoming updates\n */\n IRiskStewardReceiver public immutable RISK_STEWARD_RECEIVER;\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n\n /**\n * @notice Emitted when a supply cap is updated\n */\n event SupplyCapUpdated(uint256 indexed updateId, address indexed market, uint256 newSupplyCap);\n\n /**\n * @notice Emitted when a borrow cap is updated\n */\n event BorrowCapUpdated(uint256 indexed updateId, address indexed market, uint256 newBorrowCap);\n\n /**\n * @notice Emitted when the safe delta bps is updated\n */\n event SafeDeltaBpsUpdated(uint256 oldSafeDeltaBps, uint256 newSafeDeltaBps);\n\n /**\n * @notice Thrown when a safeDeltaBps value is greater than MAX_BPS\n */\n error InvalidSafeDeltaBps();\n\n /**\n * @notice Thrown when an update type that is not supported is operated on\n */\n error UnsupportedUpdateType();\n\n /**\n * @notice Thrown when the update is not coming from the RiskStewardReceiver\n */\n error OnlyRiskStewardReceiver();\n\n /**\n * @notice Thrown when the uint256 data length is invalid\n */\n error InvalidUintLength();\n\n /**\n * @notice Thrown when attempting to apply a redundant value (no-op change).\n */\n error RedundantValue();\n\n /**\n * @notice Sets the immutable RiskStewardReceiver address and disables initializers\n * @param riskStewardReceiver_ The address of the RiskStewardReceiver\n * @custom:error Throws ZeroAddressNotAllowed if the RiskStewardReceiver address is zero\n * @custom:oz-upgrades-unsafe-allow constructor\n */\n constructor(address riskStewardReceiver_) {\n ensureNonzeroAddress(riskStewardReceiver_);\n RISK_STEWARD_RECEIVER = IRiskStewardReceiver(riskStewardReceiver_);\n _disableInitializers();\n }\n\n /**\n * @notice Initializes the contract as ownable and access controlled.\n * @param accessControlManager_ The address of the access control manager\n */\n function initialize(address accessControlManager_) external initializer {\n __AccessControlled_init(accessControlManager_);\n }\n\n /**\n * @notice Sets the safe delta bps\n * @param safeDeltaBps_ The new safe delta bps\n * @custom:access Controlled by AccessControlManager\n * @custom:event Emits SafeDeltaBpsUpdated with the old and new safe delta bps\n * @custom:error Throws InvalidSafeDeltaBps if the safe delta bps is greater than MAX_BPS\n */\n function setSafeDeltaBps(uint256 safeDeltaBps_) external {\n _checkAccessAllowed(\"setSafeDeltaBps(uint256)\");\n if (safeDeltaBps_ > MAX_BPS) {\n revert InvalidSafeDeltaBps();\n }\n uint256 oldSafeDeltaBps = safeDeltaBps;\n if (safeDeltaBps_ == oldSafeDeltaBps) {\n revert InvalidSafeDeltaBps();\n }\n safeDeltaBps = safeDeltaBps_;\n emit SafeDeltaBpsUpdated(oldSafeDeltaBps, safeDeltaBps_);\n }\n\n /**\n * @notice Checks if an update is safe for direct execution (no timelock required)\n * @param update The update to check\n * @return True if update is safe for direct execution, false if timelock is required\n * @custom:error Throws UnsupportedUpdateType if the update type is not supported\n */\n function isSafeForDirectExecution(RiskParameterUpdate calldata update) external view returns (bool) {\n uint256 newValue = _decodeAbiEncodedUint256(update.newValue);\n // Use the core pool comptroller interface here because the getter used below has the same signature for both core and isolated pools.\n ICorePoolComptroller comptroller = ICorePoolComptroller(ICorePoolVToken(update.market).comptroller());\n uint256 currentValue;\n\n if (update.updateTypeKey == SUPPLY_CAP_KEY) {\n currentValue = comptroller.supplyCaps(update.market);\n } else if (update.updateTypeKey == BORROW_CAP_KEY) {\n currentValue = comptroller.borrowCaps(update.market);\n } else {\n revert UnsupportedUpdateType();\n }\n\n // Revert on redundant updates\n if (newValue == currentValue) {\n revert RedundantValue();\n }\n\n // If current value is 0, always require timelock (not safe for direct execution)\n if (currentValue == 0) {\n return false;\n }\n\n // Return true if difference is within safe delta (safe for direct execution)\n return _isWithinSafeDelta(newValue, currentValue);\n }\n\n /**\n * @notice Applies a market cap update from the RiskStewardReceiver.\n * Directly updates the market supply or borrow cap on the market's comptroller.\n * @custom:access Only callable by the RiskStewardReceiver\n * @param update RiskParameterUpdate update to apply\n * @custom:event Emits SupplyCapUpdated or BorrowCapUpdated depending on the update with the updateId, market and new cap\n * @custom:error Throws OnlyRiskStewardReceiver if the sender is not the RiskStewardReceiver\n * @custom:error Throws UnsupportedUpdateType if the update type is not supported\n */\n function applyUpdate(RiskParameterUpdate calldata update) external {\n if (msg.sender != address(RISK_STEWARD_RECEIVER)) {\n revert OnlyRiskStewardReceiver();\n }\n uint256 newValue = _decodeAbiEncodedUint256(update.newValue);\n\n if (update.updateTypeKey == SUPPLY_CAP_KEY) {\n _updateSupplyCaps(update.updateId, update.market, newValue);\n } else if (update.updateTypeKey == BORROW_CAP_KEY) {\n _updateBorrowCaps(update.updateId, update.market, newValue);\n } else {\n revert UnsupportedUpdateType();\n }\n }\n\n /**\n * @notice Updates the supply cap for the given market.\n * @param updateId The update ID from the Risk Oracle\n * @param market The market to update the supply cap for\n * @param newValue The new supply cap value\n * @custom:event Emits SupplyCapUpdated with the updateId, market and new supply cap\n */\n function _updateSupplyCaps(uint256 updateId, address market, uint256 newValue) internal {\n address comptroller = ICorePoolVToken(market).comptroller();\n address[] memory newSupplyCapMarkets = new address[](1);\n newSupplyCapMarkets[0] = market;\n uint256[] memory newSupplyCaps = new uint256[](1);\n newSupplyCaps[0] = newValue;\n\n // Core and isolated pools share the same `setMarketSupplyCaps` signature.\n ICorePoolComptroller(comptroller).setMarketSupplyCaps(newSupplyCapMarkets, newSupplyCaps);\n emit SupplyCapUpdated(updateId, market, newSupplyCaps[0]);\n }\n\n /**\n * @notice Updates the borrow cap for the given market.\n * @param updateId The update ID from the Risk Oracle\n * @param market The market to update the borrow cap for\n * @param newValue The new borrow cap value\n * @custom:event Emits BorrowCapUpdated with the updateId, market and new borrow cap\n */\n function _updateBorrowCaps(uint256 updateId, address market, uint256 newValue) internal {\n address comptroller = ICorePoolVToken(market).comptroller();\n address[] memory newBorrowCapMarkets = new address[](1);\n newBorrowCapMarkets[0] = market;\n uint256[] memory newBorrowCaps = new uint256[](1);\n newBorrowCaps[0] = newValue;\n\n //Core and isolated pools share the same `setMarketBorrowCaps` signature,\n ICorePoolComptroller(comptroller).setMarketBorrowCaps(newBorrowCapMarkets, newBorrowCaps);\n emit BorrowCapUpdated(updateId, market, newBorrowCaps[0]);\n }\n\n /**\n * @notice Decodes ABI-encoded bytes into a uint256.\n * @dev Expects exactly 32 bytes as produced by abi.encode(uint256).\n * @param data ABI-encoded uint256 payload (32 bytes)\n * @return value Decoded uint256\n */\n function _decodeAbiEncodedUint256(bytes memory data) internal pure returns (uint256 value) {\n if (data.length != 32) {\n revert InvalidUintLength();\n }\n\n value = abi.decode(data, (uint256));\n }\n}\n"
},
"contracts/RiskSteward/RiskOracle.sol": {
"content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.25;\n\nimport { AccessControlledV8 } from \"../Governance/AccessControlledV8.sol\";\nimport { ensureNonzeroAddress } from \"@venusprotocol/solidity-utilities/contracts/validators.sol\";\nimport { IRiskOracle, RiskParameterUpdate } from \"./Interfaces/IRiskOracle.sol\";\n\n/**\n * @title Risk Oracle\n * @author Venus\n * @notice Contract for managing and publishing risk parameter updates for Risk-Steward Updates\n */\ncontract RiskOracle is IRiskOracle, AccessControlledV8 {\n /// @notice Counter to keep track of the total number of updates\n uint256 public updateCounter;\n\n /// @notice Array to store all update types\n string[] public allUpdateTypes;\n\n /// @notice Whitelist of valid update type identifiers, keyed by updateType hash\n mapping(bytes32 => bool) public activeUpdateTypes;\n\n /// @notice Mapping from unique update ID to the update details\n mapping(uint256 => RiskParameterUpdate) public updatesById;\n\n /// @notice Authorized accounts capable of proposing updates\n mapping(address => bool) public authorizedSenders;\n\n /// @notice Mapping to store the latest update ID for each combination of update type key and market\n mapping(bytes32 => mapping(address => uint256)) public latestUpdateIdByMarketAndType;\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[44] private __gap;\n\n /**\n * @notice Modifier that restricts function access to authorized senders only\n */\n modifier onlyAuthorized() {\n if (!authorizedSenders[msg.sender]) {\n revert SenderNotAuthorized();\n }\n _;\n }\n\n /**\n * @notice Disables initializers\n * @custom:oz-upgrades-unsafe-allow constructor\n */\n constructor() {\n _disableInitializers();\n }\n\n /**\n * @notice Initializes the contract with access control manager\n * @param accessControlManager_ Address of the access control manager\n * @custom:error Reverts with \"invalid acess control manager address\" if accessControlManager_ is zero address\n */\n function initialize(address accessControlManager_) external initializer {\n __AccessControlled_init(accessControlManager_);\n }\n\n /**\n * @notice Adds a new sender to the list of addresses authorized to perform updates\n * @param sender Address to be authorized\n * @custom:access Controlled by AccessControlManager\n * @custom:error Throws ZeroAddressNotAllowed if sender is zero address\n * @custom:error Throws SenderAlreadyAuthorized if sender is already authorized\n * @custom:error Throws Unauthorized if caller is not allowed by AccessControlManager\n * @custom:event Emits AuthorizedSenderAdded when sender is successfully added\n */\n function addAuthorizedSender(address sender) external {\n _checkAccessAllowed(\"addAuthorizedSender(address)\");\n ensureNonzeroAddress(sender);\n if (authorizedSenders[sender]) {\n revert SenderAlreadyAuthorized();\n }\n authorizedSenders[sender] = true;\n emit AuthorizedSenderAdded(sender);\n }\n\n /**\n * @notice Removes an address from the list of authorized senders\n * @param sender Address to be unauthorized\n * @custom:access Controlled by AccessControlManager\n * @custom:error Throws SenderNotAuthorized if sender is not currently authorized\n * @custom:error Throws Unauthorized if caller is not allowed by AccessControlManager\n * @custom:event Emits AuthorizedSenderRemoved when sender is successfully removed\n */\n function removeAuthorizedSender(address sender) external {\n _checkAccessAllowed(\"removeAuthorizedSender(address)\");\n if (!authorizedSenders[sender]) {\n revert SenderNotAuthorized();\n }\n delete authorizedSenders[sender];\n emit AuthorizedSenderRemoved(sender);\n }\n\n /**\n * @notice Adds a new type of update to the list of authorized update types\n * @param newUpdateType New type of update to allow\n * @custom:access Controlled by AccessControlManager\n * @custom:error Throws InvalidUpdateTypeString if update type string is empty or exceeds 64 characters\n * @custom:error Throws UpdateTypeAlreadyExists if update type already exists\n * @custom:error Throws Unauthorized if caller is not allowed by AccessControlManager\n * @custom:event Emits UpdateTypeAdded when update type is successfully added\n */\n function addUpdateType(string memory newUpdateType) external {\n _checkAccessAllowed(\"addUpdateType(string)\");\n if (bytes(newUpdateType).length == 0 || bytes(newUpdateType).length > 64) {\n revert InvalidUpdateTypeString();\n }\n bytes32 key = keccak256(bytes(newUpdateType));\n\n if (_updateTypeExists(key)) {\n revert UpdateTypeAlreadyExists();\n }\n\n activeUpdateTypes[key] = true;\n allUpdateTypes.push(newUpdateType);\n emit UpdateTypeAdded(newUpdateType);\n }\n\n /**\n * @notice Sets the active status of an existing update type\n * @param updateType The update type to set active status for\n * @param active True to activate, false to deactivate\n * @custom:access Controlled by AccessControlManager\n * @custom:error Throws UpdateTypeNotFound if update type doesn't exist\n * @custom:error Throws UpdateTypeStatusUnchanged if status is already set to the desired value\n * @custom:error Throws Unauthorized if caller is not allowed by AccessControlManager\n * @custom:event Emits UpdateTypeActiveStatusChanged when status is successfully changed\n */\n function setUpdateTypeActive(string memory updateType, bool active) external {\n _checkAccessAllowed(\"setUpdateTypeActive(string,bool)\");\n bytes32 key = keccak256(bytes(updateType));\n\n if (!_updateTypeExists(key)) {\n revert UpdateTypeNotFound();\n }\n\n bool previousActive = activeUpdateTypes[key];\n if (previousActive == active) {\n revert UpdateTypeStatusUnchanged();\n }\n\n activeUpdateTypes[key] = active;\n emit UpdateTypeActiveStatusChanged(updateType, previousActive, active);\n }\n\n /**\n * @notice Publishes a new risk parameter update\n * @param referenceId An external reference ID associated with the update\n * @param newValue The new value of the risk parameter being updated\n * @param updateType Type of update performed, must be previously authorized\n * @param market Address for market of the parameter update\n * @param poolId Pool identifier for eMode-style collateral configuration (0 for regular markets)\n * @param dstEid Destination endpoint ID for cross-chain routing\n * @param additionalData Additional data for the update\n * @custom:error Throws SenderNotAuthorized if caller is not an authorized sender\n * @custom:error Throws UpdateTypeNotActive if update type is not active\n * @custom:error Throws ZeroAddressNotAllowed if market is zero address\n * @custom:event Emits UpdatePublished when update is successfully published\n */\n function publishRiskParameterUpdate(\n string memory referenceId,\n bytes memory newValue,\n string memory updateType,\n address market,\n uint96 poolId,\n uint32 dstEid,\n bytes memory additionalData\n ) external onlyAuthorized {\n _publishUpdate(referenceId, newValue, updateType, market, poolId, dstEid, additionalData);\n }\n\n /**\n * @notice Publishes multiple risk parameter updates in a single transaction\n * @param referenceIds Array of external reference IDs\n * @param newValues Array of new values for each update\n * @param updateTypes Array of types for each update, all must be authorized\n * @param markets Array of addresses for markets of the parameter updates\n * @param poolIds Array of pool identifiers for eMode-style collateral configuration (0 for regular markets)\n * @param dstEid Array of destination endpoint IDs for cross-chain routing\n * @param additionalData Array of additional data for the updates\n * @custom:error Throws SenderNotAuthorized if caller is not an authorized sender\n * @custom:error Throws ArrayLengthMismatch if the array lengths do not match or if no updates are provided\n * @custom:error Throws UpdateTypeNotActive if any update type is not active\n * @custom:error Throws ZeroAddressNotAllowed if any market is zero address\n * @custom:event Emits UpdatePublished for each successfully published update\n */\n function publishBulkRiskParameterUpdates(\n string[] memory referenceIds,\n bytes[] memory newValues,\n string[] memory updateTypes,\n address[] memory markets,\n uint96[] memory poolIds,\n uint32[] memory dstEid,\n bytes[] memory additionalData\n ) external onlyAuthorized {\n uint256 length = referenceIds.length;\n if (\n length == 0 ||\n length != newValues.length ||\n length != updateTypes.length ||\n length != markets.length ||\n length != poolIds.length ||\n length != dstEid.length ||\n length != additionalData.length\n ) {\n revert ArrayLengthMismatch();\n }\n for (uint256 i = 0; i < length; ++i) {\n _publishUpdate(\n referenceIds[i],\n newValues[i],\n updateTypes[i],\n markets[i],\n poolIds[i],\n dstEid[i],\n additionalData[i]\n );\n }\n }\n\n /**\n * @notice Fetches the most recent update for a specific parameter in a specific market\n * @param updateType The identifier for the parameter\n * @param market The market identifier\n * @return The most recent RiskParameterUpdate for the specified parameter and market\n * @custom:error Throws NoUpdateFound if no update exists for the specified parameter and market\n */\n function getLatestUpdateByMarketAndType(\n string memory updateType,\n address market\n ) external view returns (RiskParameterUpdate memory) {\n bytes32 updateTypeKey = keccak256(bytes(updateType));\n uint256 updateId = latestUpdateIdByMarketAndType[updateTypeKey][market];\n if (updateId == 0) {\n revert NoUpdateFound();\n }\n return updatesById[updateId];\n }\n\n /**\n * @notice Fetches the update for a provided updateId\n * @param updateId Update ID\n * @return The RiskParameterUpdate for the specified id\n * @custom:error Throws InvalidUpdateId if updateId is 0 or greater than updateCounter\n */\n function getUpdateById(uint256 updateId) external view returns (RiskParameterUpdate memory) {\n if (updateId == 0 || updateId > updateCounter) {\n revert InvalidUpdateId();\n }\n return updatesById[updateId];\n }\n\n /**\n * @notice Publishes a new risk parameter update internally\n * @param referenceId An external reference ID associated with the update\n * @param newValue The new value of the risk parameter being updated\n * @param updateType Type of update performed, must be previously authorized\n * @param market Address for market of the parameter update\n * @param poolId Pool identifier for eMode-style collateral configuration (0 for regular markets)\n * @param dstEid Destination endpoint ID for cross-chain routing\n * @param additionalData Additional data for the update\n * @custom:error Throws ZeroAddressNotAllowed if market is zero address\n * @custom:error Throws UpdateTypeNotActive if update type is not active\n * @custom:event Emits UpdatePublished when update is successfully published\n */\n function _publishUpdate(\n string memory referenceId,\n bytes memory newValue,\n string memory updateType,\n address market,\n uint96 poolId,\n uint32 dstEid,\n bytes memory additionalData\n ) internal {\n ensureNonzeroAddress(market);\n bytes32 updateTypeKey = keccak256(bytes(updateType));\n if (!activeUpdateTypes[updateTypeKey]) {\n revert UpdateTypeNotActive();\n }\n uint256 newUpdateCounter = ++updateCounter;\n uint256 previousUpdateId = latestUpdateIdByMarketAndType[updateTypeKey][market];\n bytes memory previousValue = updatesById[previousUpdateId].newValue;\n\n RiskParameterUpdate memory newUpdate = RiskParameterUpdate({\n referenceId: referenceId,\n updateId: newUpdateCounter,\n market: market,\n updateType: updateType,\n updateTypeKey: updateTypeKey,\n newValue: newValue,\n previousValue: previousValue,\n timestamp: block.timestamp,\n publisher: msg.sender,\n poolId: poolId,\n destLzEid: dstEid,\n additionalData: additionalData\n });\n updatesById[newUpdateCounter] = newUpdate;\n\n // Update the latest update ID for the (updateTypeKey, market) pair\n latestUpdateIdByMarketAndType[updateTypeKey][market] = newUpdateCounter;\n\n emit UpdatePublished(\n referenceId,\n newUpdateCounter,\n market,\n updateType,\n newValue,\n previousValue,\n block.timestamp,\n msg.sender,\n additionalData\n );\n }\n\n /**\n * @notice Returns the total number of update types in the allUpdateTypes array\n * @return The length of the allUpdateTypes array\n */\n function allUpdateTypesLength() external view returns (uint256) {\n return allUpdateTypes.length;\n }\n\n /**\n * @notice Gets the latest update ID for a specific market and update type (string) combination\n * @param updateType The update type string\n * @param market The market address\n * @return The latest update ID for the given market and update type, or 0 if none exists\n */\n function getLatestUpdateIdByMarketAndType(\n string memory updateType,\n address market\n ) external view returns (uint256) {\n bytes32 updateTypeKey = keccak256(bytes(updateType));\n return latestUpdateIdByMarketAndType[updateTypeKey][market];\n }\n\n /**\n * @notice Checks if a given update type is currently active.\n * @param updateType The update type string to check\n * @return True if the update type is active, false otherwise\n */\n function getActiveUpdateTypes(string memory updateType) external view returns (bool) {\n bytes32 key = keccak256(bytes(updateType));\n return activeUpdateTypes[key];\n }\n\n /**\n * @notice Returns all update types in the allUpdateTypes array\n * @return An array of all update type strings\n */\n function getAllUpdateTypes() external view returns (string[] memory) {\n return allUpdateTypes;\n }\n\n /**\n * @notice Checks if an update type exists in the allUpdateTypes array\n * @param updateTypeKey The keccak256 hash of the update type string\n * @return True if the update type exists, false otherwise\n */\n function _updateTypeExists(bytes32 updateTypeKey) internal view returns (bool) {\n for (uint256 i = 0; i < allUpdateTypes.length; ++i) {\n if (keccak256(bytes(allUpdateTypes[i])) == updateTypeKey) {\n return true;\n }\n }\n return false;\n }\n\n /**\n * @notice Disables renounceOwnership function\n * @custom:error Throws RenounceOwnershipNotAllowed\n */\n function renounceOwnership() public pure override {\n revert RenounceOwnershipNotAllowed();\n }\n}\n"
},
"contracts/RiskSteward/RiskStewardReceiver.sol": {
"content": "// SPDX-License-Identifier: BSD-3-Clause\npragma solidity 0.8.25;\n\nimport { OwnableUpgradeable } from \"@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol\";\nimport { Ownable2StepUpgradeable } from \"@openzeppelin/contracts-upgradeable/access/Ownable2StepUpgradeable.sol\";\nimport { IRiskSteward } from \"./Interfaces/IRiskSteward.sol\";\nimport { IRiskOracle, RiskParameterUpdate } from \"./Interfaces/IRiskOracle.sol\";\nimport { IRiskStewardReceiver } from \"./Interfaces/IRiskStewardReceiver.sol\";\nimport { AccessControlledV8 } from \"../Governance/AccessControlledV8.sol\";\nimport { ensureNonzeroAddress } from \"@venusprotocol/solidity-utilities/contracts/validators.sol\";\nimport { ICorePoolComptroller } from \"../interfaces/ICorePoolComptroller.sol\";\nimport {\n OAppSenderUpgradeable,\n MessagingFee\n} from \"@layerzerolabs/oapp-evm-upgradeable/contracts/oapp/OAppSenderUpgradeable.sol\";\nimport { OptionsBuilder } from \"@layerzerolabs/oapp-evm/contracts/oapp/libs/OptionsBuilder.sol\";\nimport { OAppCoreUpgradeable } from \"@layerzerolabs/oapp-evm-upgradeable/contracts/oapp/OAppCoreUpgradeable.sol\";\n\n/**\n * @title RiskStewardReceiver\n * @author Venus\n * @notice Contract that reads updates from a Risk Oracle, validates them with timelock and debounce,\n * and either executes them locally via the configured RiskSteward or forwards them cross‑chain.\n * @custom:security-contact https://github.com/VenusProtocol/governance-contracts#discussion\n */\ncontract RiskStewardReceiver is IRiskStewardReceiver, AccessControlledV8, OAppSenderUpgradeable {\n using OptionsBuilder for bytes;\n\n /**\n * @notice Period after which a proposed update becomes expired and can no longer be applied\n */\n uint256 public constant UPDATE_EXPIRATION_TIME = 2 days;\n\n /**\n * @notice Source chain LayerZero endpoint ID\n */\n uint32 public immutable LAYER_ZERO_EID;\n\n /**\n * @notice The Risk Oracle contract address\n */\n IRiskOracle public immutable RISK_ORACLE;\n\n /**\n * @notice Pause flag\n */\n bool public paused;\n\n /**\n * @notice Mapping of supported risk configurations and their validation parameters (keyed by hashed updateType)\n */\n mapping(bytes32 => RiskParamConfig) public riskParameterConfigs;\n\n /**\n * @notice Master storage of all registered updates by update ID\n */\n mapping(uint256 updateId => RegisteredUpdate) public updates;\n\n /**\n * @notice Track last processed update ID per (updateTypeKey, market)\n */\n mapping(bytes32 => mapping(address market => uint256)) public lastProcessedUpdate;\n\n /**\n * @notice Track the current registered update per (updateType, market) to avoid registering multiple updates\n */\n mapping(bytes32 => mapping(address market => uint256)) public lastRegisteredUpdate;\n\n /**\n * @notice Mapping from executor address to whitelist status\n */\n mapping(address => bool) public whitelistedExecutors;\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[44] private __gap;\n\n /**\n * @dev Ensures the caller is a whitelisted executor.\n */\n modifier onlyWhitelistedExecutors() {\n if (!whitelistedExecutors[msg.sender]) {\n revert NotAnExecutor();\n }\n _;\n }\n\n /**\n * @dev Ensures the contract is not paused.\n */\n modifier whenNotPaused() {\n if (paused) {\n revert PausedError();\n }\n _;\n }\n\n /**\n * @notice Disables initializers and sets the Risk Oracle and LayerZero configuration.\n * @param riskOracle_ The address of the Risk Oracle contract.\n * @param endpoint_ The LayerZero endpoint contract used by the underlying `OAppUpgradeable`.\n * @param layerZeroLzEid_ The LayerZero endpoint ID (EID) for this chain.\n * @custom:oz-upgrades-unsafe-allow constructor\n */\n constructor(address riskOracle_, address endpoint_, uint32 layerZeroLzEid_) OAppCoreUpgradeable(endpoint_) {\n _disableInitializers();\n ensureNonzeroAddress(riskOracle_);\n ensureNonzeroAddress(endpoint_);\n if (layerZeroLzEid_ == 0) revert InvalidLayerZeroEid();\n\n RISK_ORACLE = IRiskOracle(riskOracle_);\n LAYER_ZERO_EID = layerZeroLzEid_;\n }\n\n /**\n * @notice Initializes the contract with the Access Control Manager and OApp owner.\n * @param acm_ The address of the Access Control Manager\n * @param delegate_ The address of the OApp owner passed to `__OApp_init`.\n */\n function initialize(address acm_, address delegate_) external initializer {\n __AccessControlled_init(acm_);\n __OAppSender_init(delegate_);\n }\n\n /**\n * @notice Accepts native tokens (e.g., BNB) sent to this contract.\n */\n receive() external payable {}\n\n /**\n * @notice Allows the owner to sweep leftover native tokens (e.g., BNB) from the contract.\n * @custom:event Emits SweepNative event.\n */\n function sweepNative() external onlyOwner {\n uint256 balance = address(this).balance;\n if (balance > 0) {\n (bool success, ) = payable(owner()).call{ value: balance }(\"\");\n if (!success) revert TransferFailed();\n emit SweepNative(owner(), balance);\n }\n }\n\n /**\n * @notice Sets the pause status for `processUpdate`.\n * @param paused_ True to pause, false to unpause\n * @custom:access Controlled by AccessControlManager\n * @custom:event Emits PauseStatusUpdated\n */\n function setPaused(bool paused_) external {\n _checkAccessAllowed(\"setPaused(bool)\");\n if (paused == paused_) {\n revert PauseStatusUnchanged();\n }\n emit PauseStatusUpdated(paused, paused_);\n paused = paused_;\n }\n\n /**\n * @notice Sets the risk parameter config for a given update type\n * @param updateType The type of update to configure\n * @param riskSteward The address for the risk steward contract responsible for processing the update\n * @param debounce The debounce period for the update\n * @param timelock The timelock period before the update can be executed\n * @custom:access Controlled by AccessControlManager\n * @custom:event Emits RiskParameterConfigUpdated\n * @custom:error InvalidUpdateType if the update type string is empty\n * @custom:error Throws InvalidDebounce if the debounce is 0\n * @custom:error Throws InvalidTimelock if the timelock is greater than or equal to the expiration time\n * @custom:error Throws ZeroAddressNotAllowed if the risk steward address is zero\n */\n function setRiskParameterConfig(\n string calldata updateType,\n address riskSteward,\n uint256 debounce,\n uint256 timelock\n ) external {\n _checkAccessAllowed(\"setRiskParameterConfig(string,address,uint256,uint256)\");\n ensureNonzeroAddress(riskSteward);\n\n if (bytes(updateType).length == 0 || bytes(updateType).length > 64) {\n revert InvalidUpdateType();\n }\n if (debounce == 0) {\n revert InvalidDebounce();\n }\n if (timelock >= UPDATE_EXPIRATION_TIME) {\n revert InvalidTimelock();\n }\n\n bytes32 key = keccak256(bytes(updateType));\n RiskParamConfig memory previousConfig = riskParameterConfigs[key];\n\n riskParameterConfigs[key] = RiskParamConfig({\n active: true,\n riskSteward: riskSteward,\n debounce: debounce,\n timelock: timelock\n });\n\n emit RiskParameterConfigUpdated(\n key,\n updateType,\n previousConfig.riskSteward,\n riskSteward,\n previousConfig.debounce,\n debounce,\n previousConfig.timelock,\n timelock,\n previousConfig.active,\n true\n );\n }\n\n /**\n * @notice Sets the active status of a risk parameter config\n * @param updateType The type of update to configure\n * @param active The active status to set\n * @custom:access Controlled by AccessControlManager\n * @custom:event Emits ConfigActiveUpdated with the update type hash, update type, previous active status, and the active status\n * @custom:error Throws UnsupportedUpdateType if the update type is not supported\n * @custom:error Throws ConfigStatusUnchanged if the active status is already set to the desired value\n */\n function setConfigActive(string calldata updateType, bool active) external {\n _checkAccessAllowed(\"setConfigActive(string,bool)\");\n bytes32 key = keccak256(bytes(updateType));\n\n if (riskParameterConfigs[key].riskSteward == address(0)) {\n revert UnsupportedUpdateType();\n }\n\n bool previousActive = riskParameterConfigs[key].active;\n if (previousActive == active) {\n revert ConfigStatusUnchanged();\n }\n\n riskParameterConfigs[key].active = active;\n emit ConfigActiveUpdated(key, updateType, previousActive, active);\n }\n\n /**\n * @notice Manages the whitelist of executors that are allowed to execute timelocked registered updates.\n * @param executor The address of the executor\n * @param approved The whitelist status to set (true to whitelist, false to remove)\n * @custom:access Controlled by AccessControlManager\n * @custom:event Emits ExecutorStatusUpdated with the executor address, previous approval status, and approval status\n * @custom:error Throws ZeroAddressNotAllowed if the executor address is zero\n * @custom:error Throws ExecutorStatusUnchanged if the executor whitelist status is already set to the desired value\n */\n function setWhitelistedExecutor(address executor, bool approved) external {\n _checkAccessAllowed(\"setWhitelistedExecutor(address,bool)\");\n ensureNonzeroAddress(executor);\n\n bool previousApproved = whitelistedExecutors[executor];\n if (previousApproved == approved) {\n revert ExecutorStatusUnchanged();\n }\n\n whitelistedExecutors[executor] = approved;\n emit ExecutorStatusUpdated(executor, previousApproved, approved);\n }\n\n /**\n * @notice Processes an update from the Risk Oracle. Validates, registers the update,\n * and either executes immediately, registers with timelock, or forwards cross-chain.\n * @param updateId The update ID from the oracle's perspective\n * @custom:event Emits UpdateRegistered, UpdateExecuted, or UpdateSentToDestination depending on the update type\n * @custom:error Throws UpdateAlreadyResolved if the update was already processed\n * @custom:error Throws UpdateIsExpired if the update has expired\n * @custom:error Throws ConfigNotActive if the config is not active\n * @custom:error Throws UpdateTooFrequent if the debounce period has not passed\n * @custom:error Throws RegisteredUpdateTypeExist if there is a non-expired pending update of the same type\n */\n function processUpdate(uint256 updateId) external whenNotPaused {\n RiskParameterUpdate memory update = RISK_ORACLE.getUpdateById(updateId);\n RiskParamConfig storage config = riskParameterConfigs[update.updateTypeKey];\n bool isRemoteUpdate = update.destLzEid != 0 && update.destLzEid != LAYER_ZERO_EID;\n\n // Skip active update check for remote updates since they are sent immediately and not registered locally\n if (!isRemoteUpdate) _ensureNoActiveUpdate(update);\n _validateRegisterUpdate(update, config, isRemoteUpdate);\n\n IRiskSteward riskSteward = IRiskSteward(config.riskSteward);\n bool safeForDirectExecution = isRemoteUpdate ? false : riskSteward.isSafeForDirectExecution(update);\n _registerUpdate(update, config, safeForDirectExecution || isRemoteUpdate);\n\n if (isRemoteUpdate) {\n _sendRemoteUpdate(update, \"\", 0);\n } else if (safeForDirectExecution) {\n _executeUpdate(update, riskSteward);\n }\n }\n\n /**\n * @notice Executes a registered update. Only whitelisted executors can call this function.\n * This function can be used for updates that have completed their timelock and are ready to execute.\n * @param updateId The oracle update ID of the update to execute\n * @custom:access Only whitelisted executors can call this function\n * @custom:event Emits UpdateExecuted with the oracle update ID\n * @custom:error Throws NotAnExecutor if the caller is not a whitelisted executor\n * @custom:error Throws InvalidRegisteredUpdate if the update was never registered\n * @custom:error Throws UpdateAlreadyResolved if the update was already executed or rejected\n * @custom:error Throws UpdateIsExpired if the update has expired\n * @custom:error Throws ConfigNotActive if the config is not active\n * @custom:error Throws UpdateNotUnlocked if the unlock time has not passed\n */\n function executeRegisteredUpdate(uint256 updateId) external onlyWhitelistedExecutors {\n RegisteredUpdate storage registeredUpdate = updates[updateId];\n RiskParameterUpdate memory update = RISK_ORACLE.getUpdateById(updateId);\n RiskParamConfig storage config = riskParameterConfigs[update.updateTypeKey];\n\n _validateExecuteUpdate(registeredUpdate, update, config);\n _executeUpdate(update, IRiskSteward(config.riskSteward));\n }\n\n /**\n * @notice Rejects a registered update\n * @param updateId The oracle update ID of the update to reject\n * @custom:access Only whitelisted executors can call this function\n * @custom:event Emits UpdateRejected with the oracle update ID\n * @custom:error Throws UpdateAlreadyResolved if the update was already executed or rejected\n */\n function rejectUpdate(uint256 updateId) external onlyWhitelistedExecutors {\n RegisteredUpdate storage registeredUpdate = updates[updateId];\n\n if (registeredUpdate.status != UpdateStatus.Pending) {\n revert UpdateAlreadyResolved();\n }\n\n registeredUpdate.status = UpdateStatus.Rejected;\n emit UpdateRejected(updateId);\n }\n\n /**\n * @notice Resends a remote update to the destination chain. This function is useful in case of bridge failures.\n * @dev Duplicate update rejection is handled in the destination contract itself, so resending\n * the same update multiple times is safe and will be deduplicated on the destination side.\n * @param updateId The oracle update ID to resend\n * @param options LayerZero message options; if empty, default executor option is used\n * @custom:access Only whitelisted executors can call this function\n * @custom:event Emits UpdateResentToDestination with the update ID, destination chain ID, update type, and market\n * @custom:error Throws NotAnExecutor if the caller is not a whitelisted executor\n * @custom:error Throws InvalidUpdateToResend if the update status is not SENT_TO_DESTINATION\n * @custom:error Throws UpdateIsExpired if the update has expired\n */\n function resendRemoteUpdate(uint256 updateId, bytes calldata options) external payable onlyWhitelistedExecutors {\n RegisteredUpdate storage registeredUpdate = updates[updateId];\n if (registeredUpdate.status != UpdateStatus.SENT_TO_DESTINATION) {\n revert InvalidUpdateToResend();\n }\n\n RiskParameterUpdate memory update = RISK_ORACLE.getUpdateById(updateId);\n\n // Check if update is expired\n if (update.timestamp + UPDATE_EXPIRATION_TIME < block.timestamp) {\n revert UpdateIsExpired();\n }\n\n _sendRemoteUpdate(update, options, msg.value);\n emit UpdateResentToDestination(update.updateId, update.destLzEid, update.updateType, update.market);\n }\n\n /**\n * @notice Returns an array of update IDs for executable registered updates for a given update type and comptroller.\n * @param updateType The human‑readable identifier of the update type to filter by\n * @param comptroller The address of the Comptroller (either Core Pool or Isolated Pools) that manages the markets\n * @return executableUpdates Array of update IDs that are ready to be executed\n */\n function getExecutableUpdates(\n string calldata updateType,\n address comptroller\n ) external view returns (uint256[] memory executableUpdates) {\n bytes32 updateTypeKey = keccak256(bytes(updateType));\n // Both Core and Isolated Pools comptrollers expose the same signature\n address[] memory markets = ICorePoolComptroller(comptroller).getAllMarkets();\n uint256 maxUpdates = markets.length;\n uint256[] memory tempArray = new uint256[](maxUpdates);\n uint256 count = 0;\n\n for (uint256 i = 0; i < maxUpdates; ++i) {\n uint256 registeredUpdateId = lastRegisteredUpdate[updateTypeKey][markets[i]];\n if (!_isUpdateExecutable(registeredUpdateId)) continue;\n tempArray[count] = registeredUpdateId;\n count++;\n }\n\n // shrink array to real size\n executableUpdates = new uint256[](count);\n for (uint256 i = 0; i < count; ++i) {\n executableUpdates[i] = tempArray[i];\n }\n }\n\n /**\n * @notice Returns whether a registered update is ready to be executed.\n * @param updateId The oracle update ID to query\n * @return True if the update is pending, not expired, active, and past its timelock\n */\n function isUpdateExecutable(uint256 updateId) external view returns (bool) {\n return _isUpdateExecutable(updateId);\n }\n\n /**\n * @notice Returns the risk parameter configuration for a given update type\n * @param updateType The human-readable identifier of the update type\n * @return The risk parameter configuration\n */\n function getRiskParameterConfig(string calldata updateType) external view returns (RiskParamConfig memory) {\n bytes32 key = keccak256(bytes(updateType));\n return riskParameterConfigs[key];\n }\n\n /**\n * @notice Returns the last processed update ID for a given update type and market\n * @param updateType The human-readable identifier of the update type\n * @param market The address of the market\n * @return The last processed update ID\n */\n function getLastProcessedUpdate(string calldata updateType, address market) external view returns (uint256) {\n bytes32 key = keccak256(bytes(updateType));\n return lastProcessedUpdate[key][market];\n }\n\n /**\n * @notice Returns the last registered update ID for a given update type and market\n * @param updateType The human-readable identifier of the update type\n * @param market The address of the market\n * @return The last registered update ID\n */\n function getLastRegisteredUpdate(string calldata updateType, address market) external view returns (uint256) {\n bytes32 key = keccak256(bytes(updateType));\n return lastRegisteredUpdate[key][market];\n }\n\n /**\n * @notice Quotes the gas fee needed to pay for the full omnichain transaction in native gas or ZRO token.\n * @param update The risk parameter update payload to be sent\n * @param options Message execution options (e.g., for sending gas to the destination)\n * @param payInLzToken Whether to return the fee in ZRO token instead of native gas\n * @return fee A `MessagingFee` struct containing the calculated gas fee\n */\n function quote(\n RiskParameterUpdate memory update,\n bytes memory options,\n bool payInLzToken\n ) public view returns (MessagingFee memory fee) {\n bytes memory payload = abi.encode(update);\n fee = _quote(update.destLzEid, payload, options, payInLzToken);\n }\n\n /**\n * @notice Sends a `RiskParameterUpdate` to a destination chain via LayerZero.\n * @param dstEid Destination chain endpoint ID\n * @param update The risk parameter update payload to send\n * @param options LayerZero message options; if empty, a default executor option is used\n * @param fee Messaging fee structure returned by `quote`\n * @param refundAddress Address to receive any surplus fee refunds\n * @custom:error InvalidLzSendCaller if called by any address other than this contract\n */\n function lzSend(\n uint32 dstEid,\n RiskParameterUpdate memory update,\n bytes memory options,\n MessagingFee memory fee,\n address refundAddress\n ) public payable {\n if (msg.sender != address(this)) {\n revert InvalidLzSendCaller();\n }\n\n bytes memory payload = abi.encode(update);\n _lzSend(dstEid, payload, options, fee, refundAddress);\n }\n\n /**\n * @dev Overrides OwnableUpgradeable and Ownable2StepUpgradeable to resolve\n * the multiple inheritance ownership transfer conflict.\n */\n function transferOwnership(\n address newOwner\n ) public override(OwnableUpgradeable, Ownable2StepUpgradeable) onlyOwner {\n Ownable2StepUpgradeable.transferOwnership(newOwner);\n }\n\n /**\n * @dev Internal hook to finalize ownership transfer, resolving the\n * OwnableUpgradeable and Ownable2StepUpgradeable inheritance conflict.\n */\n function _transferOwnership(address newOwner) internal override(OwnableUpgradeable, Ownable2StepUpgradeable) {\n Ownable2StepUpgradeable._transferOwnership(newOwner);\n }\n\n /**\n * @notice Registers an update from the Risk Oracle with a timelock.\n * @param update The risk parameter update from the Risk Oracle to register\n * @param config The risk parameter configuration for this update type containing timelock\n * @param useImmediateUnlock Whether to unlock the update immediately or use timelock\n * @custom:event Emits UpdateRegistered with the oracle update ID, unlock time, update type, and market\n */\n function _registerUpdate(\n RiskParameterUpdate memory update,\n RiskParamConfig memory config,\n bool useImmediateUnlock\n ) internal {\n uint256 updateId = update.updateId;\n uint256 unlockTime = useImmediateUnlock ? block.timestamp : block.timestamp + config.timelock;\n\n updates[updateId] = RegisteredUpdate({\n updateId: updateId,\n unlockTime: unlockTime,\n status: UpdateStatus.Pending,\n executor: address(0),\n executedAt: 0\n });\n\n lastRegisteredUpdate[update.updateTypeKey][update.market] = updateId;\n emit UpdateRegistered(updateId, unlockTime, update.updateType, update.market);\n }\n\n /**\n * @notice Executes a validated update via the risk steward and records its execution metadata.\n * Updates the registered update storage, last processed tracking, and emits the execution event.\n * Preserves the unlockTime that was set during registration.\n * @param update The risk parameter update to execute\n * @param steward The risk steward contract that will process the update\n * @custom:event Emits UpdateExecuted with the oracle update ID\n */\n function _executeUpdate(RiskParameterUpdate memory update, IRiskSteward steward) internal {\n uint256 updateId = update.updateId;\n uint256 timestamp = block.timestamp;\n RegisteredUpdate storage registeredUpdate = updates[updateId];\n\n registeredUpdate.status = UpdateStatus.Executed;\n registeredUpdate.executor = address(msg.sender);\n registeredUpdate.executedAt = timestamp;\n lastProcessedUpdate[update.updateTypeKey][update.market] = updateId;\n\n steward.applyUpdate(update);\n emit UpdateExecuted(updateId);\n }\n\n /**\n * @notice Sends a risk parameter update to a destination chain via LayerZero and records it as sent.\n * The update should already be registered before calling this function.\n * @param update The risk parameter update to send to the destination chain\n * @param options LayerZero message options; if empty, default executor option is used\n * @param nativeFee Native tokens supplied to cover the bridge fee (0 to use the quoted amount)\n * @custom:event Emits UpdateSentToDestination with the update ID, destination endpoint ID, update type, and market\n */\n function _sendRemoteUpdate(RiskParameterUpdate memory update, bytes memory options, uint256 nativeFee) internal {\n bytes memory option = options.length == 0\n ? OptionsBuilder.newOptions().addExecutorLzReceiveOption(1_000_000, 0)\n : options;\n\n MessagingFee memory fee;\n\n if (nativeFee == 0) {\n fee = quote(update, option, false);\n } else {\n fee = MessagingFee(nativeFee, 0);\n }\n\n this.lzSend{ value: fee.nativeFee }(update.destLzEid, update, option, fee, address(this));\n\n RegisteredUpdate storage registeredUpdate = updates[update.updateId];\n registeredUpdate.status = UpdateStatus.SENT_TO_DESTINATION;\n registeredUpdate.executor = address(msg.sender);\n registeredUpdate.executedAt = block.timestamp;\n\n bytes32 updateTypeKey = update.updateTypeKey;\n lastProcessedUpdate[updateTypeKey][update.market] = update.updateId;\n\n emit UpdateSentToDestination(update.updateId, update.destLzEid, update.updateType, update.market);\n }\n\n /**\n * @notice Ensures there is no other pending registered update of the same type for the same market.\n * If a pending update exists and is expired, it is marked as expired and a new update can proceed.\n * If a pending update exists and is not expired, the call reverts to prevent overlapping updates.\n * @param update The risk parameter update being registered\n * @custom:event Emits UpdateExpired with the ID of the previously pending update if it is found to be expired\n * @custom:error RegisteredUpdateTypeExist if there is a non‑expired pending update of the same type for the market\n */\n function _ensureNoActiveUpdate(RiskParameterUpdate memory update) internal {\n uint256 registeredUpdateId = lastRegisteredUpdate[update.updateTypeKey][update.market];\n if (registeredUpdateId == 0) return; // no prior update of this type for this market\n\n RegisteredUpdate storage existing = updates[registeredUpdateId];\n if (existing.status != UpdateStatus.Pending) return;\n\n // Check expiration\n RiskParameterUpdate memory existingUpdate = RISK_ORACLE.getUpdateById(registeredUpdateId);\n bool expired = existingUpdate.timestamp + UPDATE_EXPIRATION_TIME < block.timestamp;\n\n if (expired) {\n existing.status = UpdateStatus.Expired;\n emit UpdateExpired(registeredUpdateId);\n return;\n }\n\n // If still pending & not expired reject new update\n revert RegisteredUpdateTypeExist(registeredUpdateId);\n }\n\n /**\n * @notice Validates an oracle update before registration.\n * @param update The risk parameter update to validate\n * @param config The configuration for this update type\n * @param isRemoteUpdate Whether the update is destined for a remote chain\n * @custom:error UpdateAlreadyResolved if the update was already registered\n * @custom:error ConfigNotActive if the configuration for the update type is not active\n * @custom:error UpdateIsExpired if the update has expired or is not the latest for the given market and type\n * @custom:error UpdateWillExpireBeforeUnlock if the update will expire before its timelock unlocks\n * @custom:error UpdateTooFrequent if the debounce period has not passed for the given market and type (only for local updates)\n */\n function _validateRegisterUpdate(\n RiskParameterUpdate memory update,\n RiskParamConfig storage config,\n bool isRemoteUpdate\n ) internal view {\n // Check if this update was already registered\n if (updates[update.updateId].status != UpdateStatus.None) {\n revert UpdateAlreadyResolved();\n }\n\n // Check if config is active\n if (!config.active) {\n revert ConfigNotActive();\n }\n\n // Check if this is the latest update for this market and type\n uint256 latestUpdateIdForMarketAndType = RISK_ORACLE.getLatestUpdateIdByMarketAndType(\n update.updateType,\n update.market\n );\n if (latestUpdateIdForMarketAndType != update.updateId) {\n revert UpdateIsExpired();\n }\n\n uint256 currentTime = block.timestamp;\n uint256 expirationTime = update.timestamp + UPDATE_EXPIRATION_TIME;\n\n // Check expiration\n if (expirationTime < currentTime) {\n revert UpdateIsExpired();\n }\n\n // Check if update will still be valid when timelock unlocks\n if (expirationTime < currentTime + config.timelock) {\n revert UpdateWillExpireBeforeUnlock();\n }\n\n // Check debounce (only for local updates)\n if (!isRemoteUpdate) {\n uint256 lastProcessedId = lastProcessedUpdate[update.updateTypeKey][update.market];\n uint256 lastExecutionTime = updates[lastProcessedId].executedAt;\n if (lastExecutionTime != 0 && (lastExecutionTime + config.debounce > currentTime)) {\n revert UpdateTooFrequent();\n }\n }\n }\n\n /**\n * @notice Validates a registered update before execution.\n * @param registeredUpdate The stored registered update metadata\n * @param update The risk parameter update fetched from the oracle\n * @param config The configuration for this update type\n * @custom:error ConfigNotActive if the configuration for the update type is not active\n * @custom:error InvalidRegisteredUpdate if the update was never registered\n * @custom:error UpdateAlreadyResolved if the update was already executed or rejected\n * @custom:error UpdateIsExpired if the update has expired\n * @custom:error UpdateNotUnlocked if the unlock time has not passed\n */\n function _validateExecuteUpdate(\n RegisteredUpdate storage registeredUpdate,\n RiskParameterUpdate memory update,\n RiskParamConfig storage config\n ) internal view {\n if (!config.active) {\n revert ConfigNotActive();\n }\n\n if (registeredUpdate.status == UpdateStatus.None) {\n revert InvalidRegisteredUpdate();\n }\n\n if (registeredUpdate.status != UpdateStatus.Pending) {\n revert UpdateAlreadyResolved();\n }\n\n if (update.timestamp + UPDATE_EXPIRATION_TIME < block.timestamp) {\n revert UpdateIsExpired();\n }\n\n if (block.timestamp < registeredUpdate.unlockTime) {\n revert UpdateNotUnlocked();\n }\n }\n\n /**\n * @notice Checks if an update has completed all conditions to be executed.\n * @param updateId The oracle update ID to query\n * @return True if the update is pending, not expired, active, and past its timelock\n */\n function _isUpdateExecutable(uint256 updateId) internal view returns (bool) {\n RegisteredUpdate storage registeredUpdate = updates[updateId];\n if (registeredUpdate.status != UpdateStatus.Pending) {\n return false;\n }\n\n RiskParameterUpdate memory update = RISK_ORACLE.getUpdateById(updateId);\n RiskParamConfig storage config = riskParameterConfigs[update.updateTypeKey];\n\n if (!config.active) {\n return false;\n }\n\n // Check expiration\n if (update.timestamp + UPDATE_EXPIRATION_TIME < block.timestamp) {\n return false;\n }\n\n // Check UnlockTime\n return block.timestamp >= registeredUpdate.unlockTime;\n }\n\n /**\n * @notice Disables renounceOwnership function\n * @custom:error Throws RenounceOwnershipNotAllowed\n */\n function renounceOwnership() public pure override {\n revert RenounceOwnershipNotAllowed();\n }\n}\n"
},
"contracts/test/MockAccessTest.sol": {
"content": "// SPDX-License-Identifier: BSD-3-Clause\npragma solidity 0.8.25;\n\nimport \"../Governance/AccessControlledV8.sol\";\nimport \"@layerzerolabs/solidity-examples/contracts/lzApp/mocks/LZEndpointMock.sol\";\n\ncontract MockAccessTest is AccessControlledV8 {\n /**\n * @param accessControlManager Access control manager contract address\n */\n function initialize(address accessControlManager) external initializer {\n __AccessControlled_init(accessControlManager);\n }\n}\n"
},
"contracts/test/MockComptroller.sol": {
"content": "// SPDX-License-Identifier: BSD-3-Clause\npragma solidity 0.8.25;\n\nimport { ICorePoolVToken } from \"../interfaces/ICorePoolVToken.sol\";\n\ncontract MockComptroller {\n /// @notice Mapping of vToken addresses to their supply caps\n mapping(address => uint256) public supplyCaps;\n\n /// @notice Mapping of vToken addresses to their borrow caps\n mapping(address => uint256) public borrowCaps;\n\n /// @notice Array of all vTokens\n ICorePoolVToken[] public allVTokens;\n\n /// @notice Mapping of vToken addresses to boolean indicating if they are listed\n mapping(address => bool) public vTokenListed;\n\n /// @notice Mapping of vToken addresses to their collateral factors\n mapping(address => uint256) internal _collateralFactorMantissa;\n\n /// @notice Mapping of vToken addresses to their liquidation thresholds\n mapping(address => uint256) internal _liquidationThresholdMantissa;\n\n /**\n * @notice Add a new vToken to be tracked\n * @param vToken The vToken to add\n */\n function supportMarket(address vToken) external {\n require(!vTokenListed[vToken], \"vToken already listed\");\n vTokenListed[address(vToken)] = true;\n allVTokens.push(ICorePoolVToken(vToken));\n }\n\n /**\n * @notice Set the supply cap for a vToken\n * @param vTokens The vToken addresses\n * @param newCaps The new supply caps\n */\n function setMarketSupplyCaps(address[] calldata vTokens, uint256[] calldata newCaps) external {\n uint256 numMarkets = vTokens.length;\n uint256 numSupplyCaps = newCaps.length;\n\n require(numMarkets != 0 && numMarkets == numSupplyCaps, \"invalid input\");\n\n for (uint256 i; i < numMarkets; ++i) {\n require(vTokenListed[vTokens[i]], \"vToken not listed\");\n supplyCaps[address(vTokens[i])] = newCaps[i];\n }\n }\n\n /**\n * @notice Set the borrow cap for a vToken\n * @param vTokens The vToken addresses\n * @param newCaps The new borrow caps\n */\n function setMarketBorrowCaps(address[] calldata vTokens, uint256[] calldata newCaps) external {\n uint256 numMarkets = vTokens.length;\n uint256 numBorrowCaps = newCaps.length;\n\n require(numMarkets != 0 && numMarkets == numBorrowCaps, \"invalid input\");\n\n for (uint256 i; i < numMarkets; ++i) {\n require(vTokenListed[vTokens[i]], \"vToken not listed\");\n borrowCaps[address(vTokens[i])] = newCaps[i];\n }\n }\n\n /**\n * @notice Get all vTokens\n * @return Array of vToken addresses\n */\n function getAllMarkets() external view returns (address[] memory) {\n address[] memory markets = new address[](allVTokens.length);\n for (uint256 i = 0; i < allVTokens.length; i++) {\n markets[i] = address(allVTokens[i]);\n }\n return markets;\n }\n\n /**\n * @notice Set the collateral factor and liquidation threshold for a vToken\n * @param vToken The vToken address\n * @param newCollateralFactorMantissa The new collateral factor mantissa\n * @param newLiquidationThresholdMantissa The new liquidation threshold mantissa\n */\n function setCollateralFactor(\n address vToken,\n uint256 newCollateralFactorMantissa,\n uint256 newLiquidationThresholdMantissa\n ) external {\n require(vTokenListed[vToken], \"vToken not listed\");\n _collateralFactorMantissa[vToken] = newCollateralFactorMantissa;\n _liquidationThresholdMantissa[vToken] = newLiquidationThresholdMantissa;\n }\n\n /**\n * @notice Get market information for a vToken\n * @param vToken The vToken address\n * @return isListed Whether the vToken is listed\n * @return collateralFactorMantissa The collateral factor mantissa\n * @return liquidationThresholdMantissa The liquidation threshold mantissa\n */\n function markets(\n address vToken\n ) external view returns (bool isListed, uint256 collateralFactorMantissa, uint256 liquidationThresholdMantissa) {\n isListed = vTokenListed[vToken];\n collateralFactorMantissa = _collateralFactorMantissa[vToken];\n liquidationThresholdMantissa = _liquidationThresholdMantissa[vToken];\n }\n}\n"
},
"contracts/test/MockCoreComptroller.sol": {
"content": "// SPDX-License-Identifier: BSD-3-Clause\npragma solidity 0.8.25;\n\nimport { ICorePoolVToken } from \"../interfaces/ICorePoolVToken.sol\";\n\ncontract MockCoreComptroller {\n /// @notice Mapping of vToken addresses to their supply caps\n mapping(address => uint256) public supplyCaps;\n\n /// @notice Mapping of vToken addresses to their borrow caps\n mapping(address => uint256) public borrowCaps;\n\n /// @notice Mapping of vToken addresses to their collateral factors (poolId 0 = regular market)\n mapping(address => uint256) internal _collateralFactorMantissa;\n\n /// @notice Mapping of vToken addresses to their liquidation thresholds (poolId 0 = regular market)\n mapping(address => uint256) internal _liquidationThresholdMantissa;\n\n /// @notice Mapping of (poolId, vToken) to eMode collateral factors\n mapping(uint96 => mapping(address => uint256)) internal _eModeCollateralFactorMantissa;\n\n /// @notice Mapping of (poolId, vToken) to eMode liquidation thresholds\n mapping(uint96 => mapping(address => uint256)) internal _eModeLiquidationThresholdMantissa;\n\n /// @notice Array of all vTokens\n ICorePoolVToken[] public allVTokens;\n\n /// @notice Mapping of vToken addresses to boolean indicating if they are listed\n mapping(address => bool) public vTokenListed;\n\n /**\n * @notice Add a new vToken to be tracked\n * @param vToken The vToken to add\n */\n function supportMarket(address vToken) external {\n require(!vTokenListed[vToken], \"vToken already listed\");\n vTokenListed[address(vToken)] = true;\n allVTokens.push(ICorePoolVToken(vToken));\n }\n\n /**\n * @notice Set the supply cap for a vToken\n * @param vTokens The vToken addresses\n * @param newCaps The new supply caps\n */\n function setMarketSupplyCaps(address[] calldata vTokens, uint256[] calldata newCaps) external {\n uint256 numMarkets = vTokens.length;\n uint256 numSupplyCaps = newCaps.length;\n\n require(numMarkets != 0 && numMarkets == numSupplyCaps, \"invalid input\");\n\n for (uint256 i; i < numMarkets; ++i) {\n require(vTokenListed[vTokens[i]], \"vToken not listed\");\n supplyCaps[address(vTokens[i])] = newCaps[i];\n }\n }\n\n /**\n * @notice Set the borrow cap for a vToken\n * @param vTokens The vToken addresses\n * @param newCaps The new borrow caps\n */\n function setMarketBorrowCaps(address[] calldata vTokens, uint256[] calldata newCaps) external {\n uint256 numMarkets = vTokens.length;\n uint256 numBorrowCaps = newCaps.length;\n\n require(numMarkets != 0 && numMarkets == numBorrowCaps, \"invalid input\");\n\n for (uint256 i; i < numMarkets; ++i) {\n require(vTokenListed[vTokens[i]], \"vToken not listed\");\n borrowCaps[address(vTokens[i])] = newCaps[i];\n }\n }\n\n /**\n * @notice Set the collateral factor and liquidation threshold for a vToken\n * @param poolId The pool ID (0 for regular markets, >0 for eMode groups)\n * @param vToken The vToken address\n * @param newCollateralFactorMantissa The new collateral factor\n * @param newLiquidationThresholdMantissa The new liquidation threshold\n * @return Always returns 0\n */\n function setCollateralFactor(\n uint96 poolId,\n address vToken,\n uint256 newCollateralFactorMantissa,\n uint256 newLiquidationThresholdMantissa\n ) external returns (uint256) {\n require(vTokenListed[vToken], \"vToken not listed\");\n if (poolId == 0) {\n _collateralFactorMantissa[vToken] = newCollateralFactorMantissa;\n _liquidationThresholdMantissa[vToken] = newLiquidationThresholdMantissa;\n } else {\n _eModeCollateralFactorMantissa[poolId][vToken] = newCollateralFactorMantissa;\n _eModeLiquidationThresholdMantissa[poolId][vToken] = newLiquidationThresholdMantissa;\n }\n return 0;\n }\n\n /**\n * @notice Get market information (for compatibility with ICorePoolComptroller interface)\n * @param vToken The vToken address\n * @return isListed Whether the market is listed\n * @return collateralFactorMantissa The collateral factor\n * @return isVenus Whether it's a Venus market\n * @return liquidationThresholdMantissa The liquidation threshold\n * @return liquidationIncentiveMantissa The liquidation incentive\n * @return marketPoolId The pool ID\n * @return isBorrowAllowed Whether borrowing is allowed\n */\n function markets(\n address vToken\n )\n external\n view\n returns (\n bool isListed,\n uint256 collateralFactorMantissa,\n bool isVenus,\n uint256 liquidationThresholdMantissa,\n uint256 liquidationIncentiveMantissa,\n uint96 marketPoolId,\n bool isBorrowAllowed\n )\n {\n isListed = vTokenListed[vToken];\n collateralFactorMantissa = _collateralFactorMantissa[vToken];\n isVenus = false;\n liquidationThresholdMantissa = _liquidationThresholdMantissa[vToken];\n liquidationIncentiveMantissa = 0;\n marketPoolId = 0;\n isBorrowAllowed = true;\n }\n\n /**\n * @notice Get eMode pool market information (for compatibility with ICorePoolComptroller interface)\n * @param poolId The eMode pool ID\n * @param vToken The vToken address\n * @return isListed Whether the market is listed\n * @return collateralFactorMantissa The collateral factor\n * @return isVenus Whether it's a Venus market\n * @return liquidationThresholdMantissa The liquidation threshold\n * @return liquidationIncentiveMantissa The liquidation incentive\n * @return marketPoolId The pool ID\n * @return isBorrowAllowed Whether borrowing is allowed\n */\n function poolMarkets(\n uint96 poolId,\n address vToken\n )\n external\n view\n returns (\n bool isListed,\n uint256 collateralFactorMantissa,\n bool isVenus,\n uint256 liquidationThresholdMantissa,\n uint256 liquidationIncentiveMantissa,\n uint96 marketPoolId,\n bool isBorrowAllowed\n )\n {\n isListed = vTokenListed[vToken];\n collateralFactorMantissa = _eModeCollateralFactorMantissa[poolId][vToken];\n isVenus = false;\n liquidationThresholdMantissa = _eModeLiquidationThresholdMantissa[poolId][vToken];\n liquidationIncentiveMantissa = 0;\n marketPoolId = poolId;\n isBorrowAllowed = true;\n }\n\n /**\n * @notice Get all vTokens\n * @return Array of vToken addresses\n */\n function getAllMarkets() external view returns (ICorePoolVToken[] memory) {\n return allVTokens;\n }\n}\n"
},
"contracts/test/MockRiskOracle.sol": {
"content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.25;\n\nimport \"@openzeppelin/contracts/access/Ownable.sol\";\nimport \"@openzeppelin/contracts/utils/Strings.sol\";\n\n/**\n * @title Risk Oracle\n * @author Chaos Labs\n */\ncontract MockRiskOracle is Ownable {\n struct RiskParameterUpdate {\n uint256 timestamp; // Timestamp of the update\n bytes newValue; // Encoded parameters, flexible for various data types\n string referenceId; // External reference, potentially linking to a document or off-chain data\n bytes previousValue; // Previous value of the parameter for historical comparison\n string updateType; // Classification of the update for validation purposes\n uint256 updateId; // Unique identifier for this specific update\n address market; // Address for market of the parameter update\n bytes additionalData; // Additional data for the update\n }\n\n string[] private allUpdateTypes; // Array to store all update types\n mapping(string => bool) internal validUpdateTypes; // Whitelist of valid update type identifiers\n mapping(uint256 => RiskParameterUpdate) private updatesById; // Mapping from unique update ID to the update details\n mapping(address => bool) private authorizedSenders; // Authorized accounts capable of executing updates\n\n // Mapping to store the latest update ID for each combination of market and update type\n mapping(address => mapping(string => uint256)) public latestUpdateIdByMarketAndType;\n uint256 public updateCounter; // Counter to keep track of the total number of updates\n string public description; // Description of contract\n\n event ParameterUpdated(\n string referenceId,\n bytes newValue,\n bytes previousValue,\n uint256 timestamp,\n string indexed updateType,\n uint256 indexed updateId,\n address indexed market,\n bytes additionalData\n );\n\n event AuthorizedSenderAdded(address indexed sender);\n event AuthorizedSenderRemoved(address indexed sender);\n event UpdateTypeAdded(string indexed updateType);\n\n modifier onlyAuthorized() {\n require(authorizedSenders[msg.sender], \"Unauthorized: Sender not authorized.\");\n _;\n }\n\n modifier onlyValidString(string memory input) {\n require(bytes(input).length > 0 && bytes(input).length <= 64, \"Invalid update type string\");\n _;\n }\n\n /**\n * @notice Constructor to set initial authorized addresses and approved update types.\n * @param _description Description of contract\n * @param initialSenders List of addresses that will initially be authorized to perform updates.\n * @param initialUpdateTypes List of valid update types initially allowed.\n */\n constructor(\n string memory _description,\n address[] memory initialSenders,\n string[] memory initialUpdateTypes\n ) Ownable() {\n description = _description;\n for (uint256 i = 0; i < initialSenders.length; i++) {\n authorizedSenders[initialSenders[i]] = true; // Automatically authorize initial senders\n }\n for (uint256 i = 0; i < initialUpdateTypes.length; i++) {\n if (!validUpdateTypes[initialUpdateTypes[i]]) {\n // Ensure no duplicate updateTypes can be set\n validUpdateTypes[initialUpdateTypes[i]] = true; // Register initial valid updates\n allUpdateTypes.push(initialUpdateTypes[i]);\n emit UpdateTypeAdded(initialUpdateTypes[i]);\n }\n }\n }\n\n /**\n * @notice Adds a new sender to the list of addresses authorized to perform updates.\n * @param sender Address to be authorized.\n */\n function addAuthorizedSender(address sender) external onlyOwner {\n require(!authorizedSenders[sender], \"Sender already authorized.\");\n authorizedSenders[sender] = true;\n emit AuthorizedSenderAdded(sender);\n }\n\n /**\n * @notice Removes an address from the list of authorized senders.\n * @param sender Address to be unauthorized.\n */\n function removeAuthorizedSender(address sender) external onlyOwner {\n require(authorizedSenders[sender], \"Sender not authorized.\");\n authorizedSenders[sender] = false;\n emit AuthorizedSenderRemoved(sender);\n }\n\n /**\n * @notice Adds a new type of update to the list of authorized update types.\n * @param newUpdateType New type of update to allow.\n */\n function addUpdateType(string memory newUpdateType) external onlyOwner onlyValidString(newUpdateType) {\n require(!validUpdateTypes[newUpdateType], \"Update type already exists.\");\n validUpdateTypes[newUpdateType] = true;\n allUpdateTypes.push(newUpdateType);\n emit UpdateTypeAdded(newUpdateType);\n }\n\n /**\n * @notice Publishes a new risk parameter update.\n * @param referenceId An external reference ID associated with the update.\n * @param newValue The new value of the risk parameter being updated.\n * @param updateType Type of update performed, must be previously authorized.\n * @param market Address for market of the parameter update\n * @param additionalData Additional data for the update\n */\n function publishRiskParameterUpdate(\n string memory referenceId,\n bytes memory newValue,\n string memory updateType,\n address market,\n bytes memory additionalData\n ) external onlyAuthorized {\n _processUpdate(referenceId, newValue, updateType, market, additionalData);\n }\n\n /**\n * @notice Publishes multiple risk parameter updates in a single transaction.\n * @param referenceIds Array of external reference IDs.\n * @param newValues Array of new values for each update.\n * @param updateTypes Array of types for each update, all must be authorized.\n * @param markets Array of addresses for markets of the parameter updates\n * @param additionalData Array of additional data for the updates\n *\n */\n function publishBulkRiskParameterUpdates(\n string[] memory referenceIds,\n bytes[] memory newValues,\n string[] memory updateTypes,\n address[] memory markets,\n bytes[] memory additionalData\n ) external onlyAuthorized {\n for (uint256 i = 0; i < referenceIds.length; i++) {\n _processUpdate(referenceIds[i], newValues[i], updateTypes[i], markets[i], additionalData[i]);\n }\n }\n\n /**\n * @dev Processes an update internally, recording and emitting an event.\n */\n function _processUpdate(\n string memory referenceId,\n bytes memory newValue,\n string memory updateType,\n address market,\n bytes memory additionalData\n ) internal {\n require(validUpdateTypes[updateType], \"Unauthorized update type.\");\n updateCounter++;\n uint256 previousUpdateId = latestUpdateIdByMarketAndType[market][updateType];\n bytes memory previousValue = updatesById[previousUpdateId].newValue;\n\n RiskParameterUpdate memory newUpdate = RiskParameterUpdate(\n block.timestamp,\n newValue,\n referenceId,\n previousValue,\n updateType,\n updateCounter,\n market,\n additionalData\n );\n updatesById[updateCounter] = newUpdate;\n\n // Update the latest update ID for the market and updateType combination\n latestUpdateIdByMarketAndType[market][updateType] = updateCounter;\n\n emit ParameterUpdated(\n referenceId,\n newValue,\n previousValue,\n block.timestamp,\n updateType,\n updateCounter,\n market,\n additionalData\n );\n }\n\n function getAllUpdateTypes() external view returns (string[] memory) {\n return allUpdateTypes;\n }\n\n /**\n * @notice Fetches the most recent update for a specific parameter in a specific market.\n * @param updateType The identifier for the parameter.\n * @param market The market identifier.\n * @return The most recent RiskParameterUpdate for the specified parameter and market.\n */\n function getLatestUpdateByParameterAndMarket(\n string memory updateType,\n address market\n ) external view returns (RiskParameterUpdate memory) {\n uint256 updateId = latestUpdateIdByMarketAndType[market][updateType];\n require(updateId > 0, \"No update found for the specified parameter and market.\");\n return updatesById[updateId];\n }\n\n /*\n * @notice Fetches the update for a provided updateId.\n * @param updateId Update ID.\n * @return The most recent RiskParameterUpdate for the specified id.\n */\n function getUpdateById(uint256 updateId) external view returns (RiskParameterUpdate memory) {\n require(updateId > 0 && updateId <= updateCounter, \"Invalid update ID.\");\n return updatesById[updateId];\n }\n\n /**\n * @notice Checks if an address is authorized to perform updates.\n * @param sender Address to check.\n * @return Boolean indicating whether the address is authorized.\n */\n function isAuthorized(address sender) external view returns (bool) {\n return authorizedSenders[sender];\n }\n}\n"
},
"contracts/test/MockVToken.sol": {
"content": "// SPDX-License-Identifier: BSD-3-Clause\npragma solidity 0.8.25;\n\nimport { InterestRateModel } from \"@venusprotocol/isolated-pools/contracts/InterestRateModel.sol\";\nimport { InterestRateModelV8 } from \"@venusprotocol/venus-protocol/contracts/InterestRateModels/InterestRateModelV8.sol\";\n\ninterface IVToken {\n function comptroller() external view returns (address);\n}\n\ncontract MockVToken is IVToken {\n address public override comptroller;\n address public interestRateModel;\n\n constructor(address _comptroller) {\n comptroller = _comptroller;\n }\n\n function setInterestRateModel(InterestRateModel newInterestRateModel) external {\n interestRateModel = address(newInterestRateModel);\n }\n\n function _setInterestRateModel(InterestRateModelV8 newInterestRateModel) external returns (uint) {\n interestRateModel = address(newInterestRateModel);\n return 0;\n }\n}\n"
},
"contracts/test/MockXVSVault.sol": {
"content": "// SPDX-License-Identifier: BSD-3-Clause\npragma solidity 0.8.25;\n\ncontract MockXVSVault {\n /* solhint-disable no-unused-vars */\n function getPriorVotes(address account, uint256 blockNumber) external view returns (uint96) {\n /* solhint-enable no-unused-vars */\n return 0;\n }\n}\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"
},
"contracts/Utils/ACMCommandsAggregator.sol": {
"content": "// SPDX-License-Identifier: BSD-3-Clause\npragma solidity 0.8.25;\n\nimport { IAccessControlManagerV8 } from \"../Governance/IAccessControlManagerV8.sol\";\nimport { ensureNonzeroAddress } from \"@venusprotocol/solidity-utilities/contracts/validators.sol\";\n\n/**\n * @title ACMCommandsAggregator\n * @author Venus\n * @notice This contract is a helper to aggregate multiple grant and revoke permissions in batches and execute them in one go.\n */\ncontract ACMCommandsAggregator {\n /*\n * @notice Struct to store permission details\n */\n struct Permission {\n /*\n * @notice Address of the contract\n */\n address contractAddress;\n /*\n * @notice Function signature\n */\n string functionSig;\n /*\n * @notice Address of the account\n */\n address account;\n }\n\n /**\n * @notice Access control manager contract\n */\n IAccessControlManagerV8 public immutable ACM;\n\n /*\n * @notice 2D array to store grant permissions in batches\n */\n Permission[][] public grantPermissions;\n\n /*\n * @notice 2D array to store revoke permissions in batches\n */\n Permission[][] public revokePermissions;\n\n /*\n * @notice Event emitted when grant permissions are added\n */\n event GrantPermissionsAdded(uint256 index);\n\n /*\n * @notice Event emitted when revoke permissions are added\n */\n event RevokePermissionsAdded(uint256 index);\n\n /*\n * @notice Event emitted when grant permissions are executed\n */\n event GrantPermissionsExecuted(uint256 index);\n\n /*\n * @notice Event emitted when revoke permissions are executed\n */\n event RevokePermissionsExecuted(uint256 index);\n\n /*\n * @notice Error to be thrown when permissions are empty\n */\n error EmptyPermissions();\n\n /*\n * @notice Constructor to set the access control manager\n * @param _acm Address of the access control manager\n */\n constructor(IAccessControlManagerV8 _acm) {\n ensureNonzeroAddress(address(_acm));\n ACM = _acm;\n }\n\n /*\n * @notice Function to add grant permissions\n * @param _permissions Array of permissions\n * @custom:event Emits GrantPermissionsAdded event\n */\n function addGrantPermissions(Permission[] memory _permissions) external {\n if (_permissions.length == 0) {\n revert EmptyPermissions();\n }\n\n uint256 index = grantPermissions.length;\n grantPermissions.push();\n\n for (uint256 i; i < _permissions.length; ++i) {\n grantPermissions[index].push(\n Permission(_permissions[i].contractAddress, _permissions[i].functionSig, _permissions[i].account)\n );\n }\n\n emit GrantPermissionsAdded(index);\n }\n\n /*\n * @notice Function to add revoke permissions\n * @param _permissions Array of permissions\n * @custom:event Emits RevokePermissionsAdded event\n */\n function addRevokePermissions(Permission[] memory _permissions) external {\n if (_permissions.length == 0) {\n revert EmptyPermissions();\n }\n\n uint256 index = revokePermissions.length;\n revokePermissions.push();\n\n for (uint256 i; i < _permissions.length; ++i) {\n revokePermissions[index].push(\n Permission(_permissions[i].contractAddress, _permissions[i].functionSig, _permissions[i].account)\n );\n }\n\n emit RevokePermissionsAdded(index);\n }\n\n /*\n * @notice Function to execute grant permissions\n * @param index Index of the permissions array\n * @custom:event Emits GrantPermissionsExecuted event\n */\n function executeGrantPermissions(uint256 index) external {\n uint256 length = grantPermissions[index].length;\n for (uint256 i; i < length; ++i) {\n Permission memory permission = grantPermissions[index][i];\n ACM.giveCallPermission(permission.contractAddress, permission.functionSig, permission.account);\n }\n\n emit GrantPermissionsExecuted(index);\n }\n\n /*\n * @notice Function to execute revoke permissions\n * @param index Index of the permissions array\n * @custom:event Emits RevokePermissionsExecuted event\n */\n function executeRevokePermissions(uint256 index) external {\n uint256 length = revokePermissions[index].length;\n for (uint256 i; i < length; ++i) {\n Permission memory permission = revokePermissions[index][i];\n ACM.revokeCallPermission(permission.contractAddress, permission.functionSig, permission.account);\n }\n\n emit RevokePermissionsExecuted(index);\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 /**\n * @dev Storage slot with the address of the current implementation.\n * This is the keccak-256 hash of \"eip1967.proxy.implementation\" subtracted by 1, and is\n * validated in the constructor.\n */\n bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\n\n /**\n * @dev Emitted when the implementation is upgraded.\n */\n event Upgraded(address indexed implementation);\n\n /**\n * @dev Returns the current implementation address.\n */\n function _getImplementation() internal view returns (address) {\n return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value;\n }\n\n /**\n * @dev Stores a new address in the EIP1967 implementation slot.\n */\n function _setImplementation(address newImplementation) private {\n require(Address.isContract(newImplementation), \"ERC1967: new implementation is not a contract\");\n StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation;\n }\n\n /**\n * @dev Perform implementation upgrade\n *\n * Emits an {Upgraded} event.\n */\n function _upgradeTo(address newImplementation) internal {\n _setImplementation(newImplementation);\n emit Upgraded(newImplementation);\n }\n\n /**\n * @dev Perform implementation upgrade with additional setup call.\n *\n * Emits an {Upgraded} event.\n */\n function _upgradeToAndCall(\n address newImplementation,\n bytes memory data,\n bool forceCall\n ) internal {\n _upgradeTo(newImplementation);\n if (data.length > 0 || forceCall) {\n Address.functionDelegateCall(newImplementation, data);\n }\n }\n\n /**\n * @dev Perform implementation upgrade with security checks for UUPS proxies, and additional setup call.\n *\n * Emits an {Upgraded} event.\n */\n function _upgradeToAndCallUUPS(\n address newImplementation,\n bytes memory data,\n bool forceCall\n ) internal {\n // Upgrades from old implementations will perform a rollback test. This test requires the new\n // implementation to upgrade back to the old, non-ERC1822 compliant, implementation. Removing\n // this special case will break upgrade paths from old UUPS implementation to new ones.\n if (StorageSlot.getBooleanSlot(_ROLLBACK_SLOT).value) {\n _setImplementation(newImplementation);\n } else {\n try IERC1822Proxiable(newImplementation).proxiableUUID() returns (bytes32 slot) {\n require(slot == _IMPLEMENTATION_SLOT, \"ERC1967Upgrade: unsupported proxiableUUID\");\n } catch {\n revert(\"ERC1967Upgrade: new implementation is not UUPS\");\n }\n _upgradeToAndCall(newImplementation, data, forceCall);\n }\n }\n\n /**\n * @dev Storage slot with the admin of the contract.\n * This is the keccak-256 hash of \"eip1967.proxy.admin\" subtracted by 1, and is\n * validated in the constructor.\n */\n bytes32 internal constant _ADMIN_SLOT = 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103;\n\n /**\n * @dev Emitted when the admin account has changed.\n */\n event AdminChanged(address previousAdmin, address newAdmin);\n\n /**\n * @dev Returns the current admin.\n */\n function _getAdmin() internal view virtual returns (address) {\n return StorageSlot.getAddressSlot(_ADMIN_SLOT).value;\n }\n\n /**\n * @dev Stores a new address in the EIP1967 admin slot.\n */\n function _setAdmin(address newAdmin) private {\n require(newAdmin != address(0), \"ERC1967: new admin is the zero address\");\n StorageSlot.getAddressSlot(_ADMIN_SLOT).value = newAdmin;\n }\n\n /**\n * @dev Changes the admin of the proxy.\n *\n * Emits an {AdminChanged} event.\n */\n function _changeAdmin(address newAdmin) internal {\n emit AdminChanged(_getAdmin(), newAdmin);\n _setAdmin(newAdmin);\n }\n\n /**\n * @dev The storage slot of the UpgradeableBeacon contract which defines the implementation for this proxy.\n * This is bytes32(uint256(keccak256('eip1967.proxy.beacon')) - 1)) and is validated in the constructor.\n */\n bytes32 internal constant _BEACON_SLOT = 0xa3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6cb3582b35133d50;\n\n /**\n * @dev Emitted when the beacon is upgraded.\n */\n event BeaconUpgraded(address indexed beacon);\n\n /**\n * @dev Returns the current beacon.\n */\n function _getBeacon() internal view returns (address) {\n return StorageSlot.getAddressSlot(_BEACON_SLOT).value;\n }\n\n /**\n * @dev Stores a new beacon in the EIP1967 beacon slot.\n */\n function _setBeacon(address newBeacon) private {\n require(Address.isContract(newBeacon), \"ERC1967: new beacon is not a contract\");\n require(Address.isContract(IBeacon(newBeacon).implementation()), \"ERC1967: beacon implementation is not a contract\");\n StorageSlot.getAddressSlot(_BEACON_SLOT).value = newBeacon;\n }\n\n /**\n * @dev Perform beacon upgrade with additional setup call. Note: This upgrades the address of the beacon, it does\n * not upgrade the implementation contained in the beacon (see {UpgradeableBeacon-_setImplementation} for that).\n *\n * Emits a {BeaconUpgraded} event.\n */\n function _upgradeBeaconToAndCall(\n address newBeacon,\n bytes memory data,\n bool forceCall\n ) internal {\n _setBeacon(newBeacon);\n emit BeaconUpgraded(newBeacon);\n if (data.length > 0 || forceCall) {\n Address.functionDelegateCall(IBeacon(newBeacon).implementation(), data);\n }\n }\n}\n"
},
"hardhat-deploy/solc_0.8/openzeppelin/proxy/Proxy.sol": {
"content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0-rc.0) (proxy/Proxy.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev This abstract contract provides a fallback function that delegates all calls to another contract using the EVM\n * instruction `delegatecall`. We refer to the second contract as the _implementation_ behind the proxy, and it has to\n * be specified by overriding the virtual {_implementation} function.\n *\n * Additionally, delegation to the implementation can be triggered manually through the {_fallback} function, or to a\n * different contract through the {_delegate} function.\n *\n * The success and return data of the delegated call will be returned back to the caller of the proxy.\n */\nabstract contract Proxy {\n /**\n * @dev Delegates the current call to `implementation`.\n *\n * This function does not return to its internal call site, it will return directly to the external caller.\n */\n function _delegate(address implementation) internal virtual {\n assembly {\n // Copy msg.data. We take full control of memory in this inline assembly\n // block because it will not return to Solidity code. We overwrite the\n // Solidity scratch pad at memory position 0.\n calldatacopy(0, 0, calldatasize())\n\n // Call the implementation.\n // out and outsize are 0 because we don't know the size yet.\n let result := delegatecall(gas(), implementation, 0, calldatasize(), 0, 0)\n\n // Copy the returned data.\n returndatacopy(0, 0, returndatasize())\n\n switch result\n // delegatecall returns 0 on error.\n case 0 {\n revert(0, returndatasize())\n }\n default {\n return(0, returndatasize())\n }\n }\n }\n\n /**\n * @dev This is a virtual function that should be overriden so it returns the address to which the fallback function\n * and {_fallback} should delegate.\n */\n function _implementation() internal view virtual returns (address);\n\n /**\n * @dev Delegates the current call to the address returned by `_implementation()`.\n *\n * This function does not return to its internall call site, it will return directly to the external caller.\n */\n function _fallback() internal virtual {\n _beforeFallback();\n _delegate(_implementation());\n }\n\n /**\n * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if no other\n * function in the contract matches the call data.\n */\n fallback() external payable virtual {\n _fallback();\n }\n\n /**\n * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if call data\n * is empty.\n */\n receive() external payable virtual {\n _fallback();\n }\n\n /**\n * @dev Hook that is called before falling back to the implementation. Can happen as part of a manual `_fallback`\n * call, or as part of the Solidity `fallback` or `receive` functions.\n *\n * If overriden should call `super._beforeFallback()`.\n */\n function _beforeFallback() internal virtual {}\n}\n"
},
"hardhat-deploy/solc_0.8/openzeppelin/proxy/transparent/ProxyAdmin.sol": {
"content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (proxy/transparent/ProxyAdmin.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./TransparentUpgradeableProxy.sol\";\nimport \"../../access/Ownable.sol\";\n\n/**\n * @dev This is an auxiliary contract meant to be assigned as the admin of a {TransparentUpgradeableProxy}. For an\n * explanation of why you would want to use this see the documentation for {TransparentUpgradeableProxy}.\n */\ncontract ProxyAdmin is Ownable {\n\n constructor (address initialOwner) Ownable(initialOwner) {}\n\n /**\n * @dev Returns the current implementation of `proxy`.\n *\n * Requirements:\n *\n * - This contract must be the admin of `proxy`.\n */\n function getProxyImplementation(TransparentUpgradeableProxy proxy) public view virtual returns (address) {\n // We need to manually run the static call since the getter cannot be flagged as view\n // bytes4(keccak256(\"implementation()\")) == 0x5c60da1b\n (bool success, bytes memory returndata) = address(proxy).staticcall(hex\"5c60da1b\");\n require(success);\n return abi.decode(returndata, (address));\n }\n\n /**\n * @dev Returns the current admin of `proxy`.\n *\n * Requirements:\n *\n * - This contract must be the admin of `proxy`.\n */\n function getProxyAdmin(TransparentUpgradeableProxy proxy) public view virtual returns (address) {\n // We need to manually run the static call since the getter cannot be flagged as view\n // bytes4(keccak256(\"admin()\")) == 0xf851a440\n (bool success, bytes memory returndata) = address(proxy).staticcall(hex\"f851a440\");\n require(success);\n return abi.decode(returndata, (address));\n }\n\n /**\n * @dev Changes the admin of `proxy` to `newAdmin`.\n *\n * Requirements:\n *\n * - This contract must be the current admin of `proxy`.\n */\n function changeProxyAdmin(TransparentUpgradeableProxy proxy, address newAdmin) public virtual onlyOwner {\n proxy.changeAdmin(newAdmin);\n }\n\n /**\n * @dev Upgrades `proxy` to `implementation`. See {TransparentUpgradeableProxy-upgradeTo}.\n *\n * Requirements:\n *\n * - This contract must be the admin of `proxy`.\n */\n function upgrade(TransparentUpgradeableProxy proxy, address implementation) public virtual onlyOwner {\n proxy.upgradeTo(implementation);\n }\n\n /**\n * @dev Upgrades `proxy` to `implementation` and calls a function on the new implementation. See\n * {TransparentUpgradeableProxy-upgradeToAndCall}.\n *\n * Requirements:\n *\n * - This contract must be the admin of `proxy`.\n */\n function upgradeAndCall(\n TransparentUpgradeableProxy proxy,\n address implementation,\n bytes memory data\n ) public payable virtual onlyOwner {\n proxy.upgradeToAndCall{value: msg.value}(implementation, data);\n }\n}\n"
},
"hardhat-deploy/solc_0.8/openzeppelin/proxy/transparent/TransparentUpgradeableProxy.sol": {
"content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (proxy/transparent/TransparentUpgradeableProxy.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../ERC1967/ERC1967Proxy.sol\";\n\n/**\n * @dev This contract implements a proxy that is upgradeable by an admin.\n *\n * To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector\n * clashing], which can potentially be used in an attack, this contract uses the\n * https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two\n * things that go hand in hand:\n *\n * 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if\n * that call matches one of the admin functions exposed by the proxy itself.\n * 2. If the admin calls the proxy, it can access the admin functions, but its calls will never be forwarded to the\n * implementation. If the admin tries to call a function on the implementation it will fail with an error that says\n * \"admin cannot fallback to proxy target\".\n *\n * These properties mean that the admin account can only be used for admin actions like upgrading the proxy or changing\n * the admin, so it's best if it's a dedicated account that is not used for anything else. This will avoid headaches due\n * to sudden errors when trying to call a function from the proxy implementation.\n *\n * Our recommendation is for the dedicated account to be an instance of the {ProxyAdmin} contract. If set up this way,\n * you should think of the `ProxyAdmin` instance as the real administrative interface of your proxy.\n */\ncontract TransparentUpgradeableProxy is ERC1967Proxy {\n /**\n * @dev Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and\n * optionally initialized with `_data` as explained in {ERC1967Proxy-constructor}.\n */\n constructor(\n address _logic,\n address admin_,\n bytes memory _data\n ) payable ERC1967Proxy(_logic, _data) {\n assert(_ADMIN_SLOT == bytes32(uint256(keccak256(\"eip1967.proxy.admin\")) - 1));\n _changeAdmin(admin_);\n }\n\n /**\n * @dev Modifier used internally that will delegate the call to the implementation unless the sender is the admin.\n */\n modifier ifAdmin() {\n if (msg.sender == _getAdmin()) {\n _;\n } else {\n _fallback();\n }\n }\n\n /**\n * @dev Returns the current admin.\n *\n * NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}.\n *\n * TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the\n * https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.\n * `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`\n */\n function admin() external ifAdmin returns (address admin_) {\n admin_ = _getAdmin();\n }\n\n /**\n * @dev Returns the current implementation.\n *\n * NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}.\n *\n * TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the\n * https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.\n * `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`\n */\n function implementation() external ifAdmin returns (address implementation_) {\n implementation_ = _implementation();\n }\n\n /**\n * @dev Changes the admin of the proxy.\n *\n * Emits an {AdminChanged} event.\n *\n * NOTE: Only the admin can call this function. See {ProxyAdmin-changeProxyAdmin}.\n */\n function changeAdmin(address newAdmin) external virtual ifAdmin {\n _changeAdmin(newAdmin);\n }\n\n /**\n * @dev Upgrade the implementation of the proxy.\n *\n * NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}.\n */\n function upgradeTo(address newImplementation) external ifAdmin {\n _upgradeToAndCall(newImplementation, bytes(\"\"), false);\n }\n\n /**\n * @dev Upgrade the implementation of the proxy, and then call a function from the new implementation as specified\n * by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the\n * proxied contract.\n *\n * NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}.\n */\n function upgradeToAndCall(address newImplementation, bytes calldata data) external payable ifAdmin {\n _upgradeToAndCall(newImplementation, data, true);\n }\n\n /**\n * @dev Returns the current admin.\n */\n function _admin() internal view virtual returns (address) {\n return _getAdmin();\n }\n\n /**\n * @dev Makes sure the admin cannot access the fallback function. See {Proxy-_beforeFallback}.\n */\n function _beforeFallback() internal virtual override {\n require(msg.sender != _getAdmin(), \"TransparentUpgradeableProxy: admin cannot fallback to proxy target\");\n super._beforeFallback();\n }\n}\n"
},
"hardhat-deploy/solc_0.8/openzeppelin/utils/Address.sol": {
"content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0-rc.0) (utils/Address.sol)\n\npragma solidity ^0.8.1;\n\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary Address {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length > 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance >= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance >= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionDelegateCall(target, data, \"Address: low-level delegate call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(isContract(target), \"Address: delegate call to non-contract\");\n\n (bool success, bytes memory returndata) = target.delegatecall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length > 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n"
},
"hardhat-deploy/solc_0.8/openzeppelin/utils/Context.sol": {
"content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract Context {\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n}\n"
},
"hardhat-deploy/solc_0.8/openzeppelin/utils/StorageSlot.sol": {
"content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/StorageSlot.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Library for reading and writing primitive types to specific storage slots.\n *\n * Storage slots are often used to avoid storage conflict when dealing with upgradeable contracts.\n * This library helps with reading and writing to such slots without the need for inline assembly.\n *\n * The functions in this library return Slot structs that contain a `value` member that can be used to read or write.\n *\n * Example usage to set ERC1967 implementation slot:\n * ```\n * contract ERC1967 {\n * bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\n *\n * function _getImplementation() internal view returns (address) {\n * return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value;\n * }\n *\n * function _setImplementation(address newImplementation) internal {\n * require(Address.isContract(newImplementation), \"ERC1967: new implementation is not a contract\");\n * StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation;\n * }\n * }\n * ```\n *\n * _Available since v4.1 for `address`, `bool`, `bytes32`, and `uint256`._\n */\nlibrary StorageSlot {\n struct AddressSlot {\n address value;\n }\n\n struct BooleanSlot {\n bool value;\n }\n\n struct Bytes32Slot {\n bytes32 value;\n }\n\n struct Uint256Slot {\n uint256 value;\n }\n\n /**\n * @dev Returns an `AddressSlot` with member `value` located at `slot`.\n */\n function getAddressSlot(bytes32 slot) internal pure returns (AddressSlot storage r) {\n assembly {\n r.slot := slot\n }\n }\n\n /**\n * @dev Returns an `BooleanSlot` with member `value` located at `slot`.\n */\n function getBooleanSlot(bytes32 slot) internal pure returns (BooleanSlot storage r) {\n assembly {\n r.slot := slot\n }\n }\n\n /**\n * @dev Returns an `Bytes32Slot` with member `value` located at `slot`.\n */\n function getBytes32Slot(bytes32 slot) internal pure returns (Bytes32Slot storage r) {\n assembly {\n r.slot := slot\n }\n }\n\n /**\n * @dev Returns an `Uint256Slot` with member `value` located at `slot`.\n */\n function getUint256Slot(bytes32 slot) internal pure returns (Uint256Slot storage r) {\n assembly {\n r.slot := slot\n }\n }\n}\n"
},
"hardhat-deploy/solc_0.8/proxy/OptimizedTransparentUpgradeableProxy.sol": {
"content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (proxy/transparent/TransparentUpgradeableProxy.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../openzeppelin/proxy/ERC1967/ERC1967Proxy.sol\";\n\n/**\n * @dev This contract implements a proxy that is upgradeable by an admin.\n *\n * To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector\n * clashing], which can potentially be used in an attack, this contract uses the\n * https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two\n * things that go hand in hand:\n *\n * 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if\n * that call matches one of the admin functions exposed by the proxy itself.\n * 2. If the admin calls the proxy, it can access the admin functions, but its calls will never be forwarded to the\n * implementation. If the admin tries to call a function on the implementation it will fail with an error that says\n * \"admin cannot fallback to proxy target\".\n *\n * These properties mean that the admin account can only be used for admin actions like upgrading the proxy or changing\n * the admin, so it's best if it's a dedicated account that is not used for anything else. This will avoid headaches due\n * to sudden errors when trying to call a function from the proxy implementation.\n *\n * Our recommendation is for the dedicated account to be an instance of the {ProxyAdmin} contract. If set up this way,\n * you should think of the `ProxyAdmin` instance as the real administrative interface of your proxy.\n */\ncontract OptimizedTransparentUpgradeableProxy is ERC1967Proxy {\n address internal immutable _ADMIN;\n\n /**\n * @dev Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and\n * optionally initialized with `_data` as explained in {ERC1967Proxy-constructor}.\n */\n constructor(\n address _logic,\n address admin_,\n bytes memory _data\n ) payable ERC1967Proxy(_logic, _data) {\n assert(_ADMIN_SLOT == bytes32(uint256(keccak256(\"eip1967.proxy.admin\")) - 1));\n _ADMIN = admin_;\n\n // still store it to work with EIP-1967\n bytes32 slot = _ADMIN_SLOT;\n // solhint-disable-next-line no-inline-assembly\n assembly {\n sstore(slot, admin_)\n }\n emit AdminChanged(address(0), admin_);\n }\n\n /**\n * @dev Modifier used internally that will delegate the call to the implementation unless the sender is the admin.\n */\n modifier ifAdmin() {\n if (msg.sender == _getAdmin()) {\n _;\n } else {\n _fallback();\n }\n }\n\n /**\n * @dev Returns the current admin.\n *\n * NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}.\n *\n * TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the\n * https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.\n * `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`\n */\n function admin() external ifAdmin returns (address admin_) {\n admin_ = _getAdmin();\n }\n\n /**\n * @dev Returns the current implementation.\n *\n * NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}.\n *\n * TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the\n * https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.\n * `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`\n */\n function implementation() external ifAdmin returns (address implementation_) {\n implementation_ = _implementation();\n }\n\n /**\n * @dev Upgrade the implementation of the proxy.\n *\n * NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}.\n */\n function upgradeTo(address newImplementation) external ifAdmin {\n _upgradeToAndCall(newImplementation, bytes(\"\"), false);\n }\n\n /**\n * @dev Upgrade the implementation of the proxy, and then call a function from the new implementation as specified\n * by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the\n * proxied contract.\n *\n * NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}.\n */\n function upgradeToAndCall(address newImplementation, bytes calldata data) external payable ifAdmin {\n _upgradeToAndCall(newImplementation, data, true);\n }\n\n /**\n * @dev Returns the current admin.\n */\n function _admin() internal view virtual returns (address) {\n return _getAdmin();\n }\n\n /**\n * @dev Makes sure the admin cannot access the fallback function. See {Proxy-_beforeFallback}.\n */\n function _beforeFallback() internal virtual override {\n require(msg.sender != _getAdmin(), \"TransparentUpgradeableProxy: admin cannot fallback to proxy target\");\n super._beforeFallback();\n }\n\n function _getAdmin() internal view virtual override returns (address) {\n return _ADMIN;\n }\n}\n"
},
"solidity-bytes-utils/contracts/BytesLib.sol": {
"content": "// SPDX-License-Identifier: Unlicense\n/*\n * @title Solidity Bytes Arrays Utils\n * @author Gonçalo Sá <goncalo.sa@consensys.net>\n *\n * @dev Bytes tightly packed arrays utility library for ethereum contracts written in Solidity.\n * The library lets you concatenate, slice and type cast bytes arrays both in memory and storage.\n */\npragma solidity >=0.8.0 <0.9.0;\n\n\nlibrary BytesLib {\n function concat(\n bytes memory _preBytes,\n bytes memory _postBytes\n )\n internal\n pure\n returns (bytes memory)\n {\n bytes memory tempBytes;\n\n assembly {\n // Get a location of some free memory and store it in tempBytes as\n // Solidity does for memory variables.\n tempBytes := mload(0x40)\n\n // Store the length of the first bytes array at the beginning of\n // the memory for tempBytes.\n let length := mload(_preBytes)\n mstore(tempBytes, length)\n\n // Maintain a memory counter for the current write location in the\n // temp bytes array by adding the 32 bytes for the array length to\n // the starting location.\n let mc := add(tempBytes, 0x20)\n // Stop copying when the memory counter reaches the length of the\n // first bytes array.\n let end := add(mc, length)\n\n for {\n // Initialize a copy counter to the start of the _preBytes data,\n // 32 bytes into its memory.\n let cc := add(_preBytes, 0x20)\n } lt(mc, end) {\n // Increase both counters by 32 bytes each iteration.\n mc := add(mc, 0x20)\n cc := add(cc, 0x20)\n } {\n // Write the _preBytes data into the tempBytes memory 32 bytes\n // at a time.\n mstore(mc, mload(cc))\n }\n\n // Add the length of _postBytes to the current length of tempBytes\n // and store it as the new length in the first 32 bytes of the\n // tempBytes memory.\n length := mload(_postBytes)\n mstore(tempBytes, add(length, mload(tempBytes)))\n\n // Move the memory counter back from a multiple of 0x20 to the\n // actual end of the _preBytes data.\n mc := end\n // Stop copying when the memory counter reaches the new combined\n // length of the arrays.\n end := add(mc, length)\n\n for {\n let cc := add(_postBytes, 0x20)\n } lt(mc, end) {\n mc := add(mc, 0x20)\n cc := add(cc, 0x20)\n } {\n mstore(mc, mload(cc))\n }\n\n // Update the free-memory pointer by padding our last write location\n // to 32 bytes: add 31 bytes to the end of tempBytes to move to the\n // next 32 byte block, then round down to the nearest multiple of\n // 32. If the sum of the length of the two arrays is zero then add\n // one before rounding down to leave a blank 32 bytes (the length block with 0).\n mstore(0x40, and(\n add(add(end, iszero(add(length, mload(_preBytes)))), 31),\n not(31) // Round down to the nearest 32 bytes.\n ))\n }\n\n return tempBytes;\n }\n\n function concatStorage(bytes storage _preBytes, bytes memory _postBytes) internal {\n assembly {\n // Read the first 32 bytes of _preBytes storage, which is the length\n // of the array. (We don't need to use the offset into the slot\n // because arrays use the entire slot.)\n let fslot := sload(_preBytes.slot)\n // Arrays of 31 bytes or less have an even value in their slot,\n // while longer arrays have an odd value. The actual length is\n // the slot divided by two for odd values, and the lowest order\n // byte divided by two for even values.\n // If the slot is even, bitwise and the slot with 255 and divide by\n // two to get the length. If the slot is odd, bitwise and the slot\n // with -1 and divide by two.\n let slength := div(and(fslot, sub(mul(0x100, iszero(and(fslot, 1))), 1)), 2)\n let mlength := mload(_postBytes)\n let newlength := add(slength, mlength)\n // slength can contain both the length and contents of the array\n // if length < 32 bytes so let's prepare for that\n // v. http://solidity.readthedocs.io/en/latest/miscellaneous.html#layout-of-state-variables-in-storage\n switch add(lt(slength, 32), lt(newlength, 32))\n case 2 {\n // Since the new array still fits in the slot, we just need to\n // update the contents of the slot.\n // uint256(bytes_storage) = uint256(bytes_storage) + uint256(bytes_memory) + new_length\n sstore(\n _preBytes.slot,\n // all the modifications to the slot are inside this\n // next block\n add(\n // we can just add to the slot contents because the\n // bytes we want to change are the LSBs\n fslot,\n add(\n mul(\n div(\n // load the bytes from memory\n mload(add(_postBytes, 0x20)),\n // zero all bytes to the right\n exp(0x100, sub(32, mlength))\n ),\n // and now shift left the number of bytes to\n // leave space for the length in the slot\n exp(0x100, sub(32, newlength))\n ),\n // increase length by the double of the memory\n // bytes length\n mul(mlength, 2)\n )\n )\n )\n }\n case 1 {\n // The stored value fits in the slot, but the combined value\n // will exceed it.\n // get the keccak hash to get the contents of the array\n mstore(0x0, _preBytes.slot)\n let sc := add(keccak256(0x0, 0x20), div(slength, 32))\n\n // save new length\n sstore(_preBytes.slot, add(mul(newlength, 2), 1))\n\n // The contents of the _postBytes array start 32 bytes into\n // the structure. Our first read should obtain the `submod`\n // bytes that can fit into the unused space in the last word\n // of the stored array. To get this, we read 32 bytes starting\n // from `submod`, so the data we read overlaps with the array\n // contents by `submod` bytes. Masking the lowest-order\n // `submod` bytes allows us to add that value directly to the\n // stored value.\n\n let submod := sub(32, slength)\n let mc := add(_postBytes, submod)\n let end := add(_postBytes, mlength)\n let mask := sub(exp(0x100, submod), 1)\n\n sstore(\n sc,\n add(\n and(\n fslot,\n 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00\n ),\n and(mload(mc), mask)\n )\n )\n\n for {\n mc := add(mc, 0x20)\n sc := add(sc, 1)\n } lt(mc, end) {\n sc := add(sc, 1)\n mc := add(mc, 0x20)\n } {\n sstore(sc, mload(mc))\n }\n\n mask := exp(0x100, sub(mc, end))\n\n sstore(sc, mul(div(mload(mc), mask), mask))\n }\n default {\n // get the keccak hash to get the contents of the array\n mstore(0x0, _preBytes.slot)\n // Start copying to the last used word of the stored array.\n let sc := add(keccak256(0x0, 0x20), div(slength, 32))\n\n // save new length\n sstore(_preBytes.slot, add(mul(newlength, 2), 1))\n\n // Copy over the first `submod` bytes of the new data as in\n // case 1 above.\n let slengthmod := mod(slength, 32)\n let mlengthmod := mod(mlength, 32)\n let submod := sub(32, slengthmod)\n let mc := add(_postBytes, submod)\n let end := add(_postBytes, mlength)\n let mask := sub(exp(0x100, submod), 1)\n\n sstore(sc, add(sload(sc), and(mload(mc), mask)))\n\n for {\n sc := add(sc, 1)\n mc := add(mc, 0x20)\n } lt(mc, end) {\n sc := add(sc, 1)\n mc := add(mc, 0x20)\n } {\n sstore(sc, mload(mc))\n }\n\n mask := exp(0x100, sub(mc, end))\n\n sstore(sc, mul(div(mload(mc), mask), mask))\n }\n }\n }\n\n function slice(\n bytes memory _bytes,\n uint256 _start,\n uint256 _length\n )\n internal\n pure\n returns (bytes memory)\n {\n // We're using the unchecked block below because otherwise execution ends \n // with the native overflow error code.\n unchecked {\n require(_length + 31 >= _length, \"slice_overflow\");\n }\n require(_bytes.length >= _start + _length, \"slice_outOfBounds\");\n\n bytes memory tempBytes;\n\n assembly {\n switch iszero(_length)\n case 0 {\n // Get a location of some free memory and store it in tempBytes as\n // Solidity does for memory variables.\n tempBytes := mload(0x40)\n\n // The first word of the slice result is potentially a partial\n // word read from the original array. To read it, we calculate\n // the length of that partial word and start copying that many\n // bytes into the array. The first word we copy will start with\n // data we don't care about, but the last `lengthmod` bytes will\n // land at the beginning of the contents of the new array. When\n // we're done copying, we overwrite the full first word with\n // the actual length of the slice.\n let lengthmod := and(_length, 31)\n\n // The multiplication in the next line is necessary\n // because when slicing multiples of 32 bytes (lengthmod == 0)\n // the following copy loop was copying the origin's length\n // and then ending prematurely not copying everything it should.\n let mc := add(add(tempBytes, lengthmod), mul(0x20, iszero(lengthmod)))\n let end := add(mc, _length)\n\n for {\n // The multiplication in the next line has the same exact purpose\n // as the one above.\n let cc := add(add(add(_bytes, lengthmod), mul(0x20, iszero(lengthmod))), _start)\n } lt(mc, end) {\n mc := add(mc, 0x20)\n cc := add(cc, 0x20)\n } {\n mstore(mc, mload(cc))\n }\n\n mstore(tempBytes, _length)\n\n //update free-memory pointer\n //allocating the array padded to 32 bytes like the compiler does now\n mstore(0x40, and(add(mc, 31), not(31)))\n }\n //if we want a zero-length slice let's just return a zero-length array\n default {\n tempBytes := mload(0x40)\n //zero out the 32 bytes slice we are about to return\n //we need to do it because Solidity does not garbage collect\n mstore(tempBytes, 0)\n\n mstore(0x40, add(tempBytes, 0x20))\n }\n }\n\n return tempBytes;\n }\n\n function toAddress(bytes memory _bytes, uint256 _start) internal pure returns (address) {\n require(_bytes.length >= _start + 20, \"toAddress_outOfBounds\");\n address tempAddress;\n\n assembly {\n tempAddress := div(mload(add(add(_bytes, 0x20), _start)), 0x1000000000000000000000000)\n }\n\n return tempAddress;\n }\n\n function toUint8(bytes memory _bytes, uint256 _start) internal pure returns (uint8) {\n require(_bytes.length >= _start + 1 , \"toUint8_outOfBounds\");\n uint8 tempUint;\n\n assembly {\n tempUint := mload(add(add(_bytes, 0x1), _start))\n }\n\n return tempUint;\n }\n\n function toUint16(bytes memory _bytes, uint256 _start) internal pure returns (uint16) {\n require(_bytes.length >= _start + 2, \"toUint16_outOfBounds\");\n uint16 tempUint;\n\n assembly {\n tempUint := mload(add(add(_bytes, 0x2), _start))\n }\n\n return tempUint;\n }\n\n function toUint32(bytes memory _bytes, uint256 _start) internal pure returns (uint32) {\n require(_bytes.length >= _start + 4, \"toUint32_outOfBounds\");\n uint32 tempUint;\n\n assembly {\n tempUint := mload(add(add(_bytes, 0x4), _start))\n }\n\n return tempUint;\n }\n\n function toUint64(bytes memory _bytes, uint256 _start) internal pure returns (uint64) {\n require(_bytes.length >= _start + 8, \"toUint64_outOfBounds\");\n uint64 tempUint;\n\n assembly {\n tempUint := mload(add(add(_bytes, 0x8), _start))\n }\n\n return tempUint;\n }\n\n function toUint96(bytes memory _bytes, uint256 _start) internal pure returns (uint96) {\n require(_bytes.length >= _start + 12, \"toUint96_outOfBounds\");\n uint96 tempUint;\n\n assembly {\n tempUint := mload(add(add(_bytes, 0xc), _start))\n }\n\n return tempUint;\n }\n\n function toUint128(bytes memory _bytes, uint256 _start) internal pure returns (uint128) {\n require(_bytes.length >= _start + 16, \"toUint128_outOfBounds\");\n uint128 tempUint;\n\n assembly {\n tempUint := mload(add(add(_bytes, 0x10), _start))\n }\n\n return tempUint;\n }\n\n function toUint256(bytes memory _bytes, uint256 _start) internal pure returns (uint256) {\n require(_bytes.length >= _start + 32, \"toUint256_outOfBounds\");\n uint256 tempUint;\n\n assembly {\n tempUint := mload(add(add(_bytes, 0x20), _start))\n }\n\n return tempUint;\n }\n\n function toBytes32(bytes memory _bytes, uint256 _start) internal pure returns (bytes32) {\n require(_bytes.length >= _start + 32, \"toBytes32_outOfBounds\");\n bytes32 tempBytes32;\n\n assembly {\n tempBytes32 := mload(add(add(_bytes, 0x20), _start))\n }\n\n return tempBytes32;\n }\n\n function equal(bytes memory _preBytes, bytes memory _postBytes) internal pure returns (bool) {\n bool success = true;\n\n assembly {\n let length := mload(_preBytes)\n\n // if lengths don't match the arrays are not equal\n switch eq(length, mload(_postBytes))\n case 1 {\n // cb is a circuit breaker in the for loop since there's\n // no said feature for inline assembly loops\n // cb = 1 - don't breaker\n // cb = 0 - break\n let cb := 1\n\n let mc := add(_preBytes, 0x20)\n let end := add(mc, length)\n\n for {\n let cc := add(_postBytes, 0x20)\n // the next line is the loop condition:\n // while(uint256(mc < end) + cb == 2)\n } eq(add(lt(mc, end), cb), 2) {\n mc := add(mc, 0x20)\n cc := add(cc, 0x20)\n } {\n // if any of these checks fails then arrays are not equal\n if iszero(eq(mload(mc), mload(cc))) {\n // unsuccess:\n success := 0\n cb := 0\n }\n }\n }\n default {\n // unsuccess:\n success := 0\n }\n }\n\n return success;\n }\n\n function equalStorage(\n bytes storage _preBytes,\n bytes memory _postBytes\n )\n internal\n view\n returns (bool)\n {\n bool success = true;\n\n assembly {\n // we know _preBytes_offset is 0\n let fslot := sload(_preBytes.slot)\n // Decode the length of the stored array like in concatStorage().\n let slength := div(and(fslot, sub(mul(0x100, iszero(and(fslot, 1))), 1)), 2)\n let mlength := mload(_postBytes)\n\n // if lengths don't match the arrays are not equal\n switch eq(slength, mlength)\n case 1 {\n // slength can contain both the length and contents of the array\n // if length < 32 bytes so let's prepare for that\n // v. http://solidity.readthedocs.io/en/latest/miscellaneous.html#layout-of-state-variables-in-storage\n if iszero(iszero(slength)) {\n switch lt(slength, 32)\n case 1 {\n // blank the last byte which is the length\n fslot := mul(div(fslot, 0x100), 0x100)\n\n if iszero(eq(fslot, mload(add(_postBytes, 0x20)))) {\n // unsuccess:\n success := 0\n }\n }\n default {\n // cb is a circuit breaker in the for loop since there's\n // no said feature for inline assembly loops\n // cb = 1 - don't breaker\n // cb = 0 - break\n let cb := 1\n\n // get the keccak hash to get the contents of the array\n mstore(0x0, _preBytes.slot)\n let sc := keccak256(0x0, 0x20)\n\n let mc := add(_postBytes, 0x20)\n let end := add(mc, mlength)\n\n // the next line is the loop condition:\n // while(uint256(mc < end) + cb == 2)\n for {} eq(add(lt(mc, end), cb), 2) {\n sc := add(sc, 1)\n mc := add(mc, 0x20)\n } {\n if iszero(eq(sload(sc), mload(mc))) {\n // unsuccess:\n success := 0\n cb := 0\n }\n }\n }\n }\n }\n default {\n // unsuccess:\n success := 0\n }\n }\n\n return success;\n }\n}\n"
}
},
"settings": {
"optimizer": {
"enabled": true,
"mode": "3"
},
"evmVersion": "paris",
"outputSelection": {
"*": {
"*": ["storageLayout", "abi", "evm.methodIdentifiers", "metadata", "devdoc", "userdoc"],
"": ["ast"]
}
},
"metadata": {
"bytecodeHash": "none"
},
"detectMissingLibraries": false,
"forceEVMLA": false,
"enableEraVMExtensions": false,
"libraries": {}
}
}