{
  "language": "Solidity",
  "sources": {
    "@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/AddressCast.sol": {
      "content": "// SPDX-License-Identifier: LZBL-1.2\n\npragma solidity ^0.8.20;\n\nlibrary AddressCast {\n    error AddressCast_InvalidSizeForAddress();\n    error AddressCast_InvalidAddress();\n\n    function toBytes32(bytes calldata _addressBytes) internal pure returns (bytes32 result) {\n        if (_addressBytes.length > 32) revert AddressCast_InvalidAddress();\n        result = bytes32(_addressBytes);\n        unchecked {\n            uint256 offset = 32 - _addressBytes.length;\n            result = result >> (offset * 8);\n        }\n    }\n\n    function toBytes32(address _address) internal pure returns (bytes32 result) {\n        result = bytes32(uint256(uint160(_address)));\n    }\n\n    function toBytes(bytes32 _addressBytes32, uint256 _size) internal pure returns (bytes memory result) {\n        if (_size == 0 || _size > 32) revert AddressCast_InvalidSizeForAddress();\n        result = new bytes(_size);\n        unchecked {\n            uint256 offset = 256 - _size * 8;\n            assembly {\n                mstore(add(result, 32), shl(offset, _addressBytes32))\n            }\n        }\n    }\n\n    function toAddress(bytes32 _addressBytes32) internal pure returns (address result) {\n        result = address(uint160(uint256(_addressBytes32)));\n    }\n\n    function toAddress(bytes calldata _addressBytes) internal pure returns (address result) {\n        if (_addressBytes.length != 20) revert AddressCast_InvalidAddress();\n        result = address(bytes20(_addressBytes));\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/IOAppOptionsType3.sol": {
      "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.20;\n\n/**\n * @dev Struct representing enforced option parameters.\n */\nstruct EnforcedOptionParam {\n    uint32 eid; // Endpoint ID\n    uint16 msgType; // Message Type\n    bytes options; // Additional options\n}\n\n/**\n * @title IOAppOptionsType3\n * @dev Interface for the OApp with Type 3 Options, allowing the setting and combining of enforced options.\n */\ninterface IOAppOptionsType3 {\n    // Custom error message for invalid options\n    error InvalidOptions(bytes options);\n\n    // Event emitted when enforced options are set\n    event EnforcedOptionSet(EnforcedOptionParam[] _enforcedOptions);\n\n    /**\n     * @notice Sets enforced options for specific endpoint and message type combinations.\n     * @param _enforcedOptions An array of EnforcedOptionParam structures specifying enforced options.\n     */\n    function setEnforcedOptions(EnforcedOptionParam[] calldata _enforcedOptions) external;\n\n    /**\n     * @notice Combines options for a given endpoint and message type.\n     * @param _eid The endpoint ID.\n     * @param _msgType The OApp message type.\n     * @param _extraOptions Additional options passed by the caller.\n     * @return options The combination of caller specified options AND enforced options.\n     */\n    function combineOptions(\n        uint32 _eid,\n        uint16 _msgType,\n        bytes calldata _extraOptions\n    ) external view returns (bytes memory options);\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/OAppOptionsType3.sol": {
      "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.20;\n\nimport { Ownable } from \"@openzeppelin/contracts/access/Ownable.sol\";\nimport { IOAppOptionsType3, EnforcedOptionParam } from \"../interfaces/IOAppOptionsType3.sol\";\n\n/**\n * @title OAppOptionsType3\n * @dev Abstract contract implementing the IOAppOptionsType3 interface with type 3 options.\n */\nabstract contract OAppOptionsType3 is IOAppOptionsType3, Ownable {\n    uint16 internal constant OPTION_TYPE_3 = 3;\n\n    // @dev The \"msgType\" should be defined in the child contract.\n    mapping(uint32 eid => mapping(uint16 msgType => bytes enforcedOption)) public enforcedOptions;\n\n    /**\n     * @dev Sets the enforced options for specific endpoint and message type combinations.\n     * @param _enforcedOptions An array of EnforcedOptionParam structures specifying enforced options.\n     *\n     * @dev Only the owner/admin of the OApp can call this function.\n     * @dev Provides a way for the OApp to enforce things like paying for PreCrime, AND/OR minimum dst lzReceive gas amounts etc.\n     * @dev These enforced options can vary as the potential options/execution on the remote may differ as per the msgType.\n     * eg. Amount of lzReceive() gas necessary to deliver a lzCompose() message adds overhead you dont want to pay\n     * if you are only making a standard LayerZero message ie. lzReceive() WITHOUT sendCompose().\n     */\n    function setEnforcedOptions(EnforcedOptionParam[] calldata _enforcedOptions) public virtual onlyOwner {\n        _setEnforcedOptions(_enforcedOptions);\n    }\n\n    /**\n     * @dev Sets the enforced options for specific endpoint and message type combinations.\n     * @param _enforcedOptions An array of EnforcedOptionParam structures specifying enforced options.\n     *\n     * @dev Provides a way for the OApp to enforce things like paying for PreCrime, AND/OR minimum dst lzReceive gas amounts etc.\n     * @dev These enforced options can vary as the potential options/execution on the remote may differ as per the msgType.\n     * eg. Amount of lzReceive() gas necessary to deliver a lzCompose() message adds overhead you dont want to pay\n     * if you are only making a standard LayerZero message ie. lzReceive() WITHOUT sendCompose().\n     */\n    function _setEnforcedOptions(EnforcedOptionParam[] memory _enforcedOptions) internal virtual {\n        for (uint256 i = 0; i < _enforcedOptions.length; i++) {\n            // @dev Enforced options are only available for optionType 3, as type 1 and 2 dont support combining.\n            _assertOptionsType3(_enforcedOptions[i].options);\n            enforcedOptions[_enforcedOptions[i].eid][_enforcedOptions[i].msgType] = _enforcedOptions[i].options;\n        }\n\n        emit EnforcedOptionSet(_enforcedOptions);\n    }\n\n    /**\n     * @notice Combines options for a given endpoint and message type.\n     * @param _eid The endpoint ID.\n     * @param _msgType The OAPP message type.\n     * @param _extraOptions Additional options passed by the caller.\n     * @return options The combination of caller specified options AND enforced options.\n     *\n     * @dev If there is an enforced lzReceive option:\n     * - {gasLimit: 200k, msg.value: 1 ether} AND a caller supplies a lzReceive option: {gasLimit: 100k, msg.value: 0.5 ether}\n     * - The resulting options will be {gasLimit: 300k, msg.value: 1.5 ether} when the message is executed on the remote lzReceive() function.\n     * @dev This presence of duplicated options is handled off-chain in the verifier/executor.\n     */\n    function combineOptions(\n        uint32 _eid,\n        uint16 _msgType,\n        bytes calldata _extraOptions\n    ) public view virtual returns (bytes memory) {\n        bytes memory enforced = enforcedOptions[_eid][_msgType];\n\n        // No enforced options, pass whatever the caller supplied, even if it's empty or legacy type 1/2 options.\n        if (enforced.length == 0) return _extraOptions;\n\n        // No caller options, return enforced\n        if (_extraOptions.length == 0) return enforced;\n\n        // @dev If caller provided _extraOptions, must be type 3 as its the ONLY type that can be combined.\n        if (_extraOptions.length >= 2) {\n            _assertOptionsType3(_extraOptions);\n            // @dev Remove the first 2 bytes containing the type from the _extraOptions and combine with enforced.\n            return bytes.concat(enforced, _extraOptions[2:]);\n        }\n\n        // No valid set of options was found.\n        revert InvalidOptions(_extraOptions);\n    }\n\n    /**\n     * @dev Internal function to assert that options are of type 3.\n     * @param _options The options to be checked.\n     */\n    function _assertOptionsType3(bytes memory _options) internal pure virtual {\n        uint16 optionsType;\n        assembly {\n            optionsType := mload(add(_options, 2))\n        }\n        if (optionsType != OPTION_TYPE_3) revert InvalidOptions(_options);\n    }\n}\n"
    },
    "@layerzerolabs/oapp-evm/contracts/oapp/libs/ReadCodecV1.sol": {
      "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.20;\n\nimport { SafeCast } from \"@openzeppelin/contracts/utils/math/SafeCast.sol\";\n\nstruct EVMCallRequestV1 {\n    uint16 appRequestLabel; // Label identifying the application or type of request (can be use in lzCompute)\n    uint32 targetEid; // Target endpoint ID (representing a target blockchain)\n    bool isBlockNum; // True if the request = block number, false if timestamp\n    uint64 blockNumOrTimestamp; // Block number or timestamp to use in the request\n    uint16 confirmations; // Number of block confirmations on top of the requested block number or timestamp before the view function can be called\n    address to; // Address of the target contract on the target chain\n    bytes callData; // Calldata for the contract call\n}\n\nstruct EVMCallComputeV1 {\n    uint8 computeSetting; // Compute setting (0 = map only, 1 = reduce only, 2 = map reduce)\n    uint32 targetEid; // Target endpoint ID (representing a target blockchain)\n    bool isBlockNum; // True if the request = block number, false if timestamp\n    uint64 blockNumOrTimestamp; // Block number or timestamp to use in the request\n    uint16 confirmations; // Number of block confirmations on top of the requested block number or timestamp before the view function can be called\n    address to; // Address of the target contract on the target chain\n}\n\nlibrary ReadCodecV1 {\n    using SafeCast for uint256;\n\n    uint16 internal constant CMD_VERSION = 1;\n\n    uint8 internal constant REQUEST_VERSION = 1;\n    uint16 internal constant RESOLVER_TYPE_SINGLE_VIEW_EVM_CALL = 1;\n\n    uint8 internal constant COMPUTE_VERSION = 1;\n    uint16 internal constant COMPUTE_TYPE_SINGLE_VIEW_EVM_CALL = 1;\n\n    error InvalidVersion();\n    error InvalidType();\n\n    function decode(\n        bytes calldata _cmd\n    )\n        internal\n        pure\n        returns (uint16 appCmdLabel, EVMCallRequestV1[] memory evmCallRequests, EVMCallComputeV1 memory compute)\n    {\n        uint256 offset = 0;\n        uint16 cmdVersion = uint16(bytes2(_cmd[offset:offset + 2]));\n        offset += 2;\n        if (cmdVersion != CMD_VERSION) revert InvalidVersion();\n\n        appCmdLabel = uint16(bytes2(_cmd[offset:offset + 2]));\n        offset += 2;\n\n        (evmCallRequests, offset) = decodeRequestsV1(_cmd, offset);\n\n        // decode the compute if it exists\n        if (offset < _cmd.length) {\n            (compute, ) = decodeEVMCallComputeV1(_cmd, offset);\n        }\n    }\n\n    function decodeRequestsV1(\n        bytes calldata _cmd,\n        uint256 _offset\n    ) internal pure returns (EVMCallRequestV1[] memory evmCallRequests, uint256 newOffset) {\n        newOffset = _offset;\n        uint16 requestCount = uint16(bytes2(_cmd[newOffset:newOffset + 2]));\n        newOffset += 2;\n\n        evmCallRequests = new EVMCallRequestV1[](requestCount);\n        for (uint16 i = 0; i < requestCount; i++) {\n            uint8 requestVersion = uint8(_cmd[newOffset]);\n            newOffset += 1;\n            if (requestVersion != REQUEST_VERSION) revert InvalidVersion();\n\n            uint16 appRequestLabel = uint16(bytes2(_cmd[newOffset:newOffset + 2]));\n            newOffset += 2;\n\n            uint16 resolverType = uint16(bytes2(_cmd[newOffset:newOffset + 2]));\n            newOffset += 2;\n\n            if (resolverType == RESOLVER_TYPE_SINGLE_VIEW_EVM_CALL) {\n                (EVMCallRequestV1 memory request, uint256 nextOffset) = decodeEVMCallRequestV1(\n                    _cmd,\n                    newOffset,\n                    appRequestLabel\n                );\n                newOffset = nextOffset;\n                evmCallRequests[i] = request;\n            } else {\n                revert InvalidType();\n            }\n        }\n    }\n\n    function decodeEVMCallRequestV1(\n        bytes calldata _cmd,\n        uint256 _offset,\n        uint16 _appRequestLabel\n    ) internal pure returns (EVMCallRequestV1 memory request, uint256 newOffset) {\n        newOffset = _offset;\n        request.appRequestLabel = _appRequestLabel;\n\n        uint16 requestSize = uint16(bytes2(_cmd[newOffset:newOffset + 2]));\n        newOffset += 2;\n        request.targetEid = uint32(bytes4(_cmd[newOffset:newOffset + 4]));\n        newOffset += 4;\n        request.isBlockNum = uint8(_cmd[newOffset]) == 1;\n        newOffset += 1;\n        request.blockNumOrTimestamp = uint64(bytes8(_cmd[newOffset:newOffset + 8]));\n        newOffset += 8;\n        request.confirmations = uint16(bytes2(_cmd[newOffset:newOffset + 2]));\n        newOffset += 2;\n        request.to = address(bytes20(_cmd[newOffset:newOffset + 20]));\n        newOffset += 20;\n        uint16 callDataSize = requestSize - 35;\n        request.callData = _cmd[newOffset:newOffset + callDataSize];\n        newOffset += callDataSize;\n    }\n\n    function decodeEVMCallComputeV1(\n        bytes calldata _cmd,\n        uint256 _offset\n    ) internal pure returns (EVMCallComputeV1 memory compute, uint256 newOffset) {\n        newOffset = _offset;\n        uint8 computeVersion = uint8(_cmd[newOffset]);\n        newOffset += 1;\n        if (computeVersion != COMPUTE_VERSION) revert InvalidVersion();\n        uint16 computeType = uint16(bytes2(_cmd[newOffset:newOffset + 2]));\n        newOffset += 2;\n        if (computeType != COMPUTE_TYPE_SINGLE_VIEW_EVM_CALL) revert InvalidType();\n\n        compute.computeSetting = uint8(_cmd[newOffset]);\n        newOffset += 1;\n        compute.targetEid = uint32(bytes4(_cmd[newOffset:newOffset + 4]));\n        newOffset += 4;\n        compute.isBlockNum = uint8(_cmd[newOffset]) == 1;\n        newOffset += 1;\n        compute.blockNumOrTimestamp = uint64(bytes8(_cmd[newOffset:newOffset + 8]));\n        newOffset += 8;\n        compute.confirmations = uint16(bytes2(_cmd[newOffset:newOffset + 2]));\n        newOffset += 2;\n        compute.to = address(bytes20(_cmd[newOffset:newOffset + 20]));\n        newOffset += 20;\n    }\n\n    function decodeCmdAppLabel(bytes calldata _cmd) internal pure returns (uint16) {\n        uint256 offset = 0;\n        uint16 cmdVersion = uint16(bytes2(_cmd[offset:offset + 2]));\n        offset += 2;\n        if (cmdVersion != CMD_VERSION) revert InvalidVersion();\n\n        return uint16(bytes2(_cmd[offset:offset + 2]));\n    }\n\n    function decodeRequestV1AppRequestLabel(bytes calldata _request) internal pure returns (uint16) {\n        uint256 offset = 0;\n        uint8 requestVersion = uint8(_request[offset]);\n        offset += 1;\n        if (requestVersion != REQUEST_VERSION) revert InvalidVersion();\n\n        return uint16(bytes2(_request[offset:offset + 2]));\n    }\n\n    function encode(\n        uint16 _appCmdLabel,\n        EVMCallRequestV1[] memory _evmCallRequests,\n        EVMCallComputeV1 memory _evmCallCompute\n    ) internal pure returns (bytes memory) {\n        bytes memory cmd = encode(_appCmdLabel, _evmCallRequests);\n        if (_evmCallCompute.targetEid != 0) {\n            // if eid is 0, it means no compute\n            cmd = appendEVMCallComputeV1(cmd, _evmCallCompute);\n        }\n        return cmd;\n    }\n\n    function encode(\n        uint16 _appCmdLabel,\n        EVMCallRequestV1[] memory _evmCallRequests\n    ) internal pure returns (bytes memory) {\n        bytes memory cmd = abi.encodePacked(CMD_VERSION, _appCmdLabel, _evmCallRequests.length.toUint16());\n        for (uint256 i = 0; i < _evmCallRequests.length; i++) {\n            cmd = appendEVMCallRequestV1(cmd, _evmCallRequests[i]);\n        }\n        return cmd;\n    }\n\n    // todo: optimize this with Buffer\n    function appendEVMCallRequestV1(\n        bytes memory _cmd,\n        EVMCallRequestV1 memory _request\n    ) internal pure returns (bytes memory) {\n        bytes memory newCmd = abi.encodePacked(\n            _cmd,\n            REQUEST_VERSION,\n            _request.appRequestLabel,\n            RESOLVER_TYPE_SINGLE_VIEW_EVM_CALL,\n            (_request.callData.length + 35).toUint16(),\n            _request.targetEid\n        );\n        return\n            abi.encodePacked(\n                newCmd,\n                _request.isBlockNum,\n                _request.blockNumOrTimestamp,\n                _request.confirmations,\n                _request.to,\n                _request.callData\n            );\n    }\n\n    function appendEVMCallComputeV1(\n        bytes memory _cmd,\n        EVMCallComputeV1 memory _compute\n    ) internal pure returns (bytes memory) {\n        return\n            abi.encodePacked(\n                _cmd,\n                COMPUTE_VERSION,\n                COMPUTE_TYPE_SINGLE_VIEW_EVM_CALL,\n                _compute.computeSetting,\n                _compute.targetEid,\n                _compute.isBlockNum,\n                _compute.blockNumOrTimestamp,\n                _compute.confirmations,\n                _compute.to\n            );\n    }\n}\n"
    },
    "@layerzerolabs/oapp-evm/contracts/oapp/OApp.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 { OAppSender, MessagingFee, MessagingReceipt } from \"./OAppSender.sol\";\n// @dev Import the 'Origin' so it's exposed to OApp implementers\n// solhint-disable-next-line no-unused-import\nimport { OAppReceiver, Origin } from \"./OAppReceiver.sol\";\nimport { OAppCore } from \"./OAppCore.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 OApp is OAppSender, OAppReceiver {\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     * @param _delegate The delegate capable of making OApp configurations inside of the endpoint.\n     */\n    constructor(address _endpoint, address _delegate) OAppCore(_endpoint, _delegate) {}\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(OAppSender, OAppReceiver)\n        returns (uint64 senderVersion, uint64 receiverVersion)\n    {\n        return (SENDER_VERSION, RECEIVER_VERSION);\n    }\n}\n"
    },
    "@layerzerolabs/oapp-evm/contracts/oapp/OAppCore.sol": {
      "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.20;\n\nimport { Ownable } from \"@openzeppelin/contracts/access/Ownable.sol\";\nimport { IOAppCore, ILayerZeroEndpointV2 } from \"./interfaces/IOAppCore.sol\";\n\n/**\n * @title OAppCore\n * @dev Abstract contract implementing the IOAppCore interface with basic OApp configurations.\n */\nabstract contract OAppCore is IOAppCore, Ownable {\n    // The LayerZero endpoint associated with the given OApp\n    ILayerZeroEndpointV2 public immutable endpoint;\n\n    // Mapping to store peers associated with corresponding endpoints\n    mapping(uint32 eid => bytes32 peer) public peers;\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     * @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     */\n    constructor(address _endpoint, address _delegate) {\n        endpoint = ILayerZeroEndpointV2(_endpoint);\n\n        if (_delegate == address(0)) revert InvalidDelegate();\n        endpoint.setDelegate(_delegate);\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        _setPeer(_eid, _peer);\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 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) internal virtual {\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        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/contracts/oapp/OAppRead.sol": {
      "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.20;\n\nimport { AddressCast } from \"@layerzerolabs/lz-evm-protocol-v2/contracts/libs/AddressCast.sol\";\n\nimport { OApp } from \"./OApp.sol\";\n\nabstract contract OAppRead is OApp {\n    constructor(address _endpoint, address _delegate) OApp(_endpoint, _delegate) {}\n\n    // -------------------------------\n    // Only Owner\n    function setReadChannel(uint32 _channelId, bool _active) public virtual onlyOwner {\n        _setPeer(_channelId, _active ? AddressCast.toBytes32(address(this)) : bytes32(0));\n    }\n}\n"
    },
    "@layerzerolabs/oapp-evm/contracts/oapp/OAppReceiver.sol": {
      "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.20;\n\nimport { IOAppReceiver, Origin } from \"./interfaces/IOAppReceiver.sol\";\nimport { OAppCore } from \"./OAppCore.sol\";\n\n/**\n * @title OAppReceiver\n * @dev Abstract contract implementing the ILayerZeroReceiver interface and extending OAppCore for OApp receivers.\n */\nabstract contract OAppReceiver is IOAppReceiver, OAppCore {\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     * @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/contracts/oapp/OAppSender.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 { OAppCore } from \"./OAppCore.sol\";\n\n/**\n * @title OAppSender\n * @dev Abstract contract implementing the OAppSender functionality for sending messages to a LayerZero endpoint.\n */\nabstract contract OAppSender is OAppCore {\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     * @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/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.8.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 * ```\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 * ```\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.\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.7.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 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"
    },
    "@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.8.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"
    },
    "@openzeppelin/contracts/token/ERC20/extensions/draft-IERC20Permit.sol": {
      "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/draft-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 */\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    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.6.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(\n        address from,\n        address to,\n        uint256 amount\n    ) external returns (bool);\n}\n"
    },
    "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol": {
      "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.8.0) (token/ERC20/utils/SafeERC20.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC20.sol\";\nimport \"../extensions/draft-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    function safeTransfer(\n        IERC20 token,\n        address to,\n        uint256 value\n    ) internal {\n        _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\n    }\n\n    function safeTransferFrom(\n        IERC20 token,\n        address from,\n        address to,\n        uint256 value\n    ) 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(\n        IERC20 token,\n        address spender,\n        uint256 value\n    ) 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    function safeIncreaseAllowance(\n        IERC20 token,\n        address spender,\n        uint256 value\n    ) internal {\n        uint256 newAllowance = token.allowance(address(this), spender) + value;\n        _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\n    }\n\n    function safeDecreaseAllowance(\n        IERC20 token,\n        address spender,\n        uint256 value\n    ) internal {\n        unchecked {\n            uint256 oldAllowance = token.allowance(address(this), spender);\n            require(oldAllowance >= value, \"SafeERC20: decreased allowance below zero\");\n            uint256 newAllowance = oldAllowance - value;\n            _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\n        }\n    }\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        if (returndata.length > 0) {\n            // Return data is optional\n            require(abi.decode(returndata, (bool)), \"SafeERC20: ERC20 operation did not succeed\");\n        }\n    }\n}\n"
    },
    "@openzeppelin/contracts/utils/Address.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 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 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 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 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"
    },
    "@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.8.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(\n        uint256 x,\n        uint256 y,\n        uint256 denominator\n    ) 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                return prod0 / denominator;\n            }\n\n            // Make sure the result is less than 2^256. Also prevents denominator == 0.\n            require(denominator > prod1);\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(\n        uint256 x,\n        uint256 y,\n        uint256 denominator,\n        Rounding rounding\n    ) 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 10, 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 * 8) < 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/Strings.sol": {
      "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.8.0) (utils/Strings.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./math/Math.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 `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"
    },
    "@venusprotocol/solidity-utilities/contracts/validators.sol": {
      "content": "// SPDX-License-Identifier: BSD-3-Clause\npragma solidity 0.8.25;\n\n/// @notice Thrown if the supplied address is a zero address where it is not allowed\nerror ZeroAddressNotAllowed();\n\n/// @notice Thrown if the supplied value is 0 where it is not allowed\nerror ZeroValueNotAllowed();\n\n/// @notice Checks if the provided address is nonzero, reverts otherwise\n/// @param address_ Address to check\n/// @custom:error ZeroAddressNotAllowed is thrown if the provided address is a zero address\nfunction ensureNonzeroAddress(address address_) pure {\n    if (address_ == address(0)) {\n        revert ZeroAddressNotAllowed();\n    }\n}\n\n/// @notice Checks if the provided value is nonzero, reverts otherwise\n/// @param value_ Value to check\n/// @custom:error ZeroValueNotAllowed is thrown if the provided value is 0\nfunction ensureNonzeroValue(uint256 value_) pure {\n    if (value_ == 0) {\n        revert ZeroValueNotAllowed();\n    }\n}\n"
    },
    "contracts/Cross-chain/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     * @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/IBlockHashDispatcher.sol": {
      "content": "// SPDX-License-Identifier: Unlicense\npragma solidity ^0.8.0;\n\ninterface IBlockHashDispatcher {\n    function getHash(uint256 blockNumber, uint256 pId) external view returns (uint256, uint256, bytes32);\n}\n"
    },
    "contracts/Cross-chain/interfaces/IDataWarehouse.sol": {
      "content": "// SPDX-License-Identifier: Unlicense\npragma solidity ^0.8.0;\n\nimport { StateProofVerifier } from \"../libs/StateProofVerifier.sol\";\n\n/**\n * @title IDataWarehouse\n * @author BGD Labs\n * @notice interface containing the methods definitions of the DataWarehouse contract\n */\ninterface IDataWarehouse {\n    /**\n     * @notice event emitted when a storage root has been processed successfully\n     * @param caller address that called the processStorageRoot method\n     * @param account address where the root is generated\n     * @param blockHash hash of the block where the root was generated\n     */\n    event StorageRootProcessed(address indexed caller, address indexed account, bytes32 indexed blockHash);\n\n    /**\n     * @notice event emitted when a storage root has been processed successfully\n     * @param caller address that called the processStorageSlot method\n     * @param account address where the slot is processed\n     * @param blockHash hash of the block where the storage proof was generated\n     * @param slot storage location to search\n     * @param value storage information on the specified location\n     */\n    event StorageSlotProcessed(\n        address indexed caller,\n        address indexed account,\n        bytes32 indexed blockHash,\n        bytes32 slot,\n        uint256 value\n    );\n\n    /**\n     * @notice method to get the storage roots of an account (token) in a certain block hash\n     * @param account address of the token to get the storage roots from\n     * @param blockHash hash of the block from where the roots are generated\n     * @return state root hash of the account on the block hash specified\n     */\n    function getStorageRoots(address account, bytes32 blockHash) external view returns (bytes32);\n\n    /**\n     * @notice method to process the storage root from an account on a block hash.\n     * @param account address of the token to get the storage roots from\n     * @param blockHash hash of the block from where the roots are generated\n     * @param blockHeaderRLP rlp encoded block header. At same block where the block hash was taken\n     * @param accountStateProofRLP rlp encoded account state proof, taken in same block as block hash\n     * @return the storage root\n     */\n    function processStorageRoot(\n        address account,\n        bytes32 blockHash,\n        bytes memory blockHeaderRLP,\n        bytes memory accountStateProofRLP\n    ) external returns (StateProofVerifier.BlockHeader memory);\n\n    /**\n     * @notice method to get the storage value at a certain slot and block hash for a certain address\n     * @param account address of the token to get the storage roots from\n     * @param blockHash hash of the block from where the roots are generated\n     * @param slot hash of the explicit storage placement where the value to get is found.\n     * @param storageProof generated proof containing the storage, at block hash\n     * @return an object containing the slot value at the specified storage slot\n     */\n    function getStorage(\n        address account,\n        bytes32 blockHash,\n        bytes32 slot,\n        bytes memory storageProof\n    ) external view returns (StateProofVerifier.SlotValue memory);\n\n    /**\n     * @notice method to register the storage value at a certain slot and block hash for a certain address\n     * @param account address of the token to get the storage roots from\n     * @param blockHash hash of the block from where the roots are generated\n     * @param slot hash of the explicit storage placement where the value to get is found.\n     * @param storageProof generated proof containing the storage, at block hash\n     */\n    function processStorageSlot(address account, bytes32 blockHash, bytes32 slot, bytes calldata storageProof) external;\n\n    /**\n     * @notice method to get the value from storage at a certain block hash, previously registered.\n     * @param blockHash hash of the block from where the roots are generated\n     * @param account address of the token to get the storage roots from\n     * @param slot hash of the explicit storage placement where the value to get is found.\n     * @return numeric slot value of the slot. The value must be decoded to get the actual stored information\n     */\n    function getRegisteredSlot(bytes32 blockHash, address account, bytes32 slot) external view returns (uint256);\n}\n"
    },
    "contracts/Cross-chain/interfaces/IGovernorBravoDelegate.sol": {
      "content": "// SPDX-License-Identifier: Unlicense\npragma solidity ^0.8.0;\n\ninterface IGovernorBravoDelegate {\n    function activateProposal(uint256 proposalId) external;\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/interfaces/IVotingPowerAggregator.sol": {
      "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.25;\n\ninterface IVotingPowerAggregator {\n   \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 destination contract address\n     * @param destChainId The LayerZero id of a source chain\n     * @param destAddress The address of the contract on the source chain\n     */\n    function setPeer(uint16 destChainId, bytes32 destAddress) external;\n\n}\n"
    },
    "contracts/Cross-chain/interfaces/IXvsVault.sol": {
      "content": "// SPDX-License-Identifier: Unlicense\npragma solidity ^0.8.0;\n\ninterface IXvsVault {\n    function getPriorVotes(address account, uint blockNumber) external view returns (uint96);\n}\n"
    },
    "contracts/Cross-chain/libs/MerklePatriciaProofVerifier.sol": {
      "content": "// SPDX-License-Identifier: MIT\n\n/**\n * Copied from https://github.com/lidofinance/curve-merkle-oracle/blob/main/contracts/MerklePatriciaProofVerifier.sol\n */\npragma solidity ^0.8.0;\n\nimport { RLPReader } from \"./RLPReader.sol\";\n\nlibrary MerklePatriciaProofVerifier {\n    using RLPReader for RLPReader.RLPItem;\n    using RLPReader for bytes;\n\n    /// @dev Validates a Merkle-Patricia-Trie proof.\n    ///      If the proof proves the inclusion of some key-value pair in the\n    ///      trie, the value is returned. Otherwise, i.e. if the proof proves\n    ///      the exclusion of a key from the trie, an empty byte array is\n    ///      returned.\n    /// @param rootHash is the Keccak-256 hash of the root node of the MPT.\n    /// @param path is the key of the node whose inclusion/exclusion we are\n    ///        proving.\n    /// @param stack is the stack of MPT nodes (starting with the root) that\n    ///        need to be traversed during verification.\n    /// @return value whose inclusion is proved or an empty byte array for\n    ///         a proof of exclusion\n    function extractProofValue(\n        bytes32 rootHash,\n        bytes memory path,\n        RLPReader.RLPItem[] memory stack\n    ) internal pure returns (bytes memory value) {\n        bytes memory mptKey = _decodeNibbles(path, 0);\n        uint256 mptKeyOffset = 0;\n\n        bytes32 nodeHashHash;\n        RLPReader.RLPItem[] memory node;\n\n        RLPReader.RLPItem memory rlpValue;\n\n        if (stack.length == 0) {\n            // Root hash of empty Merkle-Patricia-Trie\n            require(rootHash == 0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421);\n            return new bytes(0);\n        }\n\n        // Traverse stack of nodes starting at root.\n        for (uint256 i = 0; i < stack.length; i++) {\n            // We use the fact that an rlp encoded list consists of some\n            // encoding of its length plus the concatenation of its\n            // *rlp-encoded* items.\n\n            // The root node is hashed with Keccak-256 ...\n            if (i == 0 && rootHash != stack[i].rlpBytesKeccak256()) {\n                revert();\n            }\n            // ... whereas all other nodes are hashed with the MPT\n            // hash function.\n            if (i != 0 && nodeHashHash != _mptHashHash(stack[i])) {\n                revert();\n            }\n            // We verified that stack[i] has the correct hash, so we\n            // may safely decode it.\n            node = stack[i].toList();\n\n            if (node.length == 2) {\n                // Extension or Leaf node\n\n                bool isLeaf;\n                bytes memory nodeKey;\n                (isLeaf, nodeKey) = _merklePatriciaCompactDecode(node[0].toBytes());\n\n                uint256 prefixLength = _sharedPrefixLength(mptKeyOffset, mptKey, nodeKey);\n                mptKeyOffset += prefixLength;\n\n                if (prefixLength < nodeKey.length) {\n                    // Proof claims divergent extension or leaf. (Only\n                    // relevant for proofs of exclusion.)\n                    // An Extension/Leaf node is divergent iff it \"skips\" over\n                    // the point at which a Branch node should have been had the\n                    // excluded key been included in the trie.\n                    // Example: Imagine a proof of exclusion for path [1, 4],\n                    // where the current node is a Leaf node with\n                    // path [1, 3, 3, 7]. For [1, 4] to be included, there\n                    // should have been a Branch node at [1] with a child\n                    // at 3 and a child at 4.\n\n                    // Sanity check\n                    if (i < stack.length - 1) {\n                        // divergent node must come last in proof\n                        revert();\n                    }\n\n                    return new bytes(0);\n                }\n\n                if (isLeaf) {\n                    // Sanity check\n                    if (i < stack.length - 1) {\n                        // leaf node must come last in proof\n                        revert();\n                    }\n\n                    if (mptKeyOffset < mptKey.length) {\n                        return new bytes(0);\n                    }\n\n                    rlpValue = node[1];\n                    return rlpValue.toBytes();\n                } else {\n                    // extension\n                    // Sanity check\n                    if (i == stack.length - 1) {\n                        // shouldn't be at last level\n                        revert();\n                    }\n\n                    if (!node[1].isList()) {\n                        // rlp(child) was at least 32 bytes. node[1] contains\n                        // Keccak256(rlp(child)).\n                        nodeHashHash = node[1].payloadKeccak256();\n                    } else {\n                        // rlp(child) was less than 32 bytes. node[1] contains\n                        // rlp(child).\n                        nodeHashHash = node[1].rlpBytesKeccak256();\n                    }\n                }\n            } else if (node.length == 17) {\n                // Branch node\n\n                if (mptKeyOffset != mptKey.length) {\n                    // we haven't consumed the entire path, so we need to look at a child\n                    uint8 nibble = uint8(mptKey[mptKeyOffset]);\n                    mptKeyOffset += 1;\n                    if (nibble >= 16) {\n                        // each element of the path has to be a nibble\n                        revert();\n                    }\n\n                    if (_isEmptyBytesequence(node[nibble])) {\n                        // Sanity\n                        if (i != stack.length - 1) {\n                            // leaf node should be at last level\n                            revert();\n                        }\n\n                        return new bytes(0);\n                    } else if (!node[nibble].isList()) {\n                        nodeHashHash = node[nibble].payloadKeccak256();\n                    } else {\n                        nodeHashHash = node[nibble].rlpBytesKeccak256();\n                    }\n                } else {\n                    // we have consumed the entire mptKey, so we need to look at what's contained in this node.\n\n                    // Sanity\n                    if (i != stack.length - 1) {\n                        // should be at last level\n                        revert();\n                    }\n\n                    return node[16].toBytes();\n                }\n            }\n        }\n    }\n\n    /// @dev Computes the hash of the Merkle-Patricia-Trie hash of the RLP item.\n    ///      Merkle-Patricia-Tries use a weird \"hash function\" that outputs\n    ///      *variable-length* hashes: If the item is shorter than 32 bytes,\n    ///      the MPT hash is the item. Otherwise, the MPT hash is the\n    ///      Keccak-256 hash of the item.\n    ///      The easiest way to compare variable-length byte sequences is\n    ///      to compare their Keccak-256 hashes.\n    /// @param item The RLP item to be hashed.\n    /// @return Keccak-256(MPT-hash(item))\n    function _mptHashHash(RLPReader.RLPItem memory item) private pure returns (bytes32) {\n        if (item.len < 32) {\n            return item.rlpBytesKeccak256();\n        } else {\n            return keccak256(abi.encodePacked(item.rlpBytesKeccak256()));\n        }\n    }\n\n    function _isEmptyBytesequence(RLPReader.RLPItem memory item) private pure returns (bool) {\n        if (item.len != 1) {\n            return false;\n        }\n        uint8 b;\n        uint256 memPtr = item.memPtr;\n        assembly {\n            b := byte(0, mload(memPtr))\n        }\n        return b == 0x80 /* empty byte string */;\n    }\n\n    function _merklePatriciaCompactDecode(\n        bytes memory compact\n    ) private pure returns (bool isLeaf, bytes memory nibbles) {\n        require(compact.length > 0);\n        uint256 first_nibble = (uint8(compact[0]) >> 4) & 0xF;\n        uint256 skipNibbles;\n        if (first_nibble == 0) {\n            skipNibbles = 2;\n            isLeaf = false;\n        } else if (first_nibble == 1) {\n            skipNibbles = 1;\n            isLeaf = false;\n        } else if (first_nibble == 2) {\n            skipNibbles = 2;\n            isLeaf = true;\n        } else if (first_nibble == 3) {\n            skipNibbles = 1;\n            isLeaf = true;\n        } else {\n            // Not supposed to happen!\n            revert();\n        }\n        return (isLeaf, _decodeNibbles(compact, skipNibbles));\n    }\n\n    function _decodeNibbles(bytes memory compact, uint256 skipNibbles) private pure returns (bytes memory nibbles) {\n        require(compact.length > 0);\n\n        uint256 length = compact.length * 2;\n        require(skipNibbles <= length);\n        length -= skipNibbles;\n\n        nibbles = new bytes(length);\n        uint256 nibblesLength = 0;\n\n        for (uint256 i = skipNibbles; i < skipNibbles + length; i += 1) {\n            if (i % 2 == 0) {\n                nibbles[nibblesLength] = bytes1((uint8(compact[i / 2]) >> 4) & 0xF);\n            } else {\n                nibbles[nibblesLength] = bytes1((uint8(compact[i / 2]) >> 0) & 0xF);\n            }\n            nibblesLength += 1;\n        }\n\n        assert(nibblesLength == nibbles.length);\n    }\n\n    function _sharedPrefixLength(uint256 xsOffset, bytes memory xs, bytes memory ys) private pure returns (uint256) {\n        uint256 i;\n        for (i = 0; i + xsOffset < xs.length && i < ys.length; i++) {\n            if (xs[i + xsOffset] != ys[i]) {\n                return i;\n            }\n        }\n        return i;\n    }\n}\n"
    },
    "contracts/Cross-chain/libs/RLPReader.sol": {
      "content": "// SPDX-License-Identifier: Apache-2.0\n\n/*\n * @author Hamdi Allam hamdi.allam97@gmail.com\n * Please reach out with any questions or concerns\n * Code copied from: https://github.com/hamdiallam/Solidity-RLP/blob/master/contracts/RLPReader.sol\n */\npragma solidity ^0.8.0;\n\nlibrary RLPReader {\n    uint8 internal constant STRING_SHORT_START = 0x80;\n    uint8 internal constant STRING_LONG_START = 0xb8;\n    uint8 internal constant LIST_SHORT_START = 0xc0;\n    uint8 internal constant LIST_LONG_START = 0xf8;\n    uint8 internal constant WORD_SIZE = 32;\n\n    struct RLPItem {\n        uint256 len;\n        uint256 memPtr;\n    }\n\n    struct Iterator {\n        RLPItem item; // Item that's being iterated over.\n        uint256 nextPtr; // Position of the next item in the list.\n    }\n\n    /*\n     * @dev Returns the next element in the iteration. Reverts if it has not next element.\n     * @param self The iterator.\n     * @return The next element in the iteration.\n     */\n    function next(Iterator memory self) internal pure returns (RLPItem memory) {\n        require(hasNext(self));\n\n        uint256 ptr = self.nextPtr;\n        uint256 itemLength = _itemLength(ptr);\n        self.nextPtr = ptr + itemLength;\n\n        return RLPItem(itemLength, ptr);\n    }\n\n    /*\n     * @dev Returns true if the iteration has more elements.\n     * @param self The iterator.\n     * @return true if the iteration has more elements.\n     */\n    function hasNext(Iterator memory self) internal pure returns (bool) {\n        RLPItem memory item = self.item;\n        return self.nextPtr < item.memPtr + item.len;\n    }\n\n    /*\n     * @param item RLP encoded bytes\n     */\n    function toRlpItem(bytes memory item) internal pure returns (RLPItem memory) {\n        uint256 memPtr;\n        assembly {\n            memPtr := add(item, 0x20)\n        }\n\n        return RLPItem(item.length, memPtr);\n    }\n\n    /*\n     * @dev Create an iterator. Reverts if item is not a list.\n     * @param self The RLP item.\n     * @return An 'Iterator' over the item.\n     */\n    function iterator(RLPItem memory self) internal pure returns (Iterator memory) {\n        require(isList(self));\n\n        uint256 ptr = self.memPtr + _payloadOffset(self.memPtr);\n        return Iterator(self, ptr);\n    }\n\n    /*\n     * @param the RLP item.\n     */\n    function rlpLen(RLPItem memory item) internal pure returns (uint256) {\n        return item.len;\n    }\n\n    /*\n     * @param the RLP item.\n     * @return (memPtr, len) pair: location of the item's payload in memory.\n     */\n    function payloadLocation(RLPItem memory item) internal pure returns (uint256, uint256) {\n        uint256 offset = _payloadOffset(item.memPtr);\n        uint256 memPtr = item.memPtr + offset;\n        uint256 len = item.len - offset; // data length\n        return (memPtr, len);\n    }\n\n    /*\n     * @param the RLP item.\n     */\n    function payloadLen(RLPItem memory item) internal pure returns (uint256) {\n        (, uint256 len) = payloadLocation(item);\n        return len;\n    }\n\n    /*\n     * @param the RLP item containing the encoded list.\n     */\n    function toList(RLPItem memory item) internal pure returns (RLPItem[] memory) {\n        require(isList(item));\n\n        uint256 items = numItems(item);\n        RLPItem[] memory result = new RLPItem[](items);\n\n        uint256 memPtr = item.memPtr + _payloadOffset(item.memPtr);\n        uint256 dataLen;\n        for (uint256 i = 0; i < items; i++) {\n            dataLen = _itemLength(memPtr);\n            result[i] = RLPItem(dataLen, memPtr);\n            memPtr = memPtr + dataLen;\n        }\n\n        return result;\n    }\n\n    // @return indicator whether encoded payload is a list. negate this function call for isData.\n    function isList(RLPItem memory item) internal pure returns (bool) {\n        if (item.len == 0) return false;\n\n        uint8 byte0;\n        uint256 memPtr = item.memPtr;\n        assembly {\n            byte0 := byte(0, mload(memPtr))\n        }\n\n        if (byte0 < LIST_SHORT_START) return false;\n        return true;\n    }\n\n    /*\n     * @dev A cheaper version of keccak256(toRlpBytes(item)) that avoids copying memory.\n     * @return keccak256 hash of RLP encoded bytes.\n     */\n    function rlpBytesKeccak256(RLPItem memory item) internal pure returns (bytes32) {\n        uint256 ptr = item.memPtr;\n        uint256 len = item.len;\n        bytes32 result;\n        assembly {\n            result := keccak256(ptr, len)\n        }\n        return result;\n    }\n\n    /*\n     * @dev A cheaper version of keccak256(toBytes(item)) that avoids copying memory.\n     * @return keccak256 hash of the item payload.\n     */\n    function payloadKeccak256(RLPItem memory item) internal pure returns (bytes32) {\n        (uint256 memPtr, uint256 len) = payloadLocation(item);\n        bytes32 result;\n        assembly {\n            result := keccak256(memPtr, len)\n        }\n        return result;\n    }\n\n    /** RLPItem conversions into data types **/\n\n    // @returns raw rlp encoding in bytes\n    function toRlpBytes(RLPItem memory item) internal pure returns (bytes memory) {\n        bytes memory result = new bytes(item.len);\n        if (result.length == 0) return result;\n\n        uint256 ptr;\n        assembly {\n            ptr := add(0x20, result)\n        }\n\n        copy(item.memPtr, ptr, item.len);\n        return result;\n    }\n\n    // any non-zero byte except \"0x80\" is considered true\n    function toBoolean(RLPItem memory item) internal pure returns (bool) {\n        require(item.len == 1);\n        uint256 result;\n        uint256 memPtr = item.memPtr;\n        assembly {\n            result := byte(0, mload(memPtr))\n        }\n\n        // SEE Github Issue #5.\n        // Summary: Most commonly used RLP libraries (i.e Geth) will encode\n        // \"0\" as \"0x80\" instead of as \"0\". We handle this edge case explicitly\n        // here.\n        if (result == 0 || result == STRING_SHORT_START) {\n            return false;\n        } else {\n            return true;\n        }\n    }\n\n    function toAddress(RLPItem memory item) internal pure returns (address) {\n        // 1 byte for the length prefix\n        require(item.len == 21);\n\n        return address(uint160(toUint(item)));\n    }\n\n    function toUint(RLPItem memory item) internal pure returns (uint256) {\n        require(item.len > 0 && item.len <= 33);\n\n        (uint256 memPtr, uint256 len) = payloadLocation(item);\n\n        uint256 result;\n        assembly {\n            result := mload(memPtr)\n\n            // shift to the correct location if neccesary\n            if lt(len, 32) {\n                result := div(result, exp(256, sub(32, len)))\n            }\n        }\n\n        return result;\n    }\n\n    // enforces 32 byte length\n    function toUintStrict(RLPItem memory item) internal pure returns (uint256) {\n        // one byte prefix\n        require(item.len == 33);\n\n        uint256 result;\n        uint256 memPtr = item.memPtr + 1;\n        assembly {\n            result := mload(memPtr)\n        }\n\n        return result;\n    }\n\n    function toBytes(RLPItem memory item) internal pure returns (bytes memory) {\n        require(item.len > 0);\n\n        (uint256 memPtr, uint256 len) = payloadLocation(item);\n        bytes memory result = new bytes(len);\n\n        uint256 destPtr;\n        assembly {\n            destPtr := add(0x20, result)\n        }\n\n        copy(memPtr, destPtr, len);\n        return result;\n    }\n\n    /*\n     * Private Helpers\n     */\n\n    // @return number of payload items inside an encoded list.\n    function numItems(RLPItem memory item) private pure returns (uint256) {\n        if (item.len == 0) return 0;\n\n        uint256 count = 0;\n        uint256 currPtr = item.memPtr + _payloadOffset(item.memPtr);\n        uint256 endPtr = item.memPtr + item.len;\n        while (currPtr < endPtr) {\n            currPtr = currPtr + _itemLength(currPtr); // skip over an item\n            count++;\n        }\n\n        return count;\n    }\n\n    // @return entire rlp item byte length\n    function _itemLength(uint256 memPtr) private pure returns (uint256) {\n        uint256 itemLen;\n        uint256 byte0;\n        assembly {\n            byte0 := byte(0, mload(memPtr))\n        }\n\n        if (byte0 < STRING_SHORT_START) {\n            itemLen = 1;\n        } else if (byte0 < STRING_LONG_START) {\n            itemLen = byte0 - STRING_SHORT_START + 1;\n        } else if (byte0 < LIST_SHORT_START) {\n            assembly {\n                let byteLen := sub(byte0, 0xb7) // # of bytes the actual length is\n                memPtr := add(memPtr, 1) // skip over the first byte\n\n                /* 32 byte word size */\n                let dataLen := div(mload(memPtr), exp(256, sub(32, byteLen))) // right shifting to get the len\n                itemLen := add(dataLen, add(byteLen, 1))\n            }\n        } else if (byte0 < LIST_LONG_START) {\n            itemLen = byte0 - LIST_SHORT_START + 1;\n        } else {\n            assembly {\n                let byteLen := sub(byte0, 0xf7)\n                memPtr := add(memPtr, 1)\n\n                let dataLen := div(mload(memPtr), exp(256, sub(32, byteLen))) // right shifting to the correct length\n                itemLen := add(dataLen, add(byteLen, 1))\n            }\n        }\n\n        return itemLen;\n    }\n\n    // @return number of bytes until the data\n    function _payloadOffset(uint256 memPtr) private pure returns (uint256) {\n        uint256 byte0;\n        assembly {\n            byte0 := byte(0, mload(memPtr))\n        }\n\n        if (byte0 < STRING_SHORT_START) {\n            return 0;\n        } else if (byte0 < STRING_LONG_START || (byte0 >= LIST_SHORT_START && byte0 < LIST_LONG_START)) {\n            return 1;\n        } else if (byte0 < LIST_SHORT_START) {\n            // being explicit\n            return byte0 - (STRING_LONG_START - 1) + 1;\n        } else {\n            return byte0 - (LIST_LONG_START - 1) + 1;\n        }\n    }\n\n    /*\n     * @param src Pointer to source\n     * @param dest Pointer to destination\n     * @param len Amount of memory to copy from the source\n     */\n    function copy(uint256 src, uint256 dest, uint256 len) private pure {\n        if (len == 0) return;\n\n        // copy as many word sizes as possible\n        for (; len >= WORD_SIZE; len -= WORD_SIZE) {\n            assembly {\n                mstore(dest, mload(src))\n            }\n\n            src += WORD_SIZE;\n            dest += WORD_SIZE;\n        }\n\n        if (len > 0) {\n            // left over bytes. Mask is used to remove unwanted bytes from the word\n            uint256 mask = 256 ** (WORD_SIZE - len) - 1;\n            assembly {\n                let srcpart := and(mload(src), not(mask)) // zero out src\n                let destpart := and(mload(dest), mask) // retrieve the bytes\n                mstore(dest, or(destpart, srcpart))\n            }\n        }\n    }\n}\n"
    },
    "contracts/Cross-chain/libs/StateProofVerifier.sol": {
      "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\nimport { RLPReader } from \"./RLPReader.sol\";\nimport { MerklePatriciaProofVerifier } from \"./MerklePatriciaProofVerifier.sol\";\n\n/**\n * @title A helper library for verification of Merkle Patricia account and state proofs.\n */\nlibrary StateProofVerifier {\n    using RLPReader for RLPReader.RLPItem;\n    using RLPReader for bytes;\n\n    uint256 internal constant HEADER_STATE_ROOT_INDEX = 3;\n    uint256 internal constant HEADER_NUMBER_INDEX = 8;\n    uint256 internal constant HEADER_TIMESTAMP_INDEX = 11;\n\n    struct BlockHeader {\n        bytes32 hash;\n        bytes32 stateRootHash;\n        uint256 number;\n        uint256 timestamp;\n    }\n\n    struct Account {\n        bool exists;\n        uint256 nonce;\n        uint256 balance;\n        bytes32 storageRoot;\n        bytes32 codeHash;\n    }\n\n    struct SlotValue {\n        bool exists;\n        uint256 value;\n    }\n\n    /**\n     * @notice Parses block header and verifies its presence onchain within the latest 256 blocks.\n     * @param _headerRlpBytes RLP-encoded block header.\n     */\n    function verifyBlockHeader(\n        bytes memory _headerRlpBytes,\n        bytes32 _blockHash\n    ) internal pure returns (BlockHeader memory) {\n        BlockHeader memory header = parseBlockHeader(_headerRlpBytes);\n        require(header.hash == _blockHash, \"blockhash mismatch\");\n        return header;\n    }\n\n    /**\n     * @notice Parses RLP-encoded block header.\n     * @param _headerRlpBytes RLP-encoded block header.\n     */\n    function parseBlockHeader(bytes memory _headerRlpBytes) internal pure returns (BlockHeader memory) {\n        BlockHeader memory result;\n        RLPReader.RLPItem[] memory headerFields = _headerRlpBytes.toRlpItem().toList();\n\n        require(headerFields.length > HEADER_TIMESTAMP_INDEX);\n\n        result.stateRootHash = bytes32(headerFields[HEADER_STATE_ROOT_INDEX].toUint());\n        result.number = headerFields[HEADER_NUMBER_INDEX].toUint();\n        result.timestamp = headerFields[HEADER_TIMESTAMP_INDEX].toUint();\n        result.hash = keccak256(_headerRlpBytes);\n\n        return result;\n    }\n\n    /**\n     * @notice Verifies Merkle Patricia proof of an account and extracts the account fields.\n     *\n     * @param _addressHash Keccak256 hash of the address corresponding to the account.\n     * @param _stateRootHash MPT root hash of the Ethereum state trie.\n     */\n    function extractAccountFromProof(\n        bytes32 _addressHash, // keccak256(abi.encodePacked(address))\n        bytes32 _stateRootHash,\n        RLPReader.RLPItem[] memory _proof\n    ) internal pure returns (Account memory) {\n        bytes memory acctRlpBytes = MerklePatriciaProofVerifier.extractProofValue(\n            _stateRootHash,\n            abi.encodePacked(_addressHash),\n            _proof\n        );\n        Account memory account;\n\n        if (acctRlpBytes.length == 0) {\n            return account;\n        }\n\n        RLPReader.RLPItem[] memory acctFields = acctRlpBytes.toRlpItem().toList();\n        require(acctFields.length == 4);\n\n        account.exists = true;\n        account.nonce = acctFields[0].toUint();\n        account.balance = acctFields[1].toUint();\n        account.storageRoot = bytes32(acctFields[2].toUint());\n        account.codeHash = bytes32(acctFields[3].toUint());\n\n        return account;\n    }\n\n    /**\n     * @notice Verifies Merkle Patricia proof of a slot and extracts the slot's value.\n     *\n     * @param _slotHash Keccak256 hash of the slot position.\n     * @param _storageRootHash MPT root hash of the account's storage trie.\n     */\n    function extractSlotValueFromProof(\n        bytes32 _slotHash,\n        bytes32 _storageRootHash,\n        RLPReader.RLPItem[] memory _proof\n    ) internal pure returns (SlotValue memory) {\n        bytes memory valueRlpBytes = MerklePatriciaProofVerifier.extractProofValue(\n            _storageRootHash,\n            abi.encodePacked(_slotHash),\n            _proof\n        );\n\n        SlotValue memory value;\n\n        if (valueRlpBytes.length != 0) {\n            value.exists = true;\n            value.value = valueRlpBytes.toRlpItem().toUint();\n        }\n\n        return value;\n    }\n}\n"
    },
    "contracts/Cross-chain/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/Cross-chain/Voting/BlockHashDispatcher/ArbBlockHashDispatcher.sol": {
      "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.25;\n\nimport \"./BlockHashDispatcherBase.sol\";\n\n/**\n * @title IArbSys\n * @notice Interface for the ArbSys's preCompiled Contract for, `arbBlockHash()` function.\n */\n\ninterface ArbSys {\n    function arbBlockHash(uint256) external view returns (bytes32);\n}\n\n/**\n * @title ArbBlockHashDispatcher\n * @notice Arbitrum-specific implementation of BlockHashDispatcherBase using ArbSys.\n */\ncontract ArbBlockHashDispatcher is BlockHashDispatcherBase {\n    ArbSys public constant arbsys = ArbSys(address(100));\n\n    constructor(\n        address endpoint_,\n        address owner_,\n        uint32 bnbChainEId_,\n        uint32 chainId_\n    ) BlockHashDispatcherBase(endpoint_, owner_, bnbChainEId_, chainId_) {}\n\n    function getBlockHash(uint256 blockNumber) public view override returns (bytes32 blockHash) {\n        blockHash = blockNumToHash[blockNumber];\n        if (blockHash == bytes32(0)) {\n            blockHash = arbsys.arbBlockHash(blockNumber);\n        }\n    }\n}\n"
    },
    "contracts/Cross-chain/Voting/BlockHashDispatcher/BlockHashDispatcher.sol": {
      "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.25;\n\nimport \"./BlockHashDispatcherBase.sol\";\n\n/**\n * @title BlockHashDispatcher\n * @notice Common BlockHashDispatcherBase using blockhash().\n */\ncontract BlockHashDispatcher is BlockHashDispatcherBase {\n    constructor(\n        address endpoint_,\n        address owner_,\n        uint32 bnbChainEId_,\n        uint32 chainId_\n    ) BlockHashDispatcherBase(endpoint_, owner_, bnbChainEId_, chainId_) {}\n\n    function getBlockHash(uint256 blockNumber) public view override returns (bytes32 blockHash) {\n        blockHash = blockNumToHash[blockNumber];\n        if (blockHash == bytes32(0)) {\n            blockHash = blockhash(blockNumber);\n        }\n    }\n}\n"
    },
    "contracts/Cross-chain/Voting/BlockHashDispatcher/BlockHashDispatcherBase.sol": {
      "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.25;\n\nimport { OApp, MessagingFee, Origin } from \"@layerzerolabs/oapp-evm/contracts/oapp/OApp.sol\";\nimport { Pausable } from \"@openzeppelin/contracts/security/Pausable.sol\";\nimport { ensureNonzeroAddress } from \"@venusprotocol/solidity-utilities/contracts/validators.sol\";\nimport { Ownable } from \"@openzeppelin/contracts/access/Ownable.sol\";\nimport { Initializable } from \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\n\n/**\n * @title BlockHashDispatcherBase\n * @notice Abstract base contract for dispatching block hashes to a proposal chain.\n * @dev Provides shared functionality, with getBlockHash to be implemented by derived contracts.\n */\nabstract contract BlockHashDispatcherBase is Pausable, OApp, Initializable {\n    /**\n     * @notice ID of the proposal chain (e.g., BNB Chain) where block hashes will be sent\n     */\n    uint32 public BSC_CHAIN_ID;\n\n    /**\n     * @notice LZ chain id of this chain\n     */\n    uint32 public chainId;\n\n    // blockNumber -> blockHash\n    mapping(uint256 => bytes32) public blockNumToHash;\n\n    /**\n     * @notice Emitted when a block hash is dispatched to the proposal chain\n     * @param pId Proposal Id\n     * @param blockNum Block number\n     * @param payload Encoded data payload\n     */\n    event HashDispatched(uint256 indexed pId, uint256 indexed blockNum, bytes payload);\n\n    /// @notice Error thrown when an invalid chain ID is provided\n    error InvalidChainEid(uint32 eid);\n\n    /// @notice Error thrown when a block hash is not found\n    error BlockHashNotFound(uint256 blockNumber);\n\n    constructor(\n        address endpoint_,\n        address owner_,\n        uint32 bnbChainEId_,\n        uint32 chainId_\n    ) OApp(endpoint_, owner_) Ownable() {\n        ensureNonzeroAddress(address(endpoint_));\n        if (bnbChainEId_ == 0 || chainId_ == 0) {\n            revert InvalidChainEid(0);\n        }\n\n        BSC_CHAIN_ID = bnbChainEId_;\n        chainId = chainId_;\n    }\n\n    /**\n     * @notice Pauses the contract\n     * @dev Callable only by the owner\n     */\n    function pause() external onlyOwner {\n        _pause();\n    }\n\n    /**\n     * @notice Unpauses the contract\n     * @dev Callable only by the owner\n     */\n    function unpause() external onlyOwner {\n        _unpause();\n    }\n\n    /**\n     * @notice Retrieves the block hash for a given block number.\n     * @dev Must be implemented by derived contracts to provide chain-specific block hash retrieval.\n     * @param blockNumber The block number to query.\n     * @return blockHash The hash of the specified block.\n     */\n    function getBlockHash(uint256 blockNumber) public view virtual returns (bytes32 blockHash);\n\n    /**\n     * @notice Public function to store the hash of a given block number\n     */\n    function setHash(uint256 blockNumber) public {\n        bytes32 _blockHash = getBlockHash(blockNumber);\n        if (_blockHash == bytes32(0)) {\n            revert BlockHashNotFound(blockNumber);\n        }\n\n        blockNumToHash[blockNumber] = _blockHash;\n    }\n\n    /**\n     * @notice Generates a payload containing a block hash\n     * @param pId Unique identifier for the proposal\n     * @param blockNumber Block number for which the hash is generated\n     * @return payload Encoded payload containing the proposal ID, block number, and block hash\n     */\n    function getPayload(uint256 pId, uint256 blockNumber) public view returns (bytes memory payload) {\n        bytes32 blockHash_ = getBlockHash(blockNumber);\n        payload = abi.encode(pId, blockNumber, blockHash_, chainId);\n    }\n\n    /**\n     * @notice Quotes the messaging fee for dispatching a block hash\n     * @param pId Proposal ID\n     * @param blockNumber Block number\n     * @param options Messaging options\n     * @param payInLzToken Payment method (native token or LayerZero token)\n     * @return fee The messaging fee details\n     */\n    function quote(\n        uint256 pId,\n        uint256 blockNumber,\n        bytes memory options,\n        bool payInLzToken\n    ) public view returns (MessagingFee memory fee) {\n        return _quote(BSC_CHAIN_ID, getPayload(pId, blockNumber), options, payInLzToken);\n    }\n\n    /**\n     * @notice Dispatches a block hash along with its proposal ID and block number to the proposal chain\n     * @param pId Proposal ID\n     * @param blockNumber Block number\n     * @param zroTokens Address for ZRO token payment\n     * @param options Custom gas options for execution on the destination chain\n     */\n    function dispatchHash(\n        uint256 pId,\n        uint256 blockNumber,\n        uint256 zroTokens,\n        bytes calldata options\n    ) external payable whenNotPaused {\n        bytes32 blockHash = blockNumToHash[blockNumber];\n        if (blockHash == bytes32(0)) {\n            setHash(blockNumber);\n        }\n        bytes memory payload = getPayload(pId, blockNumber);\n\n        _lzSend(\n            BSC_CHAIN_ID,\n            payload,\n            options,\n            // Fee in native gas and ZRO token.\n            MessagingFee(msg.value, zroTokens),\n            // Refund address in case of failed source message.\n            payable(msg.sender)\n        );\n        emit HashDispatched(pId, blockNumber, payload);\n    }\n\n    /**\n     * @notice Retrieves the block hash for a given block number and proposal ID\n     * @param blockNumber The block number\n     * @param pId The proposal ID\n     * @return pId The proposal ID\n     * @return blockNumber The block number\n     * @return blockHash_ The block hash\n     */\n    function getHash(\n        uint256 blockNumber,\n        uint256 pId\n    ) external view whenNotPaused returns (uint256, uint256, bytes32, uint32) {\n        bytes32 blockHash_ = getBlockHash(blockNumber);\n        return (pId, blockNumber, blockHash_, chainId);\n    }\n\n    /**\n     * @notice Internal function to handle incoming LayerZero messages\n     */\n    function _lzReceive(\n        Origin calldata _origin,\n        bytes32 _guid,\n        bytes calldata payload,\n        address _executor,\n        bytes calldata _extraData\n    ) internal override {}\n}\n"
    },
    "contracts/Cross-chain/Voting/DataWarehouse.sol": {
      "content": "// SPDX-License-Identifier: BUSL-1.1\npragma solidity ^0.8.0;\n\nimport { IDataWarehouse } from \"../interfaces/IDataWarehouse.sol\";\nimport { StateProofVerifier } from \"../libs/StateProofVerifier.sol\";\nimport { RLPReader } from \"../libs/RLPReader.sol\";\n\n/**\n * @title DataWarehouse\n * @author BGD Labs\n * @notice This contract stores account state roots and allows proving against them\n */\ncontract DataWarehouse is IDataWarehouse {\n    using RLPReader for bytes;\n    using RLPReader for RLPReader.RLPItem;\n\n    uint256 public delay;\n    // account address => (block hash => Account state root hash)\n    mapping(address => mapping(bytes32 => bytes32)) internal _storageRoots;\n\n    // account address => (block hash => (slot => slot value))\n    mapping(address => mapping(bytes32 => mapping(bytes32 => uint256))) internal _slotsRegistered;\n\n    /// @inheritdoc IDataWarehouse\n    function getStorageRoots(address account, bytes32 blockHash) external view returns (bytes32) {\n        return _storageRoots[account][blockHash];\n    }\n\n    /// @inheritdoc IDataWarehouse\n    function getRegisteredSlot(bytes32 blockHash, address account, bytes32 slot) external view returns (uint256) {\n        return _slotsRegistered[account][blockHash][slot];\n    }\n\n    /// @inheritdoc IDataWarehouse\n    function processStorageRoot(\n        address account,\n        bytes32 blockHash,\n        bytes memory blockHeaderRLP,\n        bytes memory accountStateProofRLP\n    ) external returns (StateProofVerifier.BlockHeader memory) {\n        StateProofVerifier.BlockHeader memory decodedHeader = StateProofVerifier.verifyBlockHeader(\n            blockHeaderRLP,\n            blockHash\n        );\n\n        // The path for an account in the state trie is the hash of its address\n        bytes32 proofPath = keccak256(abi.encodePacked(account));\n        StateProofVerifier.Account memory accountData = StateProofVerifier.extractAccountFromProof(\n            proofPath,\n            decodedHeader.stateRootHash,\n            accountStateProofRLP.toRlpItem().toList()\n        );\n\n        _storageRoots[account][blockHash] = accountData.storageRoot;\n\n        emit StorageRootProcessed(msg.sender, account, blockHash);\n\n        return decodedHeader;\n    }\n\n    /// @inheritdoc IDataWarehouse\n    function getStorage(\n        address account,\n        bytes32 blockHash,\n        bytes32 slot,\n        bytes memory storageProof\n    ) public view returns (StateProofVerifier.SlotValue memory) {\n        bytes32 root = _storageRoots[account][blockHash];\n        require(root != bytes32(0), \"DataWarehouse: storage root not processed\");\n        // The path for a storage value is the hash of its slot\n        bytes32 proofPath = keccak256(abi.encodePacked(slot));\n        StateProofVerifier.SlotValue memory slotData = StateProofVerifier.extractSlotValueFromProof(\n            proofPath,\n            root,\n            storageProof.toRlpItem().toList()\n        );\n\n        return slotData;\n    }\n\n    /// @inheritdoc IDataWarehouse\n    function processStorageSlot(\n        address account,\n        bytes32 blockHash,\n        bytes32 slot,\n        bytes calldata storageProof\n    ) external {\n        StateProofVerifier.SlotValue memory storageSlot = getStorage(account, blockHash, slot, storageProof);\n\n        _slotsRegistered[account][blockHash][slot] = storageSlot.value;\n\n        emit StorageSlotProcessed(msg.sender, account, blockHash, slot, storageSlot.value);\n    }\n}\n"
    },
    "contracts/Cross-chain/Voting/VotingPowerAggregator.sol": {
      "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.25;\n\nimport { IDataWarehouse } from \"../interfaces/IDataWarehouse.sol\";\nimport { IGovernorBravoDelegate } from \"../interfaces/IGovernorBravoDelegate.sol\";\nimport { IBlockHashDispatcher } from \"../interfaces/IBlockHashDispatcher.sol\";\nimport { SlotUtils } from \"../../Utils/SlotUtils.sol\";\nimport { StateProofVerifier } from \"../libs/StateProofVerifier.sol\";\nimport { ExcessivelySafeCall } from \"@layerzerolabs/solidity-examples/contracts/libraries/ExcessivelySafeCall.sol\";\nimport { ensureNonzeroAddress } from \"@venusprotocol/solidity-utilities/contracts/validators.sol\";\nimport { Pausable } from \"@openzeppelin/contracts/security/Pausable.sol\";\nimport { MessagingFee, Origin } from \"@layerzerolabs/oapp-evm/contracts/oapp/OApp.sol\";\nimport { OAppRead } from \"@layerzerolabs/oapp-evm/contracts/oapp/OAppRead.sol\";\nimport { ILayerZeroEndpointV2, MessagingFee, MessagingReceipt, Origin } from \"@layerzerolabs/lz-evm-protocol-v2/contracts/interfaces/ILayerZeroEndpointV2.sol\";\nimport { ReadCodecV1, EVMCallComputeV1, EVMCallRequestV1 } from \"@layerzerolabs/oapp-evm/contracts/oapp/libs/ReadCodecV1.sol\";\nimport { OAppOptionsType3 } from \"@layerzerolabs/oapp-evm/contracts/oapp/libs/OAppOptionsType3.sol\";\nimport { AddressCast } from \"@layerzerolabs/lz-evm-protocol-v2/contracts/libs/AddressCast.sol\";\nimport { IXvsVault } from \"../interfaces/IXvsVault.sol\";\n\ncontract VotingPowerAggregator is Pausable, OAppRead, OAppOptionsType3 {\n    using ExcessivelySafeCall for address;\n\n    struct NetworkProposalBlockDetails {\n        uint256 blockNumber;\n        bytes32 blockHash;\n    }\n\n    struct SyncingParameters {\n        uint32 remoteChainEid;\n        bytes32 blockHash;\n        bytes remoteBlockHeaderRLP;\n        bytes xvsVaultStateProofRLP;\n    }\n\n    struct NetworkConfig {\n        address xvsVault;\n        address blockHashDispatcher;\n        bool isLzReadSupported;\n    }\n\n    struct LzReadParams {\n        uint32 remoteChainEid;\n        uint256 blockNumber;\n    }\n\n    struct Proofs {\n        uint32 remoteChainEid;\n        bytes numCheckpointsProof;\n        bytes checkpointsProof;\n    }\n\n    /// @notice LayerZero read message type.\n    uint8 private constant READ_MSG_TYPE = 1;\n\n    uint8 public constant CHECKPOINTS_SLOT = 16;\n    uint8 public constant NUM_CHECKPOINTS_SLOT = 17;\n    uint16 public constant MAX_BLOCK_TIME_DIFF = 600; // 10 mins\n    uint32 private constant BSC_CHAIN_ID = 5656;\n\n    IDataWarehouse public warehouse;\n    IGovernorBravoDelegate public governorBravo;\n    IXvsVault public bscXvsVault;\n\n    uint32 public READ_CHANNEL;\n\n    // remoteChainEId -> block number -> block hash\n    mapping(uint32 => mapping(uint256 => bytes32)) public remoteBlockHash;\n\n    // pId -> remoteChainEid -> (blockNumber, blockHash)\n    mapping(uint256 => mapping(uint32 => NetworkProposalBlockDetails)) public proposalBlockDetails;\n\n    // remoteChainEid -> NetworkConfig\n    mapping(uint32 => NetworkConfig) public networkConfig;\n\n    // pId -> remoteChainEids for lzRead supported networks\n    mapping(uint256 => uint32[]) public proposalRemoteChainEids;\n\n    // pId -> (remoteChainEid, blockNumber)\n    mapping(uint256 => LzReadParams[]) public lzReadParams;\n\n    /**\n     * @notice Emitted when remote block hash is received\n     */\n    event BlockHashReceived(uint256 pId, uint32 remoteChainid, uint256 blockNumber);\n\n    /**\n     * @notice Emitted when proposal failed\n     */\n    event ReceivePayloadFailed(uint32 indexed remoteChainEid, bytes indexed remoteAddress, uint64 nonce, bytes reason);\n\n    /**\n     * @notice Emitted when block hash of remote chain is received\n     */\n    event HashReceived(uint256 indexed remoteIdentifier, uint32 indexed remoteChainEid, bytes blockHash);\n\n    /**\n     * @notice Emitted when remote configurations are updated\n     */\n    event UpdateDeactivatedremoteChainEid(uint32 indexed remoteChainEid, bool isSupported);\n\n    /**\n     * @notice Emitted when vault address is updated\n     */\n    event UpdateNetworkConfig(\n        uint32 indexed remoteChainEid,\n        address xvsVault,\n        address dispatcher,\n        bool isLzreadSupported\n    );\n\n    /**\n     * @notice Emitted when syncing of voting power starts\n     */\n    event StartVotingPowerSync(\n        uint256 indexed pId,\n        address proposer,\n        SyncingParameters[] syncingParameters,\n        Proofs[] proposerVotingProofs,\n        uint256 proposalThreshold,\n        bytes extraOptions\n    );\n    /**\n     * @notice Emitted when call send to dispatcher on remote chain\n     */\n    event ReadRemoteBlockHash(uint256 indexed pId, bytes cmd, bytes option);\n\n    /**\n     * @notice Thrown when syncing details for an unsupported network is provided\n     */\n    error RemoteChainNotSupported(uint32 chainId);\n\n    /**\n     * @notice Thrown when chain id is deactivated\n     */\n    error DeactivatedChainId(uint32 chainId);\n\n    /**\n     * @notice Thrown when an access controlled function is called\n     */\n    error InvalidCaller(address providedAddress, address requiredAddress);\n\n    /**\n     * @notice Thrown when an invalid block timestamp is provided\n     */\n    error InvalidBlockTimestamp(uint32 remoteChainEid, uint256 providedTimestamp);\n\n    /**\n     * @notice Thrown when array lengths mismatch\n     */\n    error LengthMismatch(string additionalReason);\n\n    /**\n     * @notice Thrown when proposal threshold is not met\n     */\n    error ProposalThresholdNotMet(uint256 providedPower, uint256 acceptablePower);\n\n    /**\n     * @notice Thrown when an invalid chain id is provided\n     */\n    error InvalidChainEid(uint32 remoteChainEid);\n\n    /**\n     * @notice Thrown when a proposal does not exist\n     */\n    error LZReceiveProposalNotExists(string reason);\n\n    constructor(\n        address endpoint_,\n        address delegate,\n        uint32 readChannel,\n        address warehouseAddress,\n        address governorBravoAddress,\n        address bscXvsVaultAddress\n    ) OAppRead(endpoint_, delegate) {\n        ensureNonzeroAddress(warehouseAddress);\n        ensureNonzeroAddress(governorBravoAddress);\n        ensureNonzeroAddress(bscXvsVaultAddress);\n        warehouse = IDataWarehouse(warehouseAddress);\n        governorBravo = IGovernorBravoDelegate(governorBravoAddress);\n        bscXvsVault = IXvsVault(bscXvsVaultAddress);\n\n        // Set the read channel\n        setReadChannel(readChannel, true);\n    }\n\n    /**\n     * @notice Triggers the paused state of the aggregator\n     * @custom:access Only owner\n     */\n    function pause() external onlyOwner {\n        _pause();\n    }\n\n    /**\n     * @notice Triggers the resume state of the aggregator\n     * @custom:access Only owner\n     */\n    function unpause() external onlyOwner {\n        _unpause();\n    }\n\n    /**\n     * @notice Updates the network configuration for a given chain ID.\n     * @param remoteChainEid The chain ID for which to update the configuration.\n     * @param xvsVaultAddress The address of the XVS vault.\n     * @param blockHashDispatcherAddress The address of the block hash fetcher.\n     * @custom:access Only owner\n     */\n    function updateNetworkConfig(\n        uint32 remoteChainEid,\n        address xvsVaultAddress,\n        address blockHashDispatcherAddress,\n        bool isLzReadSupported\n    ) external onlyOwner {\n        ensureNonzeroAddress(xvsVaultAddress);\n        ensureNonzeroAddress(blockHashDispatcherAddress);\n\n        if (remoteChainEid == 0) {\n            revert InvalidChainEid(remoteChainEid);\n        }\n\n        networkConfig[remoteChainEid] = NetworkConfig({\n            xvsVault: xvsVaultAddress,\n            blockHashDispatcher: blockHashDispatcherAddress,\n            isLzReadSupported: isLzReadSupported\n        });\n\n        emit UpdateNetworkConfig(remoteChainEid, xvsVaultAddress, blockHashDispatcherAddress, isLzReadSupported);\n    }\n\n    /**\n     *\n     * @param pId proposal Id to start syncing voting power of\n     * @param proposer The address of the proposer\n     * @param syncingParameters Array of syncing parameters containing remote chain id with their corresponding\n     * block hash, remote block header RLP, and XVS vault state proof RLP\n     * @param proposerVotingProofs Array of proofs containing remote chain id with their corresponding proofs (numCheckpointsProof, checkpointsProof) where\n     * numCheckpointsProof is the proof data needed to verify the number of checkpoints and\n     * checkpointsProof is the proof data needed to verify the actual voting power from the checkpoints\n     * @param proposalThreshold The minimum voting power required to start syncing\n     * @param extraOptions Additional messaging options, including gas and fee settings\n     * @custom:access Only GovernorBravo\n     */\n    function startVotingPowerSync(\n        uint256 pId,\n        address proposer,\n        SyncingParameters[] calldata syncingParameters,\n        Proofs[] calldata proposerVotingProofs,\n        uint256 proposalThreshold,\n        bytes calldata extraOptions\n    ) external {\n        if (msg.sender != address(governorBravo)) {\n            revert InvalidCaller(msg.sender, address(governorBravo));\n        }\n        if (proposerVotingProofs.length > syncingParameters.length) {\n            revert LengthMismatch(\"proposerVotingProofs length > syncingParameters length\");\n        }\n\n        for (uint256 i; i < syncingParameters.length; i++) {\n            SyncingParameters memory params = syncingParameters[i];\n            if (\n                networkConfig[params.remoteChainEid].xvsVault == address(0) ||\n                networkConfig[params.remoteChainEid].blockHashDispatcher == address(0)\n            ) {\n                revert RemoteChainNotSupported(params.remoteChainEid);\n            }\n\n            StateProofVerifier.BlockHeader memory decodedHeader = warehouse.processStorageRoot(\n                networkConfig[params.remoteChainEid].xvsVault,\n                params.blockHash,\n                params.remoteBlockHeaderRLP,\n                params.xvsVaultStateProofRLP\n            );\n\n            if (!isValidBlockTimestamp(decodedHeader.timestamp)) {\n                revert InvalidBlockTimestamp(params.remoteChainEid, decodedHeader.timestamp);\n            }\n\n            proposalBlockDetails[pId][params.remoteChainEid] = NetworkProposalBlockDetails(\n                decodedHeader.number,\n                params.blockHash\n            );\n\n            proposalRemoteChainEids[pId].push(params.remoteChainEid);\n\n            if (networkConfig[params.remoteChainEid].isLzReadSupported) {\n                lzReadParams[pId].push(LzReadParams(params.remoteChainEid, decodedHeader.number));\n            }\n        }\n\n        proposalBlockDetails[pId][BSC_CHAIN_ID] = NetworkProposalBlockDetails(\n            block.number - 1,\n            blockhash(block.number - 1)\n        );\n\n        uint96 power = getVotingPower(proposer, pId, proposerVotingProofs);\n        if (power < proposalThreshold) {\n            revert ProposalThresholdNotMet(power, proposalThreshold);\n        }\n        emit StartVotingPowerSync(\n            pId,\n            proposer,\n            syncingParameters,\n            proposerVotingProofs,\n            proposalThreshold,\n            extraOptions\n        );\n\n        readRemoteBlockHash(pId, extraOptions);\n    }\n\n    /**\n     * @notice Sets the LayerZero read channel, enabling or disabling it based on `_active`.\n     * @param _channelId The channel ID to set.\n     * @param _active Flag to activate or deactivate the channel.\n     */\n    function setReadChannel(uint32 _channelId, bool _active) public override onlyOwner {\n        _setPeer(_channelId, _active ? AddressCast.toBytes32(address(this)) : bytes32(0));\n        READ_CHANNEL = _channelId;\n    }\n\n    /**\n     * @notice It will change the delegate in the endpoint.\n     * @param delegate delegate is authorized by the oapp to configure anything in layerzero\n     */\n    function setEndpointDelegate(address delegate) external onlyOwner {\n        endpoint.setDelegate(delegate);\n    }\n\n    /**\n     * @notice Sends a read request to LayerZero, querying block hashes from remote chains for a given proposal.\n     * @param proposalId Unique Id of the proposal.\n     * @param _extraOptions Additional messaging options, including gas and fee settings.\n     * @return receipt The LayerZero messaging receipt for the request.\n     */\n    function readRemoteBlockHash(\n        uint256 proposalId,\n        bytes calldata _extraOptions\n    ) public payable returns (MessagingReceipt memory receipt) {\n        uint32[] memory remoteTargetEids = new uint32[](lzReadParams[proposalId].length);\n        uint256[] memory blockNumbers = new uint256[](lzReadParams[proposalId].length);\n\n        for (uint256 i = 0; i < lzReadParams[proposalId].length; i++) {\n            remoteTargetEids[i] = lzReadParams[proposalId][i].remoteChainEid;\n            blockNumbers[i] = lzReadParams[proposalId][i].blockNumber;\n        }\n\n        bytes memory cmd = getCmd(proposalId, remoteTargetEids, blockNumbers);\n\n        emit ReadRemoteBlockHash(proposalId, cmd, _extraOptions);\n        return\n            _lzSend(\n                READ_CHANNEL,\n                cmd,\n                _extraOptions,\n                MessagingFee(msg.value, 0),\n                payable(msg.sender) // It will be proposer address\n            );\n    }\n\n    /**\n     * @notice Quotes the estimated messaging fee for querying block hashes from remote chains for a given proposal.\n     * @param proposalId Unique id of a proposal .\n     * @param remoteTargetEids Array of LayerZero Endpoint ids for the target remote chains.\n     * @param blockNumbers Array of block numbers to query hashes for on the remote chains.\n     * @param _extraOptions Additional messaging options.\n     * @param _payInLzToken Boolean flag indicating whether to pay in LayerZero tokens.\n     * @return fee The estimated messaging fee.\n     */\n    function quoteRemoteBlockHash(\n        uint256 proposalId,\n        uint32[] calldata remoteTargetEids,\n        uint256[] calldata blockNumbers,\n        bytes calldata _extraOptions,\n        bool _payInLzToken\n    ) public view returns (MessagingFee memory fee) {\n        bytes memory cmd = getCmd(proposalId, remoteTargetEids, blockNumbers);\n        return _quote(READ_CHANNEL, cmd, _extraOptions, _payInLzToken);\n    }\n\n    /**\n     * @notice Constructs a command to query the Uniswap QuoterV2 for WETH/USDC prices on all configured chains.\n     * @param proposalId Unique id of proposal.\n     * @param remoteTargetEids Array of LayerZero Endpoint IDs for the target remote chains.\n     * @param blockNumbers Array of block numbers to query hashes for on the remote chains.\n     * @return cmd The encoded command to request Uniswap quotes.\n     */\n    function getCmd(\n        uint256 proposalId,\n        uint32[] memory remoteTargetEids,\n        uint256[] memory blockNumbers\n    ) public view returns (bytes memory) {\n        uint256 networkCount = remoteTargetEids.length;\n\n        if (networkCount != blockNumbers.length) {\n            revert LengthMismatch(\"network count length != blockNumbers length\");\n        }\n\n        EVMCallRequestV1[] memory readRequests = new EVMCallRequestV1[](networkCount);\n\n        for (uint256 i = 0; i < networkCount; i++) {\n            if (networkConfig[remoteTargetEids[i]].blockHashDispatcher == address(0)) {\n                revert RemoteChainNotSupported(remoteTargetEids[i]);\n            }\n\n            bytes memory callData = abi.encodeWithSelector(\n                IBlockHashDispatcher.getHash.selector,\n                blockNumbers[i],\n                proposalId\n            );\n\n            readRequests[i] = EVMCallRequestV1({\n                appRequestLabel: uint16(i + 1),\n                targetEid: remoteTargetEids[i],\n                isBlockNum: false,\n                blockNumOrTimestamp: uint64(block.timestamp),\n                confirmations: 0,\n                to: networkConfig[remoteTargetEids[i]].blockHashDispatcher,\n                callData: callData\n            });\n        }\n\n        return ReadCodecV1.encode(0, readRequests);\n    }\n\n    /**\n     * @notice Calculates the total voting power of a voter across multiple remote chains\n     * @param voter The address of the voter for whom to calculate the voting power\n     * @param proofs Array of proofs containing remote chain id with their corresponding proofs (numCheckpointsProof, checkpointsProof) where\n     *  numCheckpointsProof is the proof data needed to verify the number of checkpoints and\n     *  checkpointsProof is the proof data needed to verify the actual voting power from the checkpoints\n     * @return power The total voting power of the voter across all supported remote chains\n     */\n    function getVotingPower(address voter, uint256 pId, Proofs[] calldata proofs) public view returns (uint96 power) {\n        uint96 totalVotingPower;\n        for (uint32 i; i < proofs.length; ++i) {\n            totalVotingPower += _getVotingPower(\n                proofs[i].remoteChainEid,\n                pId,\n                proofs[i].numCheckpointsProof,\n                proofs[i].checkpointsProof,\n                voter\n            );\n        }\n\n        totalVotingPower += bscXvsVault.getPriorVotes(voter, proposalBlockDetails[pId][BSC_CHAIN_ID].blockNumber - 1);\n\n        return totalVotingPower;\n    }\n\n    /**\n     * @dev Calculates the total voting power of a voter for a remote chain\n     * @param voter The address of the voter for whom to calculate the voting power\n     * @param pId The identifier that links to remote chain-specific data\n     * @param numCheckpointsProof The proof data needed to verify the number of checkpoints\n     * @param checkpointsProof The proof data needed to verify the actual voting power from the checkpoints\n     * @return power The total voting power of supported remote chains\n     */\n    function _getVotingPower(\n        uint32 remoteChainEid,\n        uint256 pId,\n        bytes calldata numCheckpointsProof,\n        bytes calldata checkpointsProof,\n        address voter\n    ) internal view returns (uint96) {\n        NetworkProposalBlockDetails memory blockDetails = proposalBlockDetails[pId][remoteChainEid];\n        address vault = networkConfig[remoteChainEid].xvsVault;\n\n        if (vault == address(0)) {\n            revert RemoteChainNotSupported(remoteChainEid);\n        }\n\n        StateProofVerifier.SlotValue memory latestCheckpoint = warehouse.getStorage(\n            vault,\n            blockDetails.blockHash,\n            SlotUtils.getAccountSlotHash(voter, NUM_CHECKPOINTS_SLOT),\n            numCheckpointsProof\n        );\n\n        // Reverts if latest checkpoint not exists\n        require(latestCheckpoint.exists, \"Invalid num checkpoint proof\");\n\n        if (latestCheckpoint.value == 0) {\n            return 0;\n        }\n        StateProofVerifier.SlotValue memory votingPower = warehouse.getStorage(\n            vault,\n            blockDetails.blockHash,\n            SlotUtils.getCheckpointSlotHash(voter, uint32(latestCheckpoint.value - 1), uint32(CHECKPOINTS_SLOT)),\n            checkpointsProof\n        );\n\n        // Reverts if voting power not exists\n        require(votingPower.exists, \"Invalid checkpoint proof\");\n        return uint96(votingPower.value >> 32);\n    }\n\n    /**\n     * @dev Internal function override to handle incoming messages from another chain.\n     * @param payload The encoded message payload being received. This is the resolved command from the DVN\n     *\n     * @dev The following params are unused in the current implementation of the OApp.\n     * @dev _origin A struct containing information about the message sender.\n     * @dev _guid A unique global packet identifier for the message.\n     * @dev _executor The address of the Executor responsible for processing the message.\n     * @dev _extraData Arbitrary data appended by the Executor to the message.\n     *\n     * Decodes the received payload and processes it as per the business logic defined in the function.\n     */\n    function _lzReceive(\n        Origin calldata,\n        bytes32 /*_guid*/,\n        bytes calldata payload,\n        address /*_executor*/,\n        bytes calldata /*_extraData*/\n    ) internal override {\n        (uint256 pId, uint256 blockNumber, bytes32 blockHash, uint32 remoteChainId) = abi.decode(\n            payload,\n            (uint256, uint256, bytes32, uint32)\n        );\n\n        if (proposalBlockDetails[pId][remoteChainId].blockNumber == 0) {\n            revert LZReceiveProposalNotExists(\"Remote proposal does not exist\");\n        }\n\n        remoteBlockHash[remoteChainId][blockNumber] = blockHash;\n\n        emit BlockHashReceived(pId, remoteChainId, blockNumber);\n\n        if (isProposalSynced(pId)) {\n            governorBravo.activateProposal(pId);\n        }\n    }\n\n    /**\n     * @notice Checks if the proposal is synced across all remote chains\n     * @param proposalId The identifier that links to remote chain-specific data\n     * @return True if the proposal is synced across all remote chains, false otherwise\n     */\n    function isProposalSynced(uint256 proposalId) public view returns (bool) {\n        uint32[] memory remoteProposalChainIds = proposalRemoteChainEids[proposalId];\n        uint256 proposalsLength = remoteProposalChainIds.length;\n\n        for (uint8 i = 0; i < proposalsLength; i++) {\n            uint32 remoteProposalChainId = remoteProposalChainIds[i];\n            NetworkProposalBlockDetails memory networkProposalBlockDetails = proposalBlockDetails[proposalId][\n                remoteProposalChainId\n            ];\n            if (\n                remoteBlockHash[remoteProposalChainId][networkProposalBlockDetails.blockNumber] !=\n                networkProposalBlockDetails.blockHash\n            ) {\n                return false;\n            }\n        }\n\n        return true;\n    }\n\n    /**\n     * @notice Checks if the provided block time is within 10 minutes and less than or equal to the current timestamp\n     * @param providedBlockTime The block time to be validated\n     * @return isValid True if the provided block time is valid, false otherwise\n     */\n    function isValidBlockTimestamp(uint256 providedBlockTime) internal view returns (bool) {\n        uint256 currentTimestamp = block.timestamp;\n        return (providedBlockTime <= currentTimestamp) && (providedBlockTime >= currentTimestamp - MAX_BLOCK_TIME_DIFF);\n    }\n}\n"
    },
    "contracts/Cross-chain/Voting/VotingPowerAggregatorOwner.sol": {
      "content": "// SPDX-License-Identifier: BSD-3-Clause\npragma solidity 0.8.25;\n\nimport { AccessControlledV8 } from \"../../Governance/AccessControlledV8.sol\";\nimport { IVotingPowerAggregator } from \"../interfaces/IVotingPowerAggregator.sol\";\nimport { ensureNonzeroAddress } from \"@venusprotocol/solidity-utilities/contracts/validators.sol\";\n\n/**\n * @title VotingPowerAggregatorOwner\n * @author Venus\n **/\n\ncontract VotingPowerAggregatorOwner is AccessControlledV8 {\n    /**\n     *  @custom:oz-upgrades-unsafe-allow state-variable-immutable\n     */\n    IVotingPowerAggregator public immutable VOTING_POWER_AGGREGATOR;\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 votingPowerAggregator) {\n        require(votingPowerAggregator != address(0), \"Address must not be zero\");\n        VOTING_POWER_AGGREGATOR = IVotingPowerAggregator(votingPowerAggregator);\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 dest message sender address\n     * @param destChainId_ The LayerZero id of a dest chain\n     * @param destAddress_ The address of the contract on the dest chain\n     * @custom:access Controlled by AccessControlManager\n     * @custom:event Emits setPeer with dest chain Id and dest address\n     */\n    function setPeer(uint16 destChainId_, bytes32 destAddress_) external {\n        _checkAccessAllowed(\"setPeer(uint16,bytes)\");\n        require(destChainId_ != 0, \"ChainId must not be zero\");\n        VOTING_POWER_AGGREGATOR.setPeer(destChainId_, destAddress_);\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(VOTING_POWER_AGGREGATOR).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        VOTING_POWER_AGGREGATOR.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/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 private _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/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_unchained(accessControlManager);\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"
    },
    "contracts/Utils/SlotUtils.sol": {
      "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nlibrary SlotUtils {\n    /**\n     * @notice method to calculate the slot hash of the a mapping indexed by account\n     * @param account address of the balance holder\n     * @param balanceMappingPosition base position of the storage slot of the balance on a token contract\n     * @return the slot hash\n     */\n    function getAccountSlotHash(address account, uint256 balanceMappingPosition) internal pure returns (bytes32) {\n        return keccak256(abi.encodePacked(bytes32(uint256(uint160(account))), balanceMappingPosition));\n    }\n\n    /**\n     * @notice method to calculate the slot hash of the a mapping indexed by voter and chainId\n     * @param voter address of the voter\n     * @param numCheckpoint id of the chain of the votingMachine\n     * @param representativesMappingPosition base position of the storage slot of the representatives on governance contract\n     * @return the slot hash\n     * @dev mapping(address => mapping(uint256 => address))\n     */\n    function getCheckpointSlotHash(\n        address voter,\n        uint32 numCheckpoint,\n        uint32 representativesMappingPosition\n    ) internal pure returns (bytes32) {\n        bytes memory firstLevelEncoded = abi.encode(bytes32(uint256(uint160(voter))), representativesMappingPosition);\n\n        bytes memory secondLevelEncoded = abi.encode(numCheckpoint);\n\n        return keccak256(abi.encodePacked(secondLevelEncoded, (keccak256(firstLevelEncoded))));\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"
    }
  },
  "settings": {
    "optimizer": {
      "enabled": true,
      "runs": 10000
    },
    "evmVersion": "paris",
    "outputSelection": {
      "*": {
        "*": [
          "storageLayout",
          "abi",
          "evm.bytecode",
          "evm.deployedBytecode",
          "evm.methodIdentifiers",
          "metadata",
          "devdoc",
          "userdoc",
          "evm.gasEstimates"
        ],
        "": ["ast"]
      }
    },
    "metadata": {
      "useLiteralContent": true
    }
  }
}
