UNPKG

@hyperlane-xyz/core

Version:

Core solidity contracts for Hyperlane

2 lines 1.06 MB
{"input":{"language":"Solidity","sources":{"@arbitrum/nitro-contracts/src/bridge/IBridge.sol":{"content":"// Copyright 2021-2022, Offchain Labs, Inc.\n// For license information, see https://github.com/OffchainLabs/nitro-contracts/blob/main/LICENSE\n// SPDX-License-Identifier: BUSL-1.1\n\n// solhint-disable-next-line compiler-version\npragma solidity >=0.6.9 <0.9.0;\n\nimport \"./IOwnable.sol\";\n\ninterface IBridge {\n    /// @dev This is an instruction to offchain readers to inform them where to look\n    ///      for sequencer inbox batch data. This is not the type of data (eg. das, brotli encoded, or blob versioned hash)\n    ///      and this enum is not used in the state transition function, rather it informs an offchain\n    ///      reader where to find the data so that they can supply it to the replay binary\n    enum BatchDataLocation {\n        /// @notice The data can be found in the transaction call data\n        TxInput,\n        /// @notice The data can be found in an event emitted during the transaction\n        SeparateBatchEvent,\n        /// @notice This batch contains no data\n        NoData,\n        /// @notice The data can be found in the 4844 data blobs on this transaction\n        Blob\n    }\n\n    struct TimeBounds {\n        uint64 minTimestamp;\n        uint64 maxTimestamp;\n        uint64 minBlockNumber;\n        uint64 maxBlockNumber;\n    }\n\n    event MessageDelivered(\n        uint256 indexed messageIndex,\n        bytes32 indexed beforeInboxAcc,\n        address inbox,\n        uint8 kind,\n        address sender,\n        bytes32 messageDataHash,\n        uint256 baseFeeL1,\n        uint64 timestamp\n    );\n\n    event BridgeCallTriggered(\n        address indexed outbox,\n        address indexed to,\n        uint256 value,\n        bytes data\n    );\n\n    event InboxToggle(address indexed inbox, bool enabled);\n\n    event OutboxToggle(address indexed outbox, bool enabled);\n\n    event SequencerInboxUpdated(address newSequencerInbox);\n\n    event RollupUpdated(address rollup);\n\n    function allowedDelayedInboxList(uint256) external returns (address);\n\n    function allowedOutboxList(uint256) external returns (address);\n\n    /// @dev Accumulator for delayed inbox messages; tail represents hash of the current state; each element represents the inclusion of a new message.\n    function delayedInboxAccs(uint256) external view returns (bytes32);\n\n    /// @dev Accumulator for sequencer inbox messages; tail represents hash of the current state; each element represents the inclusion of a new message.\n    function sequencerInboxAccs(uint256) external view returns (bytes32);\n\n    function rollup() external view returns (IOwnable);\n\n    function sequencerInbox() external view returns (address);\n\n    function activeOutbox() external view returns (address);\n\n    function allowedDelayedInboxes(address inbox) external view returns (bool);\n\n    function allowedOutboxes(address outbox) external view returns (bool);\n\n    function sequencerReportedSubMessageCount() external view returns (uint256);\n\n    function executeCall(\n        address to,\n        uint256 value,\n        bytes calldata data\n    ) external returns (bool success, bytes memory returnData);\n\n    function delayedMessageCount() external view returns (uint256);\n\n    function sequencerMessageCount() external view returns (uint256);\n\n    // ---------- onlySequencerInbox functions ----------\n\n    function enqueueSequencerMessage(\n        bytes32 dataHash,\n        uint256 afterDelayedMessagesRead,\n        uint256 prevMessageCount,\n        uint256 newMessageCount\n    )\n        external\n        returns (\n            uint256 seqMessageIndex,\n            bytes32 beforeAcc,\n            bytes32 delayedAcc,\n            bytes32 acc\n        );\n\n    /**\n     * @dev Allows the sequencer inbox to submit a delayed message of the batchPostingReport type\n     *      This is done through a separate function entrypoint instead of allowing the sequencer inbox\n     *      to call `enqueueDelayedMessage` to avoid the gas overhead of an extra SLOAD in either\n     *      every delayed inbox or every sequencer inbox call.\n     */\n    function submitBatchSpendingReport(address batchPoster, bytes32 dataHash)\n        external\n        returns (uint256 msgNum);\n\n    // ---------- onlyRollupOrOwner functions ----------\n\n    function setSequencerInbox(address _sequencerInbox) external;\n\n    function setDelayedInbox(address inbox, bool enabled) external;\n\n    function setOutbox(address inbox, bool enabled) external;\n\n    function updateRollupAddress(IOwnable _rollup) external;\n}\n"},"@arbitrum/nitro-contracts/src/bridge/IOutbox.sol":{"content":"// Copyright 2021-2022, Offchain Labs, Inc.\n// For license information, see https://github.com/OffchainLabs/nitro-contracts/blob/main/LICENSE\n// SPDX-License-Identifier: BUSL-1.1\n\n// solhint-disable-next-line compiler-version\npragma solidity >=0.6.9 <0.9.0;\n\nimport \"./IBridge.sol\";\n\ninterface IOutbox {\n    event SendRootUpdated(bytes32 indexed outputRoot, bytes32 indexed l2BlockHash);\n    event OutBoxTransactionExecuted(\n        address indexed to,\n        address indexed l2Sender,\n        uint256 indexed zero,\n        uint256 transactionIndex\n    );\n\n    function initialize(IBridge _bridge) external;\n\n    function rollup() external view returns (address); // the rollup contract\n\n    function bridge() external view returns (IBridge); // the bridge contract\n\n    function spent(uint256) external view returns (bytes32); // packed spent bitmap\n\n    function roots(bytes32) external view returns (bytes32); // maps root hashes => L2 block hash\n\n    // solhint-disable-next-line func-name-mixedcase\n    function OUTBOX_VERSION() external view returns (uint128); // the outbox version\n\n    function updateSendRoot(bytes32 sendRoot, bytes32 l2BlockHash) external;\n\n    function updateRollupAddress() external;\n\n    /// @notice When l2ToL1Sender returns a nonzero address, the message was originated by an L2 account\n    ///         When the return value is zero, that means this is a system message\n    /// @dev the l2ToL1Sender behaves as the tx.origin, the msg.sender should be validated to protect against reentrancies\n    function l2ToL1Sender() external view returns (address);\n\n    /// @return l2Block return L2 block when the L2 tx was initiated or 0 if no L2 to L1 transaction is active\n    function l2ToL1Block() external view returns (uint256);\n\n    /// @return l1Block return L1 block when the L2 tx was initiated or 0 if no L2 to L1 transaction is active\n    function l2ToL1EthBlock() external view returns (uint256);\n\n    /// @return timestamp return L2 timestamp when the L2 tx was initiated or 0 if no L2 to L1 transaction is active\n    function l2ToL1Timestamp() external view returns (uint256);\n\n    /// @return outputId returns the unique output identifier of the L2 to L1 tx or 0 if no L2 to L1 transaction is active\n    function l2ToL1OutputId() external view returns (bytes32);\n\n    /**\n     * @notice Executes a messages in an Outbox entry.\n     * @dev Reverts if dispute period hasn't expired, since the outbox entry\n     *      is only created once the rollup confirms the respective assertion.\n     * @dev it is not possible to execute any L2-to-L1 transaction which contains data\n     *      to a contract address without any code (as enforced by the Bridge contract).\n     * @param proof Merkle proof of message inclusion in send root\n     * @param index Merkle path to message\n     * @param l2Sender sender if original message (i.e., caller of ArbSys.sendTxToL1)\n     * @param to destination address for L1 contract call\n     * @param l2Block l2 block number at which sendTxToL1 call was made\n     * @param l1Block l1 block number at which sendTxToL1 call was made\n     * @param l2Timestamp l2 Timestamp at which sendTxToL1 call was made\n     * @param value wei in L1 message\n     * @param data abi-encoded L1 message data\n     */\n    function executeTransaction(\n        bytes32[] calldata proof,\n        uint256 index,\n        address l2Sender,\n        address to,\n        uint256 l2Block,\n        uint256 l1Block,\n        uint256 l2Timestamp,\n        uint256 value,\n        bytes calldata data\n    ) external;\n\n    /**\n     *  @dev function used to simulate the result of a particular function call from the outbox\n     *       it is useful for things such as gas estimates. This function includes all costs except for\n     *       proof validation (which can be considered offchain as a somewhat of a fixed cost - it's\n     *       not really a fixed cost, but can be treated as so with a fixed overhead for gas estimation).\n     *       We can't include the cost of proof validation since this is intended to be used to simulate txs\n     *       that are included in yet-to-be confirmed merkle roots. The simulation entrypoint could instead pretend\n     *       to confirm a pending merkle root, but that would be less practical for integrating with tooling.\n     *       It is only possible to trigger it when the msg sender is address zero, which should be impossible\n     *       unless under simulation in an eth_call or eth_estimateGas\n     */\n    function executeTransactionSimulation(\n        uint256 index,\n        address l2Sender,\n        address to,\n        uint256 l2Block,\n        uint256 l1Block,\n        uint256 l2Timestamp,\n        uint256 value,\n        bytes calldata data\n    ) external;\n\n    /**\n     * @param index Merkle path to message\n     * @return true if the message has been spent\n     */\n    function isSpent(uint256 index) external view returns (bool);\n\n    function calculateItemHash(\n        address l2Sender,\n        address to,\n        uint256 l2Block,\n        uint256 l1Block,\n        uint256 l2Timestamp,\n        uint256 value,\n        bytes calldata data\n    ) external pure returns (bytes32);\n\n    function calculateMerkleRoot(\n        bytes32[] memory proof,\n        uint256 path,\n        bytes32 item\n    ) external pure returns (bytes32);\n\n    /**\n     * @dev function to be called one time during the outbox upgrade process\n     *      this is used to fix the storage slots\n     */\n    function postUpgradeInit() external;\n}\n"},"@arbitrum/nitro-contracts/src/bridge/IOwnable.sol":{"content":"// Copyright 2021-2022, Offchain Labs, Inc.\n// For license information, see https://github.com/OffchainLabs/nitro-contracts/blob/main/LICENSE\n// SPDX-License-Identifier: BUSL-1.1\n\n// solhint-disable-next-line compiler-version\npragma solidity >=0.4.21 <0.9.0;\n\ninterface IOwnable {\n    function owner() external view returns (address);\n}\n"},"@arbitrum/nitro-contracts/src/precompiles/ArbSys.sol":{"content":"// Copyright 2021-2022, Offchain Labs, Inc.\n// For license information, see https://github.com/OffchainLabs/nitro-contracts/blob/main/LICENSE\n// SPDX-License-Identifier: BUSL-1.1\n\npragma solidity >=0.4.21 <0.9.0;\n\n/**\n * @title System level functionality\n * @notice For use by contracts to interact with core L2-specific functionality.\n * Precompiled contract that exists in every Arbitrum chain at address(100), 0x0000000000000000000000000000000000000064.\n */\ninterface ArbSys {\n    /**\n     * @notice Get Arbitrum block number (distinct from L1 block number; Arbitrum genesis block has block number 0)\n     * @return block number as int\n     */\n    function arbBlockNumber() external view returns (uint256);\n\n    /**\n     * @notice Get Arbitrum block hash (reverts unless currentBlockNum-256 <= arbBlockNum < currentBlockNum)\n     * @return block hash\n     */\n    function arbBlockHash(uint256 arbBlockNum) external view returns (bytes32);\n\n    /**\n     * @notice Gets the rollup's unique chain identifier\n     * @return Chain identifier as int\n     */\n    function arbChainID() external view returns (uint256);\n\n    /**\n     * @notice Get internal version number identifying an ArbOS build\n     * @return version number as int\n     */\n    function arbOSVersion() external view returns (uint256);\n\n    /**\n     * @notice Returns 0 since Nitro has no concept of storage gas\n     * @return uint 0\n     */\n    function getStorageGasAvailable() external view returns (uint256);\n\n    /**\n     * @notice (deprecated) check if current call is top level (meaning it was triggered by an EoA or a L1 contract)\n     * @dev this call has been deprecated and may be removed in a future release\n     * @return true if current execution frame is not a call by another L2 contract\n     */\n    function isTopLevelCall() external view returns (bool);\n\n    /**\n     * @notice map L1 sender contract address to its L2 alias\n     * @param sender sender address\n     * @param unused argument no longer used\n     * @return aliased sender address\n     */\n    function mapL1SenderContractAddressToL2Alias(address sender, address unused)\n        external\n        pure\n        returns (address);\n\n    /**\n     * @notice check if the caller (of this caller of this) is an aliased L1 contract address\n     * @return true iff the caller's address is an alias for an L1 contract address\n     */\n    function wasMyCallersAddressAliased() external view returns (bool);\n\n    /**\n     * @notice return the address of the caller (of this caller of this), without applying L1 contract address aliasing\n     * @return address of the caller's caller, without applying L1 contract address aliasing\n     */\n    function myCallersAddressWithoutAliasing() external view returns (address);\n\n    /**\n     * @notice Send given amount of Eth to dest from sender.\n     * This is a convenience function, which is equivalent to calling sendTxToL1 with empty data.\n     * @param destination recipient address on L1\n     * @return unique identifier for this L2-to-L1 transaction.\n     */\n    function withdrawEth(address destination) external payable returns (uint256);\n\n    /**\n     * @notice Send a transaction to L1\n     * @dev it is not possible to execute on the L1 any L2-to-L1 transaction which contains data\n     * to a contract address without any code (as enforced by the Bridge contract).\n     * @param destination recipient address on L1\n     * @param data (optional) calldata for L1 contract call\n     * @return a unique identifier for this L2-to-L1 transaction.\n     */\n    function sendTxToL1(address destination, bytes calldata data)\n        external\n        payable\n        returns (uint256);\n\n    /**\n     * @notice Get send Merkle tree state\n     * @return size number of sends in the history\n     * @return root root hash of the send history\n     * @return partials hashes of partial subtrees in the send history tree\n     */\n    function sendMerkleTreeState()\n        external\n        view\n        returns (\n            uint256 size,\n            bytes32 root,\n            bytes32[] memory partials\n        );\n\n    /**\n     * @notice creates a send txn from L2 to L1\n     * @param position = (level << 192) + leaf = (0 << 192) + leaf = leaf\n     */\n    event L2ToL1Tx(\n        address caller,\n        address indexed destination,\n        uint256 indexed hash,\n        uint256 indexed position,\n        uint256 arbBlockNum,\n        uint256 ethBlockNum,\n        uint256 timestamp,\n        uint256 callvalue,\n        bytes data\n    );\n\n    /// @dev DEPRECATED in favour of the new L2ToL1Tx event above after the nitro upgrade\n    event L2ToL1Transaction(\n        address caller,\n        address indexed destination,\n        uint256 indexed uniqueId,\n        uint256 indexed batchNumber,\n        uint256 indexInBatch,\n        uint256 arbBlockNum,\n        uint256 ethBlockNum,\n        uint256 timestamp,\n        uint256 callvalue,\n        bytes data\n    );\n\n    /**\n     * @notice logs a merkle branch for proof synthesis\n     * @param reserved an index meant only to align the 4th index with L2ToL1Transaction's 4th event\n     * @param hash the merkle hash\n     * @param position = (level << 192) + leaf\n     */\n    event SendMerkleUpdate(\n        uint256 indexed reserved,\n        bytes32 indexed hash,\n        uint256 indexed position\n    );\n\n    error InvalidBlockNumber(uint256 requested, uint256 current);\n}\n"},"@chainlink/contracts-ccip/src/v0.8/ccip/applications/CCIPReceiver.sol":{"content":"// SPDX-License-Identifier: MIT\npragma solidity ^0.8.4;\n\nimport {IAny2EVMMessageReceiver} from \"../interfaces/IAny2EVMMessageReceiver.sol\";\n\nimport {Client} from \"../libraries/Client.sol\";\n\nimport {IERC165} from \"../../vendor/openzeppelin-solidity/v5.0.2/contracts/utils/introspection/IERC165.sol\";\n\n/// @title CCIPReceiver - Base contract for CCIP applications that can receive messages.\nabstract contract CCIPReceiver is IAny2EVMMessageReceiver, IERC165 {\n  address internal immutable i_ccipRouter;\n\n  constructor(address router) {\n    if (router == address(0)) revert InvalidRouter(address(0));\n    i_ccipRouter = router;\n  }\n\n  /// @notice IERC165 supports an interfaceId\n  /// @param interfaceId The interfaceId to check\n  /// @return true if the interfaceId is supported\n  /// @dev Should indicate whether the contract implements IAny2EVMMessageReceiver\n  /// e.g. return interfaceId == type(IAny2EVMMessageReceiver).interfaceId || interfaceId == type(IERC165).interfaceId\n  /// This allows CCIP to check if ccipReceive is available before calling it.\n  /// If this returns false or reverts, only tokens are transferred to the receiver.\n  /// If this returns true, tokens are transferred and ccipReceive is called atomically.\n  /// Additionally, if the receiver address does not have code associated with\n  /// it at the time of execution (EXTCODESIZE returns 0), only tokens will be transferred.\n  function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n    return interfaceId == type(IAny2EVMMessageReceiver).interfaceId || interfaceId == type(IERC165).interfaceId;\n  }\n\n  /// @inheritdoc IAny2EVMMessageReceiver\n  function ccipReceive(Client.Any2EVMMessage calldata message) external virtual override onlyRouter {\n    _ccipReceive(message);\n  }\n\n  /// @notice Override this function in your implementation.\n  /// @param message Any2EVMMessage\n  function _ccipReceive(Client.Any2EVMMessage memory message) internal virtual;\n\n  /////////////////////////////////////////////////////////////////////\n  // Plumbing\n  /////////////////////////////////////////////////////////////////////\n\n  /// @notice Return the current router\n  /// @return CCIP router address\n  function getRouter() public view virtual returns (address) {\n    return address(i_ccipRouter);\n  }\n\n  error InvalidRouter(address router);\n\n  /// @dev only calls from the set router are accepted.\n  modifier onlyRouter() {\n    if (msg.sender != getRouter()) revert InvalidRouter(msg.sender);\n    _;\n  }\n}\n"},"@chainlink/contracts-ccip/src/v0.8/ccip/interfaces/IAny2EVMMessageReceiver.sol":{"content":"// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport {Client} from \"../libraries/Client.sol\";\n\n/// @notice Application contracts that intend to receive messages from\n/// the router should implement this interface.\ninterface IAny2EVMMessageReceiver {\n  /// @notice Called by the Router to deliver a message.\n  /// If this reverts, any token transfers also revert. The message\n  /// will move to a FAILED state and become available for manual execution.\n  /// @param message CCIP Message\n  /// @dev Note ensure you check the msg.sender is the OffRampRouter\n  function ccipReceive(Client.Any2EVMMessage calldata message) external;\n}\n"},"@chainlink/contracts-ccip/src/v0.8/ccip/interfaces/IRouterClient.sol":{"content":"// SPDX-License-Identifier: MIT\npragma solidity ^0.8.4;\n\nimport {Client} from \"../libraries/Client.sol\";\n\ninterface IRouterClient {\n  error UnsupportedDestinationChain(uint64 destChainSelector);\n  error InsufficientFeeTokenAmount();\n  error InvalidMsgValue();\n\n  /// @notice Checks if the given chain ID is supported for sending/receiving.\n  /// @param destChainSelector The chain to check.\n  /// @return supported is true if it is supported, false if not.\n  function isChainSupported(uint64 destChainSelector) external view returns (bool supported);\n\n  /// @param destinationChainSelector The destination chainSelector\n  /// @param message The cross-chain CCIP message including data and/or tokens\n  /// @return fee returns execution fee for the message\n  /// delivery to destination chain, denominated in the feeToken specified in the message.\n  /// @dev Reverts with appropriate reason upon invalid message.\n  function getFee(\n    uint64 destinationChainSelector,\n    Client.EVM2AnyMessage memory message\n  ) external view returns (uint256 fee);\n\n  /// @notice Request a message to be sent to the destination chain\n  /// @param destinationChainSelector The destination chain ID\n  /// @param message The cross-chain CCIP message including data and/or tokens\n  /// @return messageId The message ID\n  /// @dev Note if msg.value is larger than the required fee (from getFee) we accept\n  /// the overpayment with no refund.\n  /// @dev Reverts with appropriate reason upon invalid message.\n  function ccipSend(\n    uint64 destinationChainSelector,\n    Client.EVM2AnyMessage calldata message\n  ) external payable returns (bytes32);\n}\n"},"@chainlink/contracts-ccip/src/v0.8/ccip/libraries/Client.sol":{"content":"// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\n// End consumer library.\nlibrary Client {\n  /// @dev RMN depends on this struct, if changing, please notify the RMN maintainers.\n  struct EVMTokenAmount {\n    address token; // token address on the local chain.\n    uint256 amount; // Amount of tokens.\n  }\n\n  struct Any2EVMMessage {\n    bytes32 messageId; // MessageId corresponding to ccipSend on source.\n    uint64 sourceChainSelector; // Source chain selector.\n    bytes sender; // abi.decode(sender) if coming from an EVM chain.\n    bytes data; // payload sent in original message.\n    EVMTokenAmount[] destTokenAmounts; // Tokens and their amounts in their destination chain representation.\n  }\n\n  // If extraArgs is empty bytes, the default is 200k gas limit.\n  struct EVM2AnyMessage {\n    bytes receiver; // abi.encode(receiver address) for dest EVM chains\n    bytes data; // Data payload\n    EVMTokenAmount[] tokenAmounts; // Token transfers\n    address feeToken; // Address of feeToken. address(0) means you will send msg.value.\n    bytes extraArgs; // Populate this with _argsToBytes(EVMExtraArgsV2)\n  }\n\n  // bytes4(keccak256(\"CCIP EVMExtraArgsV1\"));\n  bytes4 public constant EVM_EXTRA_ARGS_V1_TAG = 0x97a657c9;\n\n  struct EVMExtraArgsV1 {\n    uint256 gasLimit;\n  }\n\n  function _argsToBytes(EVMExtraArgsV1 memory extraArgs) internal pure returns (bytes memory bts) {\n    return abi.encodeWithSelector(EVM_EXTRA_ARGS_V1_TAG, extraArgs);\n  }\n\n  // bytes4(keccak256(\"CCIP EVMExtraArgsV2\"));\n  bytes4 public constant EVM_EXTRA_ARGS_V2_TAG = 0x181dcf10;\n\n  /// @param gasLimit: gas limit for the callback on the destination chain.\n  /// @param allowOutOfOrderExecution: if true, it indicates that the message can be executed in any order relative to other messages from the same sender.\n  /// This value's default varies by chain. On some chains, a particular value is enforced, meaning if the expected value\n  /// is not set, the message request will revert.\n  struct EVMExtraArgsV2 {\n    uint256 gasLimit;\n    bool allowOutOfOrderExecution;\n  }\n\n  function _argsToBytes(EVMExtraArgsV2 memory extraArgs) internal pure returns (bytes memory bts) {\n    return abi.encodeWithSelector(EVM_EXTRA_ARGS_V2_TAG, extraArgs);\n  }\n}\n"},"@chainlink/contracts-ccip/src/v0.8/vendor/openzeppelin-solidity/v5.0.2/contracts/utils/introspection/IERC165.sol":{"content":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.0.0) (utils/introspection/IERC165.sol)\n\npragma solidity ^0.8.20;\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-upgradeable/access/Ownable2StepUpgradeable.sol":{"content":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.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() public virtual {\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.9.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. Can only be called by the current owner.\n     *\n     * NOTE: Renouncing ownership will leave the contract without an owner,\n     * thereby disabling any functionality that is only available to the owner.\n     */\n    function renounceOwnership() public virtual onlyOwner {\n        _transferOwnership(address(0));\n    }\n\n    /**\n     * @dev Transfers ownership of the contract to a new account (`newOwner`).\n     * Can only be called by the current owner.\n     */\n    function transferOwnership(address newOwner) public virtual onlyOwner {\n        require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n        _transferOwnership(newOwner);\n    }\n\n    /**\n     * @dev Transfers ownership of the contract to a new account (`newOwner`).\n     * Internal function without access restriction.\n     */\n    function _transferOwnership(address newOwner) internal virtual {\n        address oldOwner = _owner;\n        _owner = newOwner;\n        emit OwnershipTransferred(oldOwner, newOwner);\n    }\n\n    /**\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/interfaces/IERC1271Upgradeable.sol":{"content":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (interfaces/IERC1271.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC1271 standard signature validation method for\n * contracts as defined in https://eips.ethereum.org/EIPS/eip-1271[ERC-1271].\n *\n * _Available since v4.1._\n */\ninterface IERC1271Upgradeable {\n    /**\n     * @dev Should return whether the signature provided is valid for the provided data\n     * @param hash      Hash of the data to be signed\n     * @param signature Signature byte array associated with _data\n     */\n    function isValidSignature(bytes32 hash, bytes memory signature) external view returns (bytes4 magicValue);\n}\n"},"@openzeppelin/contracts-upgradeable/interfaces/IERC165Upgradeable.sol":{"content":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (interfaces/IERC165.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../utils/introspection/IERC165Upgradeable.sol\";\n"},"@openzeppelin/contracts-upgradeable/interfaces/IERC4906Upgradeable.sol":{"content":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (interfaces/IERC4906.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC165Upgradeable.sol\";\nimport \"./IERC721Upgradeable.sol\";\n\n/// @title EIP-721 Metadata Update Extension\ninterface IERC4906Upgradeable is IERC165Upgradeable, IERC721Upgradeable {\n    /// @dev This event emits when the metadata of a token is changed.\n    /// So that the third-party platforms such as NFT market could\n    /// timely update the images and related attributes of the NFT.\n    event MetadataUpdate(uint256 _tokenId);\n\n    /// @dev This event emits when the metadata of a range of tokens is changed.\n    /// So that the third-party platforms such as NFT market could\n    /// timely update the images and related attributes of the NFTs.\n    event BatchMetadataUpdate(uint256 _fromTokenId, uint256 _toTokenId);\n}\n"},"@openzeppelin/contracts-upgradeable/interfaces/IERC721Upgradeable.sol":{"content":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (interfaces/IERC721.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../token/ERC721/IERC721Upgradeable.sol\";\n"},"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol":{"content":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (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 * ```solidity\n * contract MyToken is ERC20Upgradeable {\n *     function initialize() initializer public {\n *         __ERC20_init(\"MyToken\", \"MTK\");\n *     }\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/token/ERC20/ERC20Upgradeable.sol":{"content":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/ERC20.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC20Upgradeable.sol\";\nimport \"./extensions/IERC20MetadataUpgradeable.sol\";\nimport \"../../utils/ContextUpgradeable.sol\";\nimport \"../../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Implementation of the {IERC20} interface.\n *\n * This implementation is agnostic to the way tokens are created. This means\n * that a supply mechanism has to be added in a derived contract using {_mint}.\n * For a generic mechanism see {ERC20PresetMinterPauser}.\n *\n * TIP: For a detailed writeup see our guide\n * https://forum.openzeppelin.com/t/how-to-implement-erc20-supply-mechanisms/226[How\n * to implement supply mechanisms].\n *\n * The default value of {decimals} is 18. To change this, you should override\n * this function so it returns a different value.\n *\n * We have followed general OpenZeppelin Contracts guidelines: functions revert\n * instead returning `false` on failure. This behavior is nonetheless\n * conventional and does not conflict with the expectations of ERC20\n * applications.\n *\n * Additionally, an {Approval} event is emitted on calls to {transferFrom}.\n * This allows applications to reconstruct the allowance for all accounts just\n * by listening to said events. Other implementations of the EIP may not emit\n * these events, as it isn't required by the specification.\n *\n * Finally, the non-standard {decreaseAllowance} and {increaseAllowance}\n * functions have been added to mitigate the well-known issues around setting\n * allowances. See {IERC20-approve}.\n */\ncontract ERC20Upgradeable is Initializable, ContextUpgradeable, IERC20Upgradeable, IERC20MetadataUpgradeable {\n    mapping(address => uint256) private _balances;\n\n    mapping(address => mapping(address => uint256)) private _allowances;\n\n    uint256 private _totalSupply;\n\n    string private _name;\n    string private _symbol;\n\n    /**\n     * @dev Sets the values for {name} and {symbol}.\n     *\n     * All two of these values are immutable: they can only be set once during\n     * construction.\n     */\n    function __ERC20_init(string memory name_, string memory symbol_) internal onlyInitializing {\n        __ERC20_init_unchained(name_, symbol_);\n    }\n\n    function __ERC20_init_unchained(string memory name_, string memory symbol_) internal onlyInitializing {\n        _name = name_;\n        _symbol = symbol_;\n    }\n\n    /**\n     * @dev Returns the name of the token.\n     */\n    function name() public view virtual override returns (string memory) {\n        return _name;\n    }\n\n    /**\n     * @dev Returns the symbol of the token, usually a shorter version of the\n     * name.\n     */\n    function symbol() public view virtual override returns (string memory) {\n        return _symbol;\n    }\n\n    /**\n     * @dev Returns the number of decimals used to get its user representation.\n     * For example, if `decimals` equals `2`, a balance of `505` tokens should\n     * be displayed to a user as `5.05` (`505 / 10 ** 2`).\n     *\n     * Tokens usually opt for a value of 18, imitating the relationship between\n     * Ether and Wei. This is the default value returned by this function, unless\n     * it's overridden.\n     *\n     * NOTE: This information is only used for _display_ purposes: it in\n     * no way affects any of the arithmetic of the contract, including\n     * {IERC20-balanceOf} and {IERC20-transfer}.\n     */\n    function decimals() public view virtual override returns (uint8) {\n        return 18;\n    }\n\n    /**\n     * @dev See {IERC20-totalSupply}.\n     */\n    function totalSupply() public view virtual override returns (uint256) {\n        return _totalSupply;\n    }\n\n    /**\n     * @dev See {IERC20-balanceOf}.\n     */\n    function balanceOf(address account) public view virtual override returns (uint256) {\n        return _balances[account];\n    }\n\n    /**\n     * @dev See {IERC20-transfer}.\n     *\n     * Requirements:\n     *\n     * - `to` cannot be the zero address.\n     * - the caller must have a balance of at least `amount`.\n     */\n    function transfer(address to, uint256 amount) public virtual override returns (bool) {\n        address owner = _msgSender();\n        _transfer(owner, to, amount);\n        return true;\n    }\n\n    /**\n     * @dev See {IERC20-allowance}.\n     */\n    function allowance(address owner, address spender) public view virtual override returns (uint256) {\n        return _allowances[owner][spender];\n    }\n\n    /**\n     * @dev See {IERC20-approve}.\n     *\n     * NOTE: If `amount` is the maximum `uint256`, the allowance is not updated on\n     * `transferFrom`. This is semantically equivalent to an infinite approval.\n     *\n     * Requirements:\n     *\n     * - `spender` cannot be the zero address.\n     */\n    function approve(address spender, uint256 amount) public virtual override returns (bool) {\n        address owner = _msgSender();\n        _approve(owner, spender, amount);\n        return true;\n    }\n\n    /**\n     * @dev See {IERC20-transferFrom}.\n     *\n     * Emits an {Approval} event indicating the updated allowance. This is not\n     * required by the EIP. See the note at the beginning of {ERC20}.\n     *\n     * NOTE: Does not update the allowance if the current allowance\n     * is the maximum `uint256`.\n     *\n     * Requirements:\n     *\n     * - `from` and `to` cannot be the zero address.\n     * - `from` must have a balance of at least `amount`.\n     * - the caller must have allowance for ``from``'s tokens of at least\n     * `amount`.\n     */\n    function transferFrom(address from, address to, uint256 amount) public virtual override returns (bool) {\n        address spender = _msgSender();\n        _spendAllowance(from, spender, amount);\n        _transfer(from, to, amount);\n        return true;\n    }\n\n    /**\n     * @dev Atomically increases the allowance granted to `spender` by the caller.\n     *\n     * This is an alternative to {approve} that can be used as a mitigation for\n     * problems described in {IERC20-approve}.\n     *\n     * Emits an {Approval} event indicating the updated allowance.\n     *\n     * Requirements:\n     *\n     * - `spender` cannot be the zero address.\n     */\n    function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {\n        address owner = _msgSender();\n        _approve(owner, spender, allowance(owner, spender) + addedValue);\n        return true;\n    }\n\n    /**\n     * @dev Atomically decreases the allowance granted to `spender` by the caller.\n     *\n     * This is an alternative to {approve} that can be used as a mitigation for\n     * problems described in {IERC20-approve}.\n     *\n     * Emits an {Approval} event indicating the updated allowance.\n     *\n     * Requirements:\n     *\n     * - `spender` cannot be the zero address.\n     * - `spender` must have allowance for the caller of at least\n     * `subtractedValue`.\n     */\n    function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) {\n        address owner = _msgSender();\n        uint256 currentAllowance = allowance(owner, spender);\n        require(currentAllowance >= subtractedValue, \"ERC20: decreased allowance below zero\");\n        unchecked {\n            _approve(owner, spender, currentAllowance - subtractedValue);\n        }\n\n        return true;\n    }\n\n    /**\n     * @dev Moves `amount` of tokens from `from` to `to`.\n     *\n     * This internal function is equivalent to {transfer}, and can be used to\n     * e.g. implement automatic token fees, slashing mechanisms, etc.\n     *\n     * Emits a {Transfer} event.\n     *\n     * Requirements:\n     *\n     * - `from` cannot be the zero address.\n     * - `to` cannot be the zero address.\n     * - `from` must have a balance of at least `amount`.\n     */\n    function _transfer(address from, address to, uint256 amount) internal virtual {\n        require(from != address(0), \"ERC20: transfer from the zero address\");\n        require(to != address(0), \"ERC20: transfer to the zero address\");\n\n        _beforeTokenTransfer(from, to, amount);\n\n        uint256 fromBalance = _balances[from];\n        require(fromBalance >= amount, \"ERC20: transfer amount exceeds balance\");\n        unchecked {\n            _balances[from] = fromBalance - amount;\n            // Overflow not possible: the sum of all balances is capped by totalSupply, and the sum is preserved by\n            // decrementing then incrementing.\n            _balances[to] += amount;\n        }\n\n        emit Transfer(from, to, amount);\n\n        _afterTokenTransfer(from, to, amount);\n    }\n\n    /** @dev Creates `amount` tokens and assigns them to `account`, increasing\n     * the total supply.\n     *\n     * Emits a {Transfer} event with `from` set to the zero address.\n     *\n     * Requirements:\n     *\n     * - `account` cannot be the zero address.\n     */\n    function _mint(address account, uint256 amount) internal virtual {\n        require(account != address(0), \"ERC20: mint to the zero address\");\n\n        _beforeTokenTransfer(address(0), account, amount);\n\n        _totalSupply += amount;\n        unchecked {\n            // Overflow not possible: balance + amount is at most totalSupply + amount, which is checked above.\n            _balances[account] += amount;\n        }\n        emit Transfer(address(0), account, amount);\n\n        _afterTokenTransfer(address(0), account, amount);\n    }\n\n    /**\n     * @dev Destroys `amount` tokens from `account`, reducing the\n     * total supply.\n     *\n     * Emits a {Transfer} event with `to` set to the zero address.\n     *\n     * Requirements:\n     *\n     * - `account` cannot be the zero address.\n     * - `account` must have at least `amount` tokens.\n     */\n    function _burn(address account, uint256 amount) internal virtual {\n        require(account != address(0), \"ERC20: burn from the zero address\");\n\n        _beforeTokenTransfer(account, address(0), amount);\n\n        uint256 accountBalance = _balances[account];\n        require(accountBalance >= amount, \"ERC20: burn amount exceeds balance\");\n        unchecked {\n            _balances[account] = accountBalance - amount;\n            // Overflow not possible: amount <= accountBalance <= totalSupply.\n            _totalSupply -= amount;\n        }\n\n        emit Transfer(account, address(0), amount);\n\n        _afterTokenTransfer(account, address(0), amount);\n    }\n\n    /**\n     * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens.\n     *\n     * This internal function is equivalent to `approve`, and can be used to\n     * e.g. set automatic allowances for certain subsystems, etc.\n     *\n     * Emits an {Approval} event.\n     *\n     * Requirements:\n     *\n     * - `owner` cannot be the zero address.\n     * - `spender` cannot be the zero address.\n     */\n    function _approve(address owner, address spender, uint256 amount) internal virtual {\n        require(owner != address(0), \"ERC20: approve from the zero address\");\n        require(spender != address(0), \"ERC20: approve to the zero address\");\n\n        _allowances[owner][spender] = amount;\n        emit Approval(owner, spender, amount);\n    }\n\n    /**\n     * @dev Updates `owner` s allowance for `spender` based on spent `amount`.\n     *\n     * Does not update the allowance amount in case of infinite allowance.\n     * Revert if not enough allowance is available.\n     *\n     * Might emit an {Approval} event.\n     */\n    function _spendAllowance(address owner, address spender, uint256 amount) internal virtual {\n        uint256 currentAllowance = allowance(owner, spender);\n        if (currentAllowance != type(uint256).max) {\n            require(currentAllowance >= amount, \"ERC20: insufficient allowance\");\n            unchecked {\n                _approve(owner, spender, currentAllowance - amount);\n            }\n        }\n    }\n\n    /**\n     * @dev Hook that is called before any transfer of tokens. This includes\n     * minting and burning.\n     *\n     * Calling conditions:\n     *\n     * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n     * will be transferred to `to`.\n     * - when `from` is zero, `amount` tokens will be minted for `to`.\n     * - when `to` is zero, `amount` of ``from``'s tokens will be burned.\n     * - `from` and `to` are never both zero.\n     *\n     * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n     */\n    function _beforeTokenTransfer(address from, address to, uint256 amount) internal virtual {}\n\n    /**\n     * @dev Hook that is called after any transfer of tokens. This includes\n     * minting and burning.\n     *\n     * Calling conditions:\n     *\n     * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n     * has been transferred to `to`.\n     * - when `from` is zero, `amount` tokens have been minted for `to`.\n     * - when `to` is zero, `amount` of ``from``'s tokens have been burned.\n     * - `from` and `to` are never both zero.\n     *\n     * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n     */\n    function _afterTokenTransfer(address from, address to, uint256 amount) internal virtual {}\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[45] private __gap;\n}\n"},"@openzeppelin/contracts-upgradeable/token/ERC20/extensions/IERC20MetadataUpgradeable.sol":{"content":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/IERC20Metadata.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC20Upgradeable.sol\";\n\n/**\n * @dev Interface for the optional metadata functions from the ERC20 standard.\n *\n * _Available since v4.1._\n */\ninterface IERC20MetadataUpgradeable is IERC20Upgradeable {\n    /**\n     * @dev Returns the name of the token.\n     */\n    function name() external view returns (string memory);\n\n    /**\n     * @dev Returns the symbol of the token.\n     */\n    function symbol() external view returns (string memory);\n\n    /**\n     * @dev Returns the decimals places of the token.\n     */\n    function decimals() external view returns (uint8);\n}\n"},"@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol":{"content":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/IERC20.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC20 standard as defined in the EIP.\n */\ninterface IERC20Upgradeable {\n    /**\n     * @dev Emitted when `value` tokens are moved from one account (`from`) to\n     * another (`to`).\n     *\n     * Note that `value` may be zero.\n     */\n    event Transfer(address indexed from, address indexed to, uint256 value);\n\n    /**\n     * @dev Emitted when the allowance of a `spender` for an `owner` is set by\n     * a call to {approve}. `value` is the new allowance.\n     */\n    event Approval(address indexed owner, address indexed spender, uint256 value);\n\n    /**\n     * @dev Returns the amount of tokens in existence.\n     */\n    function totalSupply() external view returns (uint256);\n\n    /**\n     * @dev Returns the amount of tokens owned by `account`.\n     */\n    function balanceOf(address account) external view returns (uint256);\n\n    /**\n     * @dev Moves `amount` tokens from the caller's account to `to`.\n     *\n     * Returns a boolean value indicating whether the operation succeeded.\n     *\n     * Emits a {Transfer} event.\n     */\n    function transfer(address to, uint256 amount) external returns (bool);\n\n    /**\n     * @dev Returns the remaining number of tokens that `spender` will be\n     * allowed to spend on behalf of `owner` through {transferFrom}. This is\n     * zero by default.\n     *\n     * This value changes when {approve} or {transferFrom} are called.\n     */\n    function allowance(address owner, address spender) external view returns (uint256);\n\n    /**\n     * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\n     *\n     * Returns a boolean value indicating whether the operation succeeded.\n     *\n     * IMPORTANT: Beware that changing an allowance with this method brings the risk\n     * that someone may use both the old and the new allowance by unfortunate\n     * transaction ordering. One possible solution to mitigate this race\n     * condition is to first reduce the spender's allowance to 0 and set the\n     * desired value afterwards:\n     * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\n     *\n     * Emits an {Approval} event.\n     */\n    function approve(address spender, uint256 amount) external returns (bool);\n\n    /**\n     * @dev Moves `amount` tokens from `from` to `to` using the\n     * allowance mechanism. `amount` is then deducted from the caller's\n     * allowance.\n     *\n     * Returns a boolean value indicating whether the operation succeeded.\n     *\n     * Emits a {Transfer} event.\n     */\n    function transferFrom(address from, address to, uint256 amount) external returns (bool);\n}\n"},"@openzeppelin/contracts-upgradeable/token/ERC721/ERC721Upgradeable.sol":{"content":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC721/ERC721.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC721Upgradeable.sol\";\nimport \"./IERC721ReceiverUpgradeable.sol\";\nimport \"./extensions/IERC721MetadataUpgradeable.sol\";\nimport \"../../utils/AddressUpgradeable.sol\";\nimport \"../../utils/ContextUpgradeable.sol\";\nimport \"../../utils/StringsUpgradeable.sol\";\nimport \"../../utils/introspection/ERC165Upgradeable.sol\";\nimport \"../../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Implementation of https://eips.ethereum.org/EIPS/eip-721[ERC721] Non-Fungible Token Standard, including\n * the Metadata extension, but not including the Enumerable extension, which is available separately as\n * {ERC721Enumerable}.\n */\ncontract ERC721Upgradeable is Initializable, ContextUpgradeable, ERC165Upgradeable, IERC721Upgradeable, IERC721MetadataUpgradeable {\n    using AddressUpgradeable for address;\n    using StringsUpgradeable for uint256;\n\n    // Token name\n    string private _name;\n\n    // Token symbol\n    string private _symbol;\n\n    // Mapping from token ID to owner address\n    mapping(uint256 => address) private _owners;\n\n    // Mapping owner address to token count\n    mapping(address => uint256) private _balances;\n\n    // Mapping from token ID to approved address\n    mapping(uint256 => address) private _tokenApprovals;\n\n    // Mapping from owner to operator approvals\n    mapping(address => mapping(address => bool)) private _operatorApprovals;\n\n    /**\n     * @dev Initializes the contract by setting a `name` and a `symbol` to the token collection.\n     */\n    function __ERC721_init(string memory name_, string memory symbol_) internal onlyInitializing {\n        __ERC721_init_unchained(name_, symbol_);\n    }\n\n    function __ERC721_init_unchained(string memory name_, string memory symbol_) internal onlyInitializing {\n        _name = name_;\n        _symbol = symbol_;\n    }\n\n    /**\n     * @dev See {IERC165-supportsInterface}.\n     */\n    function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165Upgradeable, IERC165Upgradeable) returns (bool) {\n        return\n            interfaceId == type(IERC721Upgradeable).interfaceId ||\n            interfaceId == type(IERC721MetadataUpgradeable).interfaceId ||\n            super.supportsInterface(interfaceId);\n    }\n\n    /**\n     * @dev See {IERC721-balanceOf}.\n     */\n    function balanceOf(address owner) public view virtual override returns (uint256) {\n        require(owner != address(0), \"ERC721: address zero is not a valid owner\");\n        return _balances[owner];\n    }\n\n    /**\n     * @dev See {IERC721-ownerOf}.\n     */\n    function ownerOf(uint256 tokenId) public view virtual override returns (address) {\n        address owner = _ownerOf(tokenId);\n        require(owner != address(0), \"ERC721: invalid token ID\");\n        return owner;\n    }\n\n    /**\n     * @dev See {IERC721Metadata-name}.\n     */\n    function name() public view virtual override returns (string memory) {\n        return _name;\n    }\n\n    /**\n     * @dev See {IERC721Metadata-symbol}.\n     */\n    function symbol() public view virtual override returns (string memory) {\n        return _symbol;\n    }\n\n    /**\n     * @dev See {IERC721Metadata-tokenURI}.\n     */\n    function tokenURI(uint256 tokenId) public view virtual override returns (string memory) {\n        _requireMinted(tokenId);\n\n        string memory baseURI = _baseURI();\n        return bytes(baseURI).length > 0 ? string(abi.encodePacked(baseURI, tokenId.toString())) : \"\";\n    }\n\n    /**\n     * @dev Base URI for computing {tokenURI}. If set, the resulting URI for each\n     * token will be the concatenation of the `baseURI` and the `tokenId`. Empty\n     * by default, can be overridden in child contracts.\n     */\n    function _baseURI() internal view virtual returns (string memory) {\n        return \"\";\n    }\n\n    /**\n     * @dev See {IERC721-approve}.\n     */\n    function approve(address to, uint256 tokenId) public virtual override {\n        address owner = ERC721Upgradeable.ownerOf(tokenId);\n        require(to != owner, \"ERC721: approval to current owner\");\n\n        require(\n            _msgSender() == owner || isApprovedForAll(owner, _msgSender()),\n            \"ERC721: approve caller is not token owner or approved for all\"\n        );\n\n        _approve(to, tokenId);\n    }\n\n    /**\n     * @dev See {IERC721-getApproved}.\n     */\n    function getApproved(uint256 tokenId) public view virtual override returns (address) {\n        _requireMinted(tokenId);\n\n        return _tokenApprovals[tokenId];\n    }\n\n    /**\n     * @dev See {IERC721-setApprovalForAll}.\n     */\n    function setApprovalForAll(address operator, bool approved) public virtual override {\n        _setApprovalForAll(_msgSender(), operator, approved);\n    }\n\n    /**\n     * @dev See {IERC721-isApprovedForAll}.\n     */\n    function isApprovedForAll(address owner, address operator) public view virtual override returns (bool) {\n        return _operatorApprovals[owner][operator];\n    }\n\n    /**\n     * @dev See {IERC721-transferFrom}.\n     */\n    function transferFrom(address from, address to, uint256 tokenId) public virtual override {\n        //solhint-disable-next-line max-line-length\n        require(_isApprovedOrOwner(_msgSender(), tokenId), \"ERC721: caller is not token owner or approved\");\n\n        _transfer(from, to, tokenId);\n    }\n\n    /**\n     * @dev See {IERC721-safeTransferFrom}.\n     */\n    function safeTransferFrom(address from, address to, uint256 tokenId) public virtual override {\n        safeTransferFrom(from, to, tokenId, \"\");\n    }\n\n    /**\n     * @dev See {IERC721-safeTransferFrom}.\n     */\n    function safeTransferFrom(address from, address to, uint256 tokenId, bytes memory data) public virtual override {\n        require(_isApprovedOrOwner(_msgSender(), tokenId), \"ERC721: caller is not token owner or approved\");\n        _safeTransfer(from, to, tokenId, data);\n    }\n\n    /**\n     * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients\n     * are aware of the ERC721 protocol to prevent tokens from being forever locked.\n     *\n     * `data` is additional data, it has no specified format and it is sent in call to `to`.\n     *\n     * This internal function is equivalent to {safeTransferFrom}, and can be used to e.g.\n     * implement alternative mechanisms to perform token transfer, such as signature-based.\n     *\n     * Requirements:\n     *\n     * - `from` cannot be the zero address.\n     * - `to` cannot be the zero address.\n     * - `tokenId` token must exist and be owned by `from`.\n     * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n     *\n     * Emits a {Transfer} event.\n     */\n    function _safeTransfer(address from, address to, uint256 tokenId, bytes memory data) internal virtual {\n        _transfer(from, to, tokenId);\n        require(_checkOnERC721Received(from, to, tokenId, data), \"ERC721: transfer to non ERC721Receiver implementer\");\n    }\n\n    /**\n     * @dev Returns the owner of the `tokenId`. Does NOT revert if token doesn't exist\n     */\n    function _ownerOf(uint256 tokenId) internal view virtual returns (address) {\n        return _owners[tokenId];\n    }\n\n    /**\n     * @dev Returns whether `tokenId` exists.\n     *\n     * Tokens can be managed by their owner or approved accounts via {approve} or {setApprovalForAll}.\n     *\n     * Tokens start existing when they are minted (`_mint`),\n     * and stop existing when they are burned (`_burn`).\n     */\n    function _exists(uint256 tokenId) internal view virtual returns (bool) {\n        return _ownerOf(tokenId) != address(0);\n    }\n\n    /**\n     * @dev Returns whether `spender` is allowed to manage `tokenId`.\n     *\n     * Requirements:\n     *\n     * - `tokenId` must exist.\n     */\n    function _isApprovedOrOwner(address spender, uint256 tokenId) internal view virtual returns (bool) {\n        address owner = ERC721Upgradeable.ownerOf(tokenId);\n        return (spender == owner || isApprovedForAll(owner, spender) || getApproved(tokenId) == spender);\n    }\n\n    /**\n     * @dev Safely mints `tokenId` and transfers it to `to`.\n     *\n     * Requirements:\n     *\n     * - `tokenId` must not exist.\n     * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n     *\n     * Emits a {Transfer} event.\n     */\n    function _safeMint(address to, uint256 tokenId) internal virtual {\n        _safeMint(to, tokenId, \"\");\n    }\n\n    /**\n     * @dev Same as {xref-ERC721-_safeMint-address-uint256-}[`_safeMint`], with an additional `data` parameter which is\n     * forwarded in {IERC721Receiver-onERC721Received} to contract recipients.\n     */\n    function _safeMint(address to, uint256 tokenId, bytes memory data) internal virtual {\n        _mint(to, tokenId);\n        require(\n            _checkOnERC721Received(address(0), to, tokenId, data),\n            \"ERC721: transfer to non ERC721Receiver implementer\"\n        );\n    }\n\n    /**\n     * @dev Mints `tokenId` and transfers it to `to`.\n     *\n     * WARNING: Usage of this method is discouraged, use {_safeMint} whenever possible\n     *\n     * Requirements:\n     *\n     * - `tokenId` must not exist.\n     * - `to` cannot be the zero address.\n     *\n     * Emits a {Transfer} event.\n     */\n    function _mint(address to, uint256 tokenId) internal virtual {\n        require(to != address(0), \"ERC721: mint to the zero address\");\n        require(!_exists(tokenId), \"ERC721: token already minted\");\n\n        _beforeTokenTransfer(address(0), to, tokenId, 1);\n\n        // Check that tokenId was not minted by `_beforeTokenTransfer` hook\n        require(!_exists(tokenId), \"ERC721: token already minted\");\n\n        unchecked {\n            // Will not overflow unless all 2**256 token ids are minted to the same owner.\n            // Given that tokens are minted one by one, it is impossible in practice that\n            // this ever happens. Might change if we allow batch minting.\n            // The ERC fails to describe this case.\n            _balances[to] += 1;\n        }\n\n        _owners[tokenId] = to;\n\n        emit Transfer(address(0), to, tokenId);\n\n        _afterTokenTransfer(address(0), to, tokenId, 1);\n    }\n\n    /**\n     * @dev Destroys `tokenId`.\n     * The approval is cleared when the token is burned.\n     * This is an internal function that does not check if the sender is authorized to operate on the token.\n     *\n     * Requirements:\n     *\n     * - `tokenId` must exist.\n     *\n     * Emits a {Transfer} event.\n     */\n    function _burn(uint256 tokenId) internal virtual {\n        address owner = ERC721Upgradeable.ownerOf(tokenId);\n\n        _beforeTokenTransfer(owner, address(0), tokenId, 1);\n\n        // Update ownership in case tokenId was transferred by `_beforeTokenTransfer` hook\n        owner = ERC721Upgradeable.ownerOf(tokenId);\n\n        // Clear approvals\n        delete _tokenApprovals[tokenId];\n\n        unchecked {\n            // Cannot overflow, as that would require more tokens to be burned/transferred\n            // out than the owner initially received through minting and transferring in.\n            _balances[owner] -= 1;\n        }\n        delete _owners[tokenId];\n\n        emit Transfer(owner, address(0), tokenId);\n\n        _afterTokenTransfer(owner, address(0), tokenId, 1);\n    }\n\n    /**\n     * @dev Transfers `tokenId` from `from` to `to`.\n     *  As opposed to {transferFrom}, this imposes no restrictions on msg.sender.\n     *\n     * Requirements:\n     *\n     * - `to` cannot be the zero address.\n     * - `tokenId` token must be owned by `from`.\n     *\n     * Emits a {Transfer} event.\n     */\n    function _transfer(address from, address to, uint256 tokenId) internal virtual {\n        require(ERC721Upgradeable.ownerOf(tokenId) == from, \"ERC721: transfer from incorrect owner\");\n        require(to != address(0), \"ERC721: transfer to the zero address\");\n\n        _beforeTokenTransfer(from, to, tokenId, 1);\n\n        // Check that tokenId was not transferred by `_beforeTokenTransfer` hook\n        require(ERC721Upgradeable.ownerOf(tokenId) == from, \"ERC721: transfer from incorrect owner\");\n\n        // Clear approvals from the previous owner\n        delete _tokenApprovals[tokenId];\n\n        unchecked {\n            // `_balances[from]` cannot overflow for the same reason as described in `_burn`:\n            // `from`'s balance is the number of token held, which is at least one before the current\n            // transfer.\n            // `_balances[to]` could overflow in the conditions described in `_mint`. That would require\n            // all 2**256 token ids to be minted, which in practice is impossible.\n            _balances[from] -= 1;\n            _balances[to] += 1;\n        }\n        _owners[tokenId] = to;\n\n        emit Transfer(from, to, tokenId);\n\n        _afterTokenTransfer(from, to, tokenId, 1);\n    }\n\n    /**\n     * @dev Approve `to` to operate on `tokenId`\n     *\n     * Emits an {Approval} event.\n     */\n    function _approve(address to, uint256 tokenId) internal virtual {\n        _tokenApprovals[tokenId] = to;\n        emit Approval(ERC721Upgradeable.ownerOf(tokenId), to, tokenId);\n    }\n\n    /**\n     * @dev Approve `operator` to operate on all of `owner` tokens\n     *\n     * Emits an {ApprovalForAll} event.\n     */\n    function _setApprovalForAll(address owner, address operator, bool approved) internal virtual {\n        require(owner != operator, \"ERC721: approve to caller\");\n        _operatorApprovals[owner][operator] = approved;\n        emit ApprovalForAll(owner, operator, approved);\n    }\n\n    /**\n     * @dev Reverts if the `tokenId` has not been minted yet.\n     */\n    function _requireMinted(uint256 tokenId) internal view virtual {\n        require(_exists(tokenId), \"ERC721: invalid token ID\");\n    }\n\n    /**\n     * @dev Internal function to invoke {IERC721Receiver-onERC721Received} on a target address.\n     * The call is not executed if the target address is not a contract.\n     *\n     * @param from address representing the previous owner of the given token ID\n     * @param to target address that will receive the tokens\n     * @param tokenId uint256 ID of the token to be transferred\n     * @param data bytes optional data to send along with the call\n     * @return bool whether the call correctly returned the expected magic value\n     */\n    function _checkOnERC721Received(\n        address from,\n        address to,\n        uint256 tokenId,\n        bytes memory data\n    ) private returns (bool) {\n        if (to.isContract()) {\n            try IERC721ReceiverUpgradeable(to).onERC721Received(_msgSender(), from, tokenId, data) returns (bytes4 retval) {\n                return retval == IERC721ReceiverUpgradeable.onERC721Received.selector;\n            } catch (bytes memory reason) {\n                if (reason.length == 0) {\n                    revert(\"ERC721: transfer to non ERC721Receiver implementer\");\n                } else {\n                    /// @solidity memory-safe-assembly\n                    assembly {\n                        revert(add(32, reason), mload(reason))\n                    }\n                }\n            }\n        } else {\n            return true;\n        }\n    }\n\n    /**\n     * @dev Hook that is called before any token transfer. This includes minting and burning. If {ERC721Consecutive} is\n     * used, the hook may be called as part of a consecutive (batch) mint, as indicated by `batchSize` greater than 1.\n     *\n     * Calling conditions:\n     *\n     * - When `from` and `to` are both non-zero, ``from``'s tokens will be transferred to `to`.\n     * - When `from` is zero, the tokens will be minted for `to`.\n     * - When `to` is zero, ``from``'s tokens will be burned.\n     * - `from` and `to` are never both zero.\n     * - `batchSize` is non-zero.\n     *\n     * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n     */\n    function _beforeTokenTransfer(address from, address to, uint256 firstTokenId, uint256 batchSize) internal virtual {}\n\n    /**\n     * @dev Hook that is called after any token transfer. This includes minting and burning. If {ERC721Consecutive} is\n     * used, the hook may be called as part of a consecutive (batch) mint, as indicated by `batchSize` greater than 1.\n     *\n     * Calling conditions:\n     *\n     * - When `from` and `to` are both non-zero, ``from``'s tokens were transferred to `to`.\n     * - When `from` is zero, the tokens were minted for `to`.\n     * - When `to` is zero, ``from``'s tokens were burned.\n     * - `from` and `to` are never both zero.\n     * - `batchSize` is non-zero.\n     *\n     * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n     */\n    function _afterTokenTransfer(address from, address to, uint256 firstTokenId, uint256 batchSize) internal virtual {}\n\n    /**\n     * @dev Unsafe write access to the balances, used by extensions that \"mint\" tokens using an {ownerOf} override.\n     *\n     * WARNING: Anyone calling this MUST ensure that the balances remain consistent with the ownership. The invariant\n     * being that for any address `a` the value returned by `balanceOf(a)` must be equal to the number of tokens such\n     * that `ownerOf(tokenId)` is `a`.\n     */\n    // solhint-disable-next-line func-name-mixedcase\n    function __unsafe_increaseBalance(address account, uint256 amount) internal {\n        _balances[account] += amount;\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[44] private __gap;\n}\n"},"@openzeppelin/contracts-upgradeable/token/ERC721/extensions/ERC721EnumerableUpgradeable.sol":{"content":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.8.0) (token/ERC721/extensions/ERC721Enumerable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../ERC721Upgradeable.sol\";\nimport \"./IERC721EnumerableUpgradeable.sol\";\nimport \"../../../proxy/utils/Initializable.sol\";\n\n/**\n * @dev This implements an optional extension of {ERC721} defined in the EIP that adds\n * enumerability of all the token ids in the contract as well as all token ids owned by each\n * account.\n */\nabstract contract ERC721EnumerableUpgradeable is Initializable, ERC721Upgradeable, IERC721EnumerableUpgradeable {\n    function __ERC721Enumerable_init() internal onlyInitializing {\n    }\n\n    function __ERC721Enumerable_init_unchained() internal onlyInitializing {\n    }\n    // Mapping from owner to list of owned token IDs\n    mapping(address => mapping(uint256 => uint256)) private _ownedTokens;\n\n    // Mapping from token ID to index of the owner tokens list\n    mapping(uint256 => uint256) private _ownedTokensIndex;\n\n    // Array with all token ids, used for enumeration\n    uint256[] private _allTokens;\n\n    // Mapping from token id to position in the allTokens array\n    mapping(uint256 => uint256) private _allTokensIndex;\n\n    /**\n     * @dev See {IERC165-supportsInterface}.\n     */\n    function supportsInterface(bytes4 interfaceId) public view virtual override(IERC165Upgradeable, ERC721Upgradeable) returns (bool) {\n        return interfaceId == type(IERC721EnumerableUpgradeable).interfaceId || super.supportsInterface(interfaceId);\n    }\n\n    /**\n     * @dev See {IERC721Enumerable-tokenOfOwnerByIndex}.\n     */\n    function tokenOfOwnerByIndex(address owner, uint256 index) public view virtual override returns (uint256) {\n        require(index < ERC721Upgradeable.balanceOf(owner), \"ERC721Enumerable: owner index out of bounds\");\n        return _ownedTokens[owner][index];\n    }\n\n    /**\n     * @dev See {IERC721Enumerable-totalSupply}.\n     */\n    function totalSupply() public view virtual override returns (uint256) {\n        return _allTokens.length;\n    }\n\n    /**\n     * @dev See {IERC721Enumerable-tokenByIndex}.\n     */\n    function tokenByIndex(uint256 index) public view virtual override returns (uint256) {\n        require(index < ERC721EnumerableUpgradeable.totalSupply(), \"ERC721Enumerable: global index out of bounds\");\n        return _allTokens[index];\n    }\n\n    /**\n     * @dev See {ERC721-_beforeTokenTransfer}.\n     */\n    function _beforeTokenTransfer(\n        address from,\n        address to,\n        uint256 firstTokenId,\n        uint256 batchSize\n    ) internal virtual override {\n        super._beforeTokenTransfer(from, to, firstTokenId, batchSize);\n\n        if (batchSize > 1) {\n            // Will only trigger during construction. Batch transferring (minting) is not available afterwards.\n            revert(\"ERC721Enumerable: consecutive transfers not supported\");\n        }\n\n        uint256 tokenId = firstTokenId;\n\n        if (from == address(0)) {\n            _addTokenToAllTokensEnumeration(tokenId);\n        } else if (from != to) {\n            _removeTokenFromOwnerEnumeration(from, tokenId);\n        }\n        if (to == address(0)) {\n            _removeTokenFromAllTokensEnumeration(tokenId);\n        } else if (to != from) {\n            _addTokenToOwnerEnumeration(to, tokenId);\n        }\n    }\n\n    /**\n     * @dev Private function to add a token to this extension's ownership-tracking data structures.\n     * @param to address representing the new owner of the given token ID\n     * @param tokenId uint256 ID of the token to be added to the tokens list of the given address\n     */\n    function _addTokenToOwnerEnumeration(address to, uint256 tokenId) private {\n        uint256 length = ERC721Upgradeable.balanceOf(to);\n        _ownedTokens[to][length] = tokenId;\n        _ownedTokensIndex[tokenId] = length;\n    }\n\n    /**\n     * @dev Private function to add a token to this extension's token tracking data structures.\n     * @param tokenId uint256 ID of the token to be added to the tokens list\n     */\n    function _addTokenToAllTokensEnumeration(uint256 tokenId) private {\n        _allTokensIndex[tokenId] = _allTokens.length;\n        _allTokens.push(tokenId);\n    }\n\n    /**\n     * @dev Private function to remove a token from this extension's ownership-tracking data structures. Note that\n     * while the token is not assigned a new owner, the `_ownedTokensIndex` mapping is _not_ updated: this allows for\n     * gas optimizations e.g. when performing a transfer operation (avoiding double writes).\n     * This has O(1) time complexity, but alters the order of the _ownedTokens array.\n     * @param from address representing the previous owner of the given token ID\n     * @param tokenId uint256 ID of the token to be removed from the tokens list of the given address\n     */\n    function _removeTokenFromOwnerEnumeration(address from, uint256 tokenId) private {\n        // To prevent a gap in from's tokens array, we store the last token in the index of the token to delete, and\n        // then delete the last slot (swap and pop).\n\n        uint256 lastTokenIndex = ERC721Upgradeable.balanceOf(from) - 1;\n        uint256 tokenIndex = _ownedTokensIndex[tokenId];\n\n        // When the token to delete is the last token, the swap operation is unnecessary\n        if (tokenIndex != lastTokenIndex) {\n            uint256 lastTokenId = _ownedTokens[from][lastTokenIndex];\n\n            _ownedTokens[from][tokenIndex] = lastTokenId; // Move the last token to the slot of the to-delete token\n            _ownedTokensIndex[lastTokenId] = tokenIndex; // Update the moved token's index\n        }\n\n        // This also deletes the contents at the last position of the array\n        delete _ownedTokensIndex[tokenId];\n        delete _ownedTokens[from][lastTokenIndex];\n    }\n\n    /**\n     * @dev Private function to remove a token from this extension's token tracking data structures.\n     * This has O(1) time complexity, but alters the order of the _allTokens array.\n     * @param tokenId uint256 ID of the token to be removed from the tokens list\n     */\n    function _removeTokenFromAllTokensEnumeration(uint256 tokenId) private {\n        // To prevent a gap in the tokens array, we store the last token in the index of the token to delete, and\n        // then delete the last slot (swap and pop).\n\n        uint256 lastTokenIndex = _allTokens.length - 1;\n        uint256 tokenIndex = _allTokensIndex[tokenId];\n\n        // When the token to delete is the last token, the swap operation is unnecessary. However, since this occurs so\n        // rarely (when the last minted token is burnt) that we still do the swap here to avoid the gas cost of adding\n        // an 'if' statement (like in _removeTokenFromOwnerEnumeration)\n        uint256 lastTokenId = _allTokens[lastTokenIndex];\n\n        _allTokens[tokenIndex] = lastTokenId; // Move the last token to the slot of the to-delete token\n        _allTokensIndex[lastTokenId] = tokenIndex; // Update the moved token's index\n\n        // This also deletes the contents at the last position of the array\n        delete _allTokensIndex[tokenId];\n        _allTokens.pop();\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[46] private __gap;\n}\n"},"@openzeppelin/contracts-upgradeable/token/ERC721/extensions/ERC721URIStorageUpgradeable.sol":{"content":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC721/extensions/ERC721URIStorage.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../ERC721Upgradeable.sol\";\nimport \"../../../interfaces/IERC4906Upgradeable.sol\";\nimport \"../../../proxy/utils/Initializable.sol\";\n\n/**\n * @dev ERC721 token with storage based token URI management.\n */\nabstract contract ERC721URIStorageUpgradeable is Initializable, IERC4906Upgradeable, ERC721Upgradeable {\n    function __ERC721URIStorage_init() internal onlyInitializing {\n    }\n\n    function __ERC721URIStorage_init_unchained() internal onlyInitializing {\n    }\n    using StringsUpgradeable for uint256;\n\n    // Optional mapping for token URIs\n    mapping(uint256 => string) private _tokenURIs;\n\n    /**\n     * @dev See {IERC165-supportsInterface}\n     */\n    function supportsInterface(bytes4 interfaceId) public view virtual override(ERC721Upgradeable, IERC165Upgradeable) returns (bool) {\n        return interfaceId == bytes4(0x49064906) || super.supportsInterface(interfaceId);\n    }\n\n    /**\n     * @dev See {IERC721Metadata-tokenURI}.\n     */\n    function tokenURI(uint256 tokenId) public view virtual override returns (string memory) {\n        _requireMinted(tokenId);\n\n        string memory _tokenURI = _tokenURIs[tokenId];\n        string memory base = _baseURI();\n\n        // If there is no base URI, return the token URI.\n        if (bytes(base).length == 0) {\n            return _tokenURI;\n        }\n        // If both are set, concatenate the baseURI and tokenURI (via abi.encodePacked).\n        if (bytes(_tokenURI).length > 0) {\n            return string(abi.encodePacked(base, _tokenURI));\n        }\n\n        return super.tokenURI(tokenId);\n    }\n\n    /**\n     * @dev Sets `_tokenURI` as the tokenURI of `tokenId`.\n     *\n     * Emits {MetadataUpdate}.\n     *\n     * Requirements:\n     *\n     * - `tokenId` must exist.\n     */\n    function _setTokenURI(uint256 tokenId, string memory _tokenURI) internal virtual {\n        require(_exists(tokenId), \"ERC721URIStorage: URI set of nonexistent token\");\n        _tokenURIs[tokenId] = _tokenURI;\n\n        emit MetadataUpdate(tokenId);\n    }\n\n    /**\n     * @dev See {ERC721-_burn}. This override additionally checks to see if a\n     * token-specific URI was set for the token, and if so, it deletes the token URI from\n     * the storage mapping.\n     */\n    function _burn(uint256 tokenId) internal virtual override {\n        super._burn(tokenId);\n\n        if (bytes(_tokenURIs[tokenId]).length != 0) {\n            delete _tokenURIs[tokenId];\n        }\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/token/ERC721/extensions/IERC721EnumerableUpgradeable.sol":{"content":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC721/extensions/IERC721Enumerable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC721Upgradeable.sol\";\n\n/**\n * @title ERC-721 Non-Fungible Token Standard, optional enumeration extension\n * @dev See https://eips.ethereum.org/EIPS/eip-721\n */\ninterface IERC721EnumerableUpgradeable is IERC721Upgradeable {\n    /**\n     * @dev Returns the total amount of tokens stored by the contract.\n     */\n    function totalSupply() external view returns (uint256);\n\n    /**\n     * @dev Returns a token ID owned by `owner` at a given `index` of its token list.\n     * Use along with {balanceOf} to enumerate all of ``owner``'s tokens.\n     */\n    function tokenOfOwnerByIndex(address owner, uint256 index) external view returns (uint256);\n\n    /**\n     * @dev Returns a token ID at a given `index` of all the tokens stored by the contract.\n     * Use along with {totalSupply} to enumerate all tokens.\n     */\n    function tokenByIndex(uint256 index) external view returns (uint256);\n}\n"},"@openzeppelin/contracts-upgradeable/token/ERC721/extensions/IERC721MetadataUpgradeable.sol":{"content":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC721/extensions/IERC721Metadata.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC721Upgradeable.sol\";\n\n/**\n * @title ERC-721 Non-Fungible Token Standard, optional metadata extension\n * @dev See https://eips.ethereum.org/EIPS/eip-721\n */\ninterface IERC721MetadataUpgradeable is IERC721Upgradeable {\n    /**\n     * @dev Returns the token collection name.\n     */\n    function name() external view returns (string memory);\n\n    /**\n     * @dev Returns the token collection symbol.\n     */\n    function symbol() external view returns (string memory);\n\n    /**\n     * @dev Returns the Uniform Resource Identifier (URI) for `tokenId` token.\n     */\n    function tokenURI(uint256 tokenId) external view returns (string memory);\n}\n"},"@openzeppelin/contracts-upgradeable/token/ERC721/IERC721ReceiverUpgradeable.sol":{"content":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC721/IERC721Receiver.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @title ERC721 token receiver interface\n * @dev Interface for any contract that wants to support safeTransfers\n * from ERC721 asset contracts.\n */\ninterface IERC721ReceiverUpgradeable {\n    /**\n     * @dev Whenever an {IERC721} `tokenId` token is transferred to this contract via {IERC721-safeTransferFrom}\n     * by `operator` from `from`, this function is called.\n     *\n     * It must return its Solidity selector to confirm the token transfer.\n     * If any other value is returned or the interface is not implemented by the recipient, the transfer will be reverted.\n     *\n     * The selector can be obtained in Solidity with `IERC721Receiver.onERC721Received.selector`.\n     */\n    function onERC721Received(\n        address operator,\n        address from,\n        uint256 tokenId,\n        bytes calldata data\n    ) external returns (bytes4);\n}\n"},"@openzeppelin/contracts-upgradeable/token/ERC721/IERC721Upgradeable.sol":{"content":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC721/IERC721.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../../utils/introspection/IERC165Upgradeable.sol\";\n\n/**\n * @dev Required interface of an ERC721 compliant contract.\n */\ninterface IERC721Upgradeable is IERC165Upgradeable {\n    /**\n     * @dev Emitted when `tokenId` token is transferred from `from` to `to`.\n     */\n    event Transfer(address indexed from, address indexed to, uint256 indexed tokenId);\n\n    /**\n     * @dev Emitted when `owner` enables `approved` to manage the `tokenId` token.\n     */\n    event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId);\n\n    /**\n     * @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets.\n     */\n    event ApprovalForAll(address indexed owner, address indexed operator, bool approved);\n\n    /**\n     * @dev Returns the number of tokens in ``owner``'s account.\n     */\n    function balanceOf(address owner) external view returns (uint256 balance);\n\n    /**\n     * @dev Returns the owner of the `tokenId` token.\n     *\n     * Requirements:\n     *\n     * - `tokenId` must exist.\n     */\n    function ownerOf(uint256 tokenId) external view returns (address owner);\n\n    /**\n     * @dev Safely transfers `tokenId` token from `from` to `to`.\n     *\n     * Requirements:\n     *\n     * - `from` cannot be the zero address.\n     * - `to` cannot be the zero address.\n     * - `tokenId` token must exist and be owned by `from`.\n     * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\n     * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n     *\n     * Emits a {Transfer} event.\n     */\n    function safeTransferFrom(address from, address to, uint256 tokenId, bytes calldata data) external;\n\n    /**\n     * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients\n     * are aware of the ERC721 protocol to prevent tokens from being forever locked.\n     *\n     * Requirements:\n     *\n     * - `from` cannot be the zero address.\n     * - `to` cannot be the zero address.\n     * - `tokenId` token must exist and be owned by `from`.\n     * - If the caller is not `from`, it must have been allowed to move this token by either {approve} or {setApprovalForAll}.\n     * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n     *\n     * Emits a {Transfer} event.\n     */\n    function safeTransferFrom(address from, address to, uint256 tokenId) external;\n\n    /**\n     * @dev Transfers `tokenId` token from `from` to `to`.\n     *\n     * WARNING: Note that the caller is responsible to confirm that the recipient is capable of receiving ERC721\n     * or else they may be permanently lost. Usage of {safeTransferFrom} prevents loss, though the caller must\n     * understand this adds an external call which potentially creates a reentrancy vulnerability.\n     *\n     * Requirements:\n     *\n     * - `from` cannot be the zero address.\n     * - `to` cannot be the zero address.\n     * - `tokenId` token must be owned by `from`.\n     * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\n     *\n     * Emits a {Transfer} event.\n     */\n    function transferFrom(address from, address to, uint256 tokenId) external;\n\n    /**\n     * @dev Gives permission to `to` to transfer `tokenId` token to another account.\n     * The approval is cleared when the token is transferred.\n     *\n     * Only a single account can be approved at a time, so approving the zero address clears previous approvals.\n     *\n     * Requirements:\n     *\n     * - The caller must own the token or be an approved operator.\n     * - `tokenId` must exist.\n     *\n     * Emits an {Approval} event.\n     */\n    function approve(address to, uint256 tokenId) external;\n\n    /**\n     * @dev Approve or remove `operator` as an operator for the caller.\n     * Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller.\n     *\n     * Requirements:\n     *\n     * - The `operator` cannot be the caller.\n     *\n     * Emits an {ApprovalForAll} event.\n     */\n    function setApprovalForAll(address operator, bool approved) external;\n\n    /**\n     * @dev Returns the account approved for `tokenId` token.\n     *\n     * Requirements:\n     *\n     * - `tokenId` must exist.\n     */\n    function getApproved(uint256 tokenId) external view returns (address operator);\n\n    /**\n     * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`.\n     *\n     * See {setApprovalForAll}\n     */\n    function isApprovedForAll(address owner, address operator) external view returns (bool);\n}\n"},"@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol":{"content":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/Address.sol)\n\npragma solidity ^0.8.1;\n\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary 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     * Furthermore, `isContract` will also return true if the target contract within\n     * the same transaction is already scheduled for destruction by `SELFDESTRUCT`,\n     * which only has an effect at the end of a transaction.\n     * ====\n     *\n     * [IMPORTANT]\n     * ====\n     * You shouldn't rely on `isContract` to protect against flash loan attacks!\n     *\n     * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n     * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n     * constructor.\n     * ====\n     */\n    function isContract(address account) internal view returns (bool) {\n        // This method relies on extcodesize/address.code.length, which returns 0\n        // for contracts in construction, since the code is only stored at the end\n        // of the constructor execution.\n\n        return account.code.length > 0;\n    }\n\n    /**\n     * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n     * `recipient`, forwarding all available gas and reverting on errors.\n     *\n     * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n     * of certain opcodes, possibly making contracts go over the 2300 gas limit\n     * imposed by `transfer`, making them unable to receive funds via\n     * `transfer`. {sendValue} removes this limitation.\n     *\n     * https://consensys.net/diligence/blog/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n     *\n     * IMPORTANT: because control is transferred to `recipient`, care must be\n     * taken to not create reentrancy vulnerabilities. Consider using\n     * {ReentrancyGuard} or the\n     * https://solidity.readthedocs.io/en/v0.8.0/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n     */\n    function sendValue(address payable recipient, uint256 amount) internal {\n        require(address(this).balance >= amount, \"Address: insufficient balance\");\n\n        (bool success, ) = recipient.call{value: amount}(\"\");\n        require(success, \"Address: unable to send value, recipient may have reverted\");\n    }\n\n    /**\n     * @dev Performs a Solidity function call using a low level `call`. A\n     * plain `call` is an unsafe replacement for a function call: use this\n     * function instead.\n     *\n     * If `target` reverts with a revert reason, it is bubbled up by this\n     * function (like regular Solidity function calls).\n     *\n     * Returns the raw returned data. To convert to the expected return value,\n     * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n     *\n     * Requirements:\n     *\n     * - `target` must be a contract.\n     * - calling `target` with `data` must not revert.\n     *\n     * _Available since v3.1._\n     */\n    function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n        return functionCallWithValue(target, data, 0, \"Address: low-level call failed\");\n    }\n\n    /**\n     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n     * `errorMessage` as a fallback revert reason when `target` reverts.\n     *\n     * _Available since v3.1._\n     */\n    function functionCall(\n        address target,\n        bytes memory data,\n        string memory errorMessage\n    ) internal returns (bytes memory) {\n        return functionCallWithValue(target, data, 0, errorMessage);\n    }\n\n    /**\n     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n     * but also transferring `value` wei to `target`.\n     *\n     * Requirements:\n     *\n     * - the calling contract must have an ETH balance of at least `value`.\n     * - the called Solidity function must be `payable`.\n     *\n     * _Available since v3.1._\n     */\n    function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {\n        return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n    }\n\n    /**\n     * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n     * with `errorMessage` as a fallback revert reason when `target` reverts.\n     *\n     * _Available since v3.1._\n     */\n    function functionCallWithValue(\n        address target,\n        bytes memory data,\n        uint256 value,\n        string memory errorMessage\n    ) internal returns (bytes memory) {\n        require(address(this).balance >= value, \"Address: insufficient balance for call\");\n        (bool success, bytes memory returndata) = target.call{value: value}(data);\n        return verifyCallResultFromTarget(target, success, returndata, errorMessage);\n    }\n\n    /**\n     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n     * but performing a static call.\n     *\n     * _Available since v3.3._\n     */\n    function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n        return functionStaticCall(target, data, \"Address: low-level static call failed\");\n    }\n\n    /**\n     * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n     * but performing a static call.\n     *\n     * _Available since v3.3._\n     */\n    function functionStaticCall(\n        address target,\n        bytes memory data,\n        string memory errorMessage\n    ) internal view returns (bytes memory) {\n        (bool success, bytes memory returndata) = target.staticcall(data);\n        return verifyCallResultFromTarget(target, success, returndata, errorMessage);\n    }\n\n    /**\n     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n     * but performing a delegate call.\n     *\n     * _Available since v3.4._\n     */\n    function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\n        return functionDelegateCall(target, data, \"Address: low-level delegate call failed\");\n    }\n\n    /**\n     * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n     * but performing a delegate call.\n     *\n     * _Available since v3.4._\n     */\n    function functionDelegateCall(\n        address target,\n        bytes memory data,\n        string memory errorMessage\n    ) internal returns (bytes memory) {\n        (bool success, bytes memory returndata) = target.delegatecall(data);\n        return verifyCallResultFromTarget(target, success, returndata, errorMessage);\n    }\n\n    /**\n     * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling\n     * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract.\n     *\n     * _Available since v4.8._\n     */\n    function verifyCallResultFromTarget(\n        address target,\n        bool success,\n        bytes memory returndata,\n        string memory errorMessage\n    ) internal view returns (bytes memory) {\n        if (success) {\n            if (returndata.length == 0) {\n                // only check isContract if the call was successful and the return data is empty\n                // otherwise we already know that it was a contract\n                require(isContract(target), \"Address: call to non-contract\");\n            }\n            return returndata;\n        } else {\n            _revert(returndata, errorMessage);\n        }\n    }\n\n    /**\n     * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the\n     * revert reason or using the provided one.\n     *\n     * _Available since v4.3._\n     */\n    function verifyCallResult(\n        bool success,\n        bytes memory returndata,\n        string memory errorMessage\n    ) internal pure returns (bytes memory) {\n        if (success) {\n            return returndata;\n        } else {\n            _revert(returndata, errorMessage);\n        }\n    }\n\n    function _revert(bytes memory returndata, string memory errorMessage) private pure {\n        // Look for revert reason and bubble it up if present\n        if (returndata.length > 0) {\n            // The easiest way to bubble the revert reason is using memory via assembly\n            /// @solidity memory-safe-assembly\n            assembly {\n                let returndata_size := mload(returndata)\n                revert(add(32, returndata), returndata_size)\n            }\n        } else {\n            revert(errorMessage);\n        }\n    }\n}\n"},"@openzeppelin/contracts-upgradeable/utils/CheckpointsUpgradeable.sol":{"content":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/Checkpoints.sol)\n// This file was procedurally generated from scripts/generate/templates/Checkpoints.js.\n\npragma solidity ^0.8.0;\n\nimport \"./math/MathUpgradeable.sol\";\nimport \"./math/SafeCastUpgradeable.sol\";\n\n/**\n * @dev This library defines the `History` struct, for checkpointing values as they change at different points in\n * time, and later looking up past values by block number. See {Votes} as an example.\n *\n * To create a history of checkpoints define a variable type `Checkpoints.History` in your contract, and store a new\n * checkpoint for the current transaction block using the {push} function.\n *\n * _Available since v4.5._\n */\nlibrary CheckpointsUpgradeable {\n    struct History {\n        Checkpoint[] _checkpoints;\n    }\n\n    struct Checkpoint {\n        uint32 _blockNumber;\n        uint224 _value;\n    }\n\n    /**\n     * @dev Returns the value at a given block number. If a checkpoint is not available at that block, the closest one\n     * before it is returned, or zero otherwise. Because the number returned corresponds to that at the end of the\n     * block, the requested block number must be in the past, excluding the current block.\n     */\n    function getAtBlock(History storage self, uint256 blockNumber) internal view returns (uint256) {\n        require(blockNumber < block.number, \"Checkpoints: block not yet mined\");\n        uint32 key = SafeCastUpgradeable.toUint32(blockNumber);\n\n        uint256 len = self._checkpoints.length;\n        uint256 pos = _upperBinaryLookup(self._checkpoints, key, 0, len);\n        return pos == 0 ? 0 : _unsafeAccess(self._checkpoints, pos - 1)._value;\n    }\n\n    /**\n     * @dev Returns the value at a given block number. If a checkpoint is not available at that block, the closest one\n     * before it is returned, or zero otherwise. Similar to {upperLookup} but optimized for the case when the searched\n     * checkpoint is probably \"recent\", defined as being among the last sqrt(N) checkpoints where N is the number of\n     * checkpoints.\n     */\n    function getAtProbablyRecentBlock(History storage self, uint256 blockNumber) internal view returns (uint256) {\n        require(blockNumber < block.number, \"Checkpoints: block not yet mined\");\n        uint32 key = SafeCastUpgradeable.toUint32(blockNumber);\n\n        uint256 len = self._checkpoints.length;\n\n        uint256 low = 0;\n        uint256 high = len;\n\n        if (len > 5) {\n            uint256 mid = len - MathUpgradeable.sqrt(len);\n            if (key < _unsafeAccess(self._checkpoints, mid)._blockNumber) {\n                high = mid;\n            } else {\n                low = mid + 1;\n            }\n        }\n\n        uint256 pos = _upperBinaryLookup(self._checkpoints, key, low, high);\n\n        return pos == 0 ? 0 : _unsafeAccess(self._checkpoints, pos - 1)._value;\n    }\n\n    /**\n     * @dev Pushes a value onto a History so that it is stored as the checkpoint for the current block.\n     *\n     * Returns previous value and new value.\n     */\n    function push(History storage self, uint256 value) internal returns (uint256, uint256) {\n        return _insert(self._checkpoints, SafeCastUpgradeable.toUint32(block.number), SafeCastUpgradeable.toUint224(value));\n    }\n\n    /**\n     * @dev Pushes a value onto a History, by updating the latest value using binary operation `op`. The new value will\n     * be set to `op(latest, delta)`.\n     *\n     * Returns previous value and new value.\n     */\n    function push(\n        History storage self,\n        function(uint256, uint256) view returns (uint256) op,\n        uint256 delta\n    ) internal returns (uint256, uint256) {\n        return push(self, op(latest(self), delta));\n    }\n\n    /**\n     * @dev Returns the value in the most recent checkpoint, or zero if there are no checkpoints.\n     */\n    function latest(History storage self) internal view returns (uint224) {\n        uint256 pos = self._checkpoints.length;\n        return pos == 0 ? 0 : _unsafeAccess(self._checkpoints, pos - 1)._value;\n    }\n\n    /**\n     * @dev Returns whether there is a checkpoint in the structure (i.e. it is not empty), and if so the key and value\n     * in the most recent checkpoint.\n     */\n    function latestCheckpoint(\n        History storage self\n    ) internal view returns (bool exists, uint32 _blockNumber, uint224 _value) {\n        uint256 pos = self._checkpoints.length;\n        if (pos == 0) {\n            return (false, 0, 0);\n        } else {\n            Checkpoint memory ckpt = _unsafeAccess(self._checkpoints, pos - 1);\n            return (true, ckpt._blockNumber, ckpt._value);\n        }\n    }\n\n    /**\n     * @dev Returns the number of checkpoint.\n     */\n    function length(History storage self) internal view returns (uint256) {\n        return self._checkpoints.length;\n    }\n\n    /**\n     * @dev Pushes a (`key`, `value`) pair into an ordered list of checkpoints, either by inserting a new checkpoint,\n     * or by updating the last one.\n     */\n    function _insert(Checkpoint[] storage self, uint32 key, uint224 value) private returns (uint224, uint224) {\n        uint256 pos = self.length;\n\n        if (pos > 0) {\n            // Copying to memory is important here.\n            Checkpoint memory last = _unsafeAccess(self, pos - 1);\n\n            // Checkpoint keys must be non-decreasing.\n            require(last._blockNumber <= key, \"Checkpoint: decreasing keys\");\n\n            // Update or push new checkpoint\n            if (last._blockNumber == key) {\n                _unsafeAccess(self, pos - 1)._value = value;\n            } else {\n                self.push(Checkpoint({_blockNumber: key, _value: value}));\n            }\n            return (last._value, value);\n        } else {\n            self.push(Checkpoint({_blockNumber: key, _value: value}));\n            return (0, value);\n        }\n    }\n\n    /**\n     * @dev Return the index of the last (most recent) checkpoint with key lower or equal than the search key, or `high` if there is none.\n     * `low` and `high` define a section where to do the search, with inclusive `low` and exclusive `high`.\n     *\n     * WARNING: `high` should not be greater than the array's length.\n     */\n    function _upperBinaryLookup(\n        Checkpoint[] storage self,\n        uint32 key,\n        uint256 low,\n        uint256 high\n    ) private view returns (uint256) {\n        while (low < high) {\n            uint256 mid = MathUpgradeable.average(low, high);\n            if (_unsafeAccess(self, mid)._blockNumber > key) {\n                high = mid;\n            } else {\n                low = mid + 1;\n            }\n        }\n        return high;\n    }\n\n    /**\n     * @dev Return the index of the first (oldest) checkpoint with key is greater or equal than the search key, or `high` if there is none.\n     * `low` and `high` define a section where to do the search, with inclusive `low` and exclusive `high`.\n     *\n     * WARNING: `high` should not be greater than the array's length.\n     */\n    function _lowerBinaryLookup(\n        Checkpoint[] storage self,\n        uint32 key,\n        uint256 low,\n        uint256 high\n    ) private view returns (uint256) {\n        while (low < high) {\n            uint256 mid = MathUpgradeable.average(low, high);\n            if (_unsafeAccess(self, mid)._blockNumber < key) {\n                low = mid + 1;\n            } else {\n                high = mid;\n            }\n        }\n        return high;\n    }\n\n    /**\n     * @dev Access an element of the array without performing bounds check. The position is assumed to be within bounds.\n     */\n    function _unsafeAccess(Checkpoint[] storage self, uint256 pos) private pure returns (Checkpoint storage result) {\n        assembly {\n            mstore(0, self.slot)\n            result.slot := add(keccak256(0, 0x20), pos)\n        }\n    }\n\n    struct Trace224 {\n        Checkpoint224[] _checkpoints;\n    }\n\n    struct Checkpoint224 {\n        uint32 _key;\n        uint224 _value;\n    }\n\n    /**\n     * @dev Pushes a (`key`, `value`) pair into a Trace224 so that it is stored as the checkpoint.\n     *\n     * Returns previous value and new value.\n     */\n    function push(Trace224 storage self, uint32 key, uint224 value) internal returns (uint224, uint224) {\n        return _insert(self._checkpoints, key, value);\n    }\n\n    /**\n     * @dev Returns the value in the first (oldest) checkpoint with key greater or equal than the search key, or zero if there is none.\n     */\n    function lowerLookup(Trace224 storage self, uint32 key) internal view returns (uint224) {\n        uint256 len = self._checkpoints.length;\n        uint256 pos = _lowerBinaryLookup(self._checkpoints, key, 0, len);\n        return pos == len ? 0 : _unsafeAccess(self._checkpoints, pos)._value;\n    }\n\n    /**\n     * @dev Returns the value in the last (most recent) checkpoint with key lower or equal than the search key, or zero if there is none.\n     */\n    function upperLookup(Trace224 storage self, uint32 key) internal view returns (uint224) {\n        uint256 len = self._checkpoints.length;\n        uint256 pos = _upperBinaryLookup(self._checkpoints, key, 0, len);\n        return pos == 0 ? 0 : _unsafeAccess(self._checkpoints, pos - 1)._value;\n    }\n\n    /**\n     * @dev Returns the value in the last (most recent) checkpoint with key lower or equal than the search key, or zero if there is none.\n     *\n     * NOTE: This is a variant of {upperLookup} that is optimised to find \"recent\" checkpoint (checkpoints with high keys).\n     */\n    function upperLookupRecent(Trace224 storage self, uint32 key) internal view returns (uint224) {\n        uint256 len = self._checkpoints.length;\n\n        uint256 low = 0;\n        uint256 high = len;\n\n        if (len > 5) {\n            uint256 mid = len - MathUpgradeable.sqrt(len);\n            if (key < _unsafeAccess(self._checkpoints, mid)._key) {\n                high = mid;\n            } else {\n                low = mid + 1;\n            }\n        }\n\n        uint256 pos = _upperBinaryLookup(self._checkpoints, key, low, high);\n\n        return pos == 0 ? 0 : _unsafeAccess(self._checkpoints, pos - 1)._value;\n    }\n\n    /**\n     * @dev Returns the value in the most recent checkpoint, or zero if there are no checkpoints.\n     */\n    function latest(Trace224 storage self) internal view returns (uint224) {\n        uint256 pos = self._checkpoints.length;\n        return pos == 0 ? 0 : _unsafeAccess(self._checkpoints, pos - 1)._value;\n    }\n\n    /**\n     * @dev Returns whether there is a checkpoint in the structure (i.e. it is not empty), and if so the key and value\n     * in the most recent checkpoint.\n     */\n    function latestCheckpoint(Trace224 storage self) internal view returns (bool exists, uint32 _key, uint224 _value) {\n        uint256 pos = self._checkpoints.length;\n        if (pos == 0) {\n            return (false, 0, 0);\n        } else {\n            Checkpoint224 memory ckpt = _unsafeAccess(self._checkpoints, pos - 1);\n            return (true, ckpt._key, ckpt._value);\n        }\n    }\n\n    /**\n     * @dev Returns the number of checkpoint.\n     */\n    function length(Trace224 storage self) internal view returns (uint256) {\n        return self._checkpoints.length;\n    }\n\n    /**\n     * @dev Pushes a (`key`, `value`) pair into an ordered list of checkpoints, either by inserting a new checkpoint,\n     * or by updating the last one.\n     */\n    function _insert(Checkpoint224[] storage self, uint32 key, uint224 value) private returns (uint224, uint224) {\n        uint256 pos = self.length;\n\n        if (pos > 0) {\n            // Copying to memory is important here.\n            Checkpoint224 memory last = _unsafeAccess(self, pos - 1);\n\n            // Checkpoint keys must be non-decreasing.\n            require(last._key <= key, \"Checkpoint: decreasing keys\");\n\n            // Update or push new checkpoint\n            if (last._key == key) {\n                _unsafeAccess(self, pos - 1)._value = value;\n            } else {\n                self.push(Checkpoint224({_key: key, _value: value}));\n            }\n            return (last._value, value);\n        } else {\n            self.push(Checkpoint224({_key: key, _value: value}));\n            return (0, value);\n        }\n    }\n\n    /**\n     * @dev Return the index of the last (most recent) checkpoint with key lower or equal than the search key, or `high` if there is none.\n     * `low` and `high` define a section where to do the search, with inclusive `low` and exclusive `high`.\n     *\n     * WARNING: `high` should not be greater than the array's length.\n     */\n    function _upperBinaryLookup(\n        Checkpoint224[] storage self,\n        uint32 key,\n        uint256 low,\n        uint256 high\n    ) private view returns (uint256) {\n        while (low < high) {\n            uint256 mid = MathUpgradeable.average(low, high);\n            if (_unsafeAccess(self, mid)._key > key) {\n                high = mid;\n            } else {\n                low = mid + 1;\n            }\n        }\n        return high;\n    }\n\n    /**\n     * @dev Return the index of the first (oldest) checkpoint with key is greater or equal than the search key, or `high` if there is none.\n     * `low` and `high` define a section where to do the search, with inclusive `low` and exclusive `high`.\n     *\n     * WARNING: `high` should not be greater than the array's length.\n     */\n    function _lowerBinaryLookup(\n        Checkpoint224[] storage self,\n        uint32 key,\n        uint256 low,\n        uint256 high\n    ) private view returns (uint256) {\n        while (low < high) {\n            uint256 mid = MathUpgradeable.average(low, high);\n            if (_unsafeAccess(self, mid)._key < key) {\n                low = mid + 1;\n            } else {\n                high = mid;\n            }\n        }\n        return high;\n    }\n\n    /**\n     * @dev Access an element of the array without performing bounds check. The position is assumed to be within bounds.\n     */\n    function _unsafeAccess(\n        Checkpoint224[] storage self,\n        uint256 pos\n    ) private pure returns (Checkpoint224 storage result) {\n        assembly {\n            mstore(0, self.slot)\n            result.slot := add(keccak256(0, 0x20), pos)\n        }\n    }\n\n    struct Trace160 {\n        Checkpoint160[] _checkpoints;\n    }\n\n    struct Checkpoint160 {\n        uint96 _key;\n        uint160 _value;\n    }\n\n    /**\n     * @dev Pushes a (`key`, `value`) pair into a Trace160 so that it is stored as the checkpoint.\n     *\n     * Returns previous value and new value.\n     */\n    function push(Trace160 storage self, uint96 key, uint160 value) internal returns (uint160, uint160) {\n        return _insert(self._checkpoints, key, value);\n    }\n\n    /**\n     * @dev Returns the value in the first (oldest) checkpoint with key greater or equal than the search key, or zero if there is none.\n     */\n    function lowerLookup(Trace160 storage self, uint96 key) internal view returns (uint160) {\n        uint256 len = self._checkpoints.length;\n        uint256 pos = _lowerBinaryLookup(self._checkpoints, key, 0, len);\n        return pos == len ? 0 : _unsafeAccess(self._checkpoints, pos)._value;\n    }\n\n    /**\n     * @dev Returns the value in the last (most recent) checkpoint with key lower or equal than the search key, or zero if there is none.\n     */\n    function upperLookup(Trace160 storage self, uint96 key) internal view returns (uint160) {\n        uint256 len = self._checkpoints.length;\n        uint256 pos = _upperBinaryLookup(self._checkpoints, key, 0, len);\n        return pos == 0 ? 0 : _unsafeAccess(self._checkpoints, pos - 1)._value;\n    }\n\n    /**\n     * @dev Returns the value in the last (most recent) checkpoint with key lower or equal than the search key, or zero if there is none.\n     *\n     * NOTE: This is a variant of {upperLookup} that is optimised to find \"recent\" checkpoint (checkpoints with high keys).\n     */\n    function upperLookupRecent(Trace160 storage self, uint96 key) internal view returns (uint160) {\n        uint256 len = self._checkpoints.length;\n\n        uint256 low = 0;\n        uint256 high = len;\n\n        if (len > 5) {\n            uint256 mid = len - MathUpgradeable.sqrt(len);\n            if (key < _unsafeAccess(self._checkpoints, mid)._key) {\n                high = mid;\n            } else {\n                low = mid + 1;\n            }\n        }\n\n        uint256 pos = _upperBinaryLookup(self._checkpoints, key, low, high);\n\n        return pos == 0 ? 0 : _unsafeAccess(self._checkpoints, pos - 1)._value;\n    }\n\n    /**\n     * @dev Returns the value in the most recent checkpoint, or zero if there are no checkpoints.\n     */\n    function latest(Trace160 storage self) internal view returns (uint160) {\n        uint256 pos = self._checkpoints.length;\n        return pos == 0 ? 0 : _unsafeAccess(self._checkpoints, pos - 1)._value;\n    }\n\n    /**\n     * @dev Returns whether there is a checkpoint in the structure (i.e. it is not empty), and if so the key and value\n     * in the most recent checkpoint.\n     */\n    function latestCheckpoint(Trace160 storage self) internal view returns (bool exists, uint96 _key, uint160 _value) {\n        uint256 pos = self._checkpoints.length;\n        if (pos == 0) {\n            return (false, 0, 0);\n        } else {\n            Checkpoint160 memory ckpt = _unsafeAccess(self._checkpoints, pos - 1);\n            return (true, ckpt._key, ckpt._value);\n        }\n    }\n\n    /**\n     * @dev Returns the number of checkpoint.\n     */\n    function length(Trace160 storage self) internal view returns (uint256) {\n        return self._checkpoints.length;\n    }\n\n    /**\n     * @dev Pushes a (`key`, `value`) pair into an ordered list of checkpoints, either by inserting a new checkpoint,\n     * or by updating the last one.\n     */\n    function _insert(Checkpoint160[] storage self, uint96 key, uint160 value) private returns (uint160, uint160) {\n        uint256 pos = self.length;\n\n        if (pos > 0) {\n            // Copying to memory is important here.\n            Checkpoint160 memory last = _unsafeAccess(self, pos - 1);\n\n            // Checkpoint keys must be non-decreasing.\n            require(last._key <= key, \"Checkpoint: decreasing keys\");\n\n            // Update or push new checkpoint\n            if (last._key == key) {\n                _unsafeAccess(self, pos - 1)._value = value;\n            } else {\n                self.push(Checkpoint160({_key: key, _value: value}));\n            }\n            return (last._value, value);\n        } else {\n            self.push(Checkpoint160({_key: key, _value: value}));\n            return (0, value);\n        }\n    }\n\n    /**\n     * @dev Return the index of the last (most recent) checkpoint with key lower or equal than the search key, or `high` if there is none.\n     * `low` and `high` define a section where to do the search, with inclusive `low` and exclusive `high`.\n     *\n     * WARNING: `high` should not be greater than the array's length.\n     */\n    function _upperBinaryLookup(\n        Checkpoint160[] storage self,\n        uint96 key,\n        uint256 low,\n        uint256 high\n    ) private view returns (uint256) {\n        while (low < high) {\n            uint256 mid = MathUpgradeable.average(low, high);\n            if (_unsafeAccess(self, mid)._key > key) {\n                high = mid;\n            } else {\n                low = mid + 1;\n            }\n        }\n        return high;\n    }\n\n    /**\n     * @dev Return the index of the first (oldest) checkpoint with key is greater or equal than the search key, or `high` if there is none.\n     * `low` and `high` define a section where to do the search, with inclusive `low` and exclusive `high`.\n     *\n     * WARNING: `high` should not be greater than the array's length.\n     */\n    function _lowerBinaryLookup(\n        Checkpoint160[] storage self,\n        uint96 key,\n        uint256 low,\n        uint256 high\n    ) private view returns (uint256) {\n        while (low < high) {\n            uint256 mid = MathUpgradeable.average(low, high);\n            if (_unsafeAccess(self, mid)._key < key) {\n                low = mid + 1;\n            } else {\n                high = mid;\n            }\n        }\n        return high;\n    }\n\n    /**\n     * @dev Access an element of the array without performing bounds check. The position is assumed to be within bounds.\n     */\n    function _unsafeAccess(\n        Checkpoint160[] storage self,\n        uint256 pos\n    ) private pure returns (Checkpoint160 storage result) {\n        assembly {\n            mstore(0, self.slot)\n            result.slot := add(keccak256(0, 0x20), pos)\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-upgradeable/utils/cryptography/ECDSAUpgradeable.sol":{"content":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/cryptography/ECDSA.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../StringsUpgradeable.sol\";\n\n/**\n * @dev Elliptic Curve Digital Signature Algorithm (ECDSA) operations.\n *\n * These functions can be used to verify that a message was signed by the holder\n * of the private keys of a given address.\n */\nlibrary ECDSAUpgradeable {\n    enum RecoverError {\n        NoError,\n        InvalidSignature,\n        InvalidSignatureLength,\n        InvalidSignatureS,\n        InvalidSignatureV // Deprecated in v4.8\n    }\n\n    function _throwError(RecoverError error) private pure {\n        if (error == RecoverError.NoError) {\n            return; // no error: do nothing\n        } else if (error == RecoverError.InvalidSignature) {\n            revert(\"ECDSA: invalid signature\");\n        } else if (error == RecoverError.InvalidSignatureLength) {\n            revert(\"ECDSA: invalid signature length\");\n        } else if (error == RecoverError.InvalidSignatureS) {\n            revert(\"ECDSA: invalid signature 's' value\");\n        }\n    }\n\n    /**\n     * @dev Returns the address that signed a hashed message (`hash`) with\n     * `signature` or error string. This address can then be used for verification purposes.\n     *\n     * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n     * this function rejects them by requiring the `s` value to be in the lower\n     * half order, and the `v` value to be either 27 or 28.\n     *\n     * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n     * verification to be secure: it is possible to craft signatures that\n     * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n     * this is by receiving a hash of the original message (which may otherwise\n     * be too long), and then calling {toEthSignedMessageHash} on it.\n     *\n     * Documentation for signature generation:\n     * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n     * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n     *\n     * _Available since v4.3._\n     */\n    function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n        if (signature.length == 65) {\n            bytes32 r;\n            bytes32 s;\n            uint8 v;\n            // ecrecover takes the signature parameters, and the only way to get them\n            // currently is to use assembly.\n            /// @solidity memory-safe-assembly\n            assembly {\n                r := mload(add(signature, 0x20))\n                s := mload(add(signature, 0x40))\n                v := byte(0, mload(add(signature, 0x60)))\n            }\n            return tryRecover(hash, v, r, s);\n        } else {\n            return (address(0), RecoverError.InvalidSignatureLength);\n        }\n    }\n\n    /**\n     * @dev Returns the address that signed a hashed message (`hash`) with\n     * `signature`. This address can then be used for verification purposes.\n     *\n     * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n     * this function rejects them by requiring the `s` value to be in the lower\n     * half order, and the `v` value to be either 27 or 28.\n     *\n     * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n     * verification to be secure: it is possible to craft signatures that\n     * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n     * this is by receiving a hash of the original message (which may otherwise\n     * be too long), and then calling {toEthSignedMessageHash} on it.\n     */\n    function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n        (address recovered, RecoverError error) = tryRecover(hash, signature);\n        _throwError(error);\n        return recovered;\n    }\n\n    /**\n     * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n     *\n     * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n     *\n     * _Available since v4.3._\n     */\n    function tryRecover(bytes32 hash, bytes32 r, bytes32 vs) internal pure returns (address, RecoverError) {\n        bytes32 s = vs & bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n        uint8 v = uint8((uint256(vs) >> 255) + 27);\n        return tryRecover(hash, v, r, s);\n    }\n\n    /**\n     * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n     *\n     * _Available since v4.2._\n     */\n    function recover(bytes32 hash, bytes32 r, bytes32 vs) internal pure returns (address) {\n        (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n        _throwError(error);\n        return recovered;\n    }\n\n    /**\n     * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n     * `r` and `s` signature fields separately.\n     *\n     * _Available since v4.3._\n     */\n    function tryRecover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) internal pure returns (address, RecoverError) {\n        // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n        // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n        // the valid range for s in (301): 0 < s < secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n        // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n        //\n        // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n        // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n        // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n        // these malleable signatures as well.\n        if (uint256(s) > 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n            return (address(0), RecoverError.InvalidSignatureS);\n        }\n\n        // If the signature is valid (and not malleable), return the signer address\n        address signer = ecrecover(hash, v, r, s);\n        if (signer == address(0)) {\n            return (address(0), RecoverError.InvalidSignature);\n        }\n\n        return (signer, RecoverError.NoError);\n    }\n\n    /**\n     * @dev Overload of {ECDSA-recover} that receives the `v`,\n     * `r` and `s` signature fields separately.\n     */\n    function recover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) internal pure returns (address) {\n        (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n        _throwError(error);\n        return recovered;\n    }\n\n    /**\n     * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n     * produces hash corresponding to the one signed with the\n     * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n     * JSON-RPC method as part of EIP-191.\n     *\n     * See {recover}.\n     */\n    function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32 message) {\n        // 32 is the length in bytes of hash,\n        // enforced by the type signature above\n        /// @solidity memory-safe-assembly\n        assembly {\n            mstore(0x00, \"\\x19Ethereum Signed Message:\\n32\")\n            mstore(0x1c, hash)\n            message := keccak256(0x00, 0x3c)\n        }\n    }\n\n    /**\n     * @dev Returns an Ethereum Signed Message, created from `s`. This\n     * produces hash corresponding to the one signed with the\n     * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n     * JSON-RPC method as part of EIP-191.\n     *\n     * See {recover}.\n     */\n    function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n        return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", StringsUpgradeable.toString(s.length), s));\n    }\n\n    /**\n     * @dev Returns an Ethereum Signed Typed Data, created from a\n     * `domainSeparator` and a `structHash`. This produces hash corresponding\n     * to the one signed with the\n     * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n     * JSON-RPC method as part of EIP-712.\n     *\n     * See {recover}.\n     */\n    function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32 data) {\n        /// @solidity memory-safe-assembly\n        assembly {\n            let ptr := mload(0x40)\n            mstore(ptr, \"\\x19\\x01\")\n            mstore(add(ptr, 0x02), domainSeparator)\n            mstore(add(ptr, 0x22), structHash)\n            data := keccak256(ptr, 0x42)\n        }\n    }\n\n    /**\n     * @dev Returns an Ethereum Signed Data with intended validator, created from a\n     * `validator` and `data` according to the version 0 of EIP-191.\n     *\n     * See {recover}.\n     */\n    function toDataWithIntendedValidatorHash(address validator, bytes memory data) internal pure returns (bytes32) {\n        return keccak256(abi.encodePacked(\"\\x19\\x00\", validator, data));\n    }\n}\n"},"@openzeppelin/contracts-upgradeable/utils/cryptography/SignatureCheckerUpgradeable.sol":{"content":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/cryptography/SignatureChecker.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./ECDSAUpgradeable.sol\";\nimport \"../../interfaces/IERC1271Upgradeable.sol\";\n\n/**\n * @dev Signature verification helper that can be used instead of `ECDSA.recover` to seamlessly support both ECDSA\n * signatures from externally owned accounts (EOAs) as well as ERC1271 signatures from smart contract wallets like\n * Argent and Gnosis Safe.\n *\n * _Available since v4.1._\n */\nlibrary SignatureCheckerUpgradeable {\n    /**\n     * @dev Checks if a signature is valid for a given signer and data hash. If the signer is a smart contract, the\n     * signature is validated against that smart contract using ERC1271, otherwise it's validated using `ECDSA.recover`.\n     *\n     * NOTE: Unlike ECDSA signatures, contract signatures are revocable, and the outcome of this function can thus\n     * change through time. It could return true at block N and false at block N+1 (or the opposite).\n     */\n    function isValidSignatureNow(address signer, bytes32 hash, bytes memory signature) internal view returns (bool) {\n        (address recovered, ECDSAUpgradeable.RecoverError error) = ECDSAUpgradeable.tryRecover(hash, signature);\n        return\n            (error == ECDSAUpgradeable.RecoverError.NoError && recovered == signer) ||\n            isValidERC1271SignatureNow(signer, hash, signature);\n    }\n\n    /**\n     * @dev Checks if a signature is valid for a given signer and data hash. The signature is validated\n     * against the signer smart contract using ERC1271.\n     *\n     * NOTE: Unlike ECDSA signatures, contract signatures are revocable, and the outcome of this function can thus\n     * change through time. It could return true at block N and false at block N+1 (or the opposite).\n     */\n    function isValidERC1271SignatureNow(\n        address signer,\n        bytes32 hash,\n        bytes memory signature\n    ) internal view returns (bool) {\n        (bool success, bytes memory result) = signer.staticcall(\n            abi.encodeWithSelector(IERC1271Upgradeable.isValidSignature.selector, hash, signature)\n        );\n        return (success &&\n            result.length >= 32 &&\n            abi.decode(result, (bytes32)) == bytes32(IERC1271Upgradeable.isValidSignature.selector));\n    }\n}\n"},"@openzeppelin/contracts-upgradeable/utils/introspection/ERC165Upgradeable.sol":{"content":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC165Upgradeable.sol\";\nimport \"../../proxy/utils/Initializable.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 ERC165Upgradeable is Initializable, IERC165Upgradeable {\n    function __ERC165_init() internal onlyInitializing {\n    }\n\n    function __ERC165_init_unchained() internal onlyInitializing {\n    }\n    /**\n     * @dev See {IERC165-supportsInterface}.\n     */\n    function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n        return interfaceId == type(IERC165Upgradeable).interfaceId;\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-upgradeable/utils/introspection/IERC165Upgradeable.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 IERC165Upgradeable {\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-upgradeable/utils/math/MathUpgradeable.sol":{"content":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/math/Math.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Standard math utilities missing in the Solidity language.\n */\nlibrary MathUpgradeable {\n    enum Rounding {\n        Down, // Toward negative infinity\n        Up, // Toward infinity\n        Zero // Toward zero\n    }\n\n    /**\n     * @dev Returns the largest of two numbers.\n     */\n    function max(uint256 a, uint256 b) internal pure returns (uint256) {\n        return a > b ? a : b;\n    }\n\n    /**\n     * @dev Returns the smallest of two numbers.\n     */\n    function min(uint256 a, uint256 b) internal pure returns (uint256) {\n        return a < b ? a : b;\n    }\n\n    /**\n     * @dev Returns the average of two numbers. The result is rounded towards\n     * zero.\n     */\n    function average(uint256 a, uint256 b) internal pure returns (uint256) {\n        // (a + b) / 2 can overflow.\n        return (a & b) + (a ^ b) / 2;\n    }\n\n    /**\n     * @dev Returns the ceiling of the division of two numbers.\n     *\n     * This differs from standard division with `/` in that it rounds up instead\n     * of rounding down.\n     */\n    function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) {\n        // (a + b - 1) / b can overflow on addition, so we distribute.\n        return a == 0 ? 0 : (a - 1) / b + 1;\n    }\n\n    /**\n     * @notice Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or denominator == 0\n     * @dev Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv)\n     * with further edits by Uniswap Labs also under MIT license.\n     */\n    function mulDiv(uint256 x, uint256 y, uint256 denominator) internal pure returns (uint256 result) {\n        unchecked {\n            // 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use\n            // use the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256\n            // variables such that product = prod1 * 2^256 + prod0.\n            uint256 prod0; // Least significant 256 bits of the product\n            uint256 prod1; // Most significant 256 bits of the product\n            assembly {\n                let mm := mulmod(x, y, not(0))\n                prod0 := mul(x, y)\n                prod1 := sub(sub(mm, prod0), lt(mm, prod0))\n            }\n\n            // Handle non-overflow cases, 256 by 256 division.\n            if (prod1 == 0) {\n                // Solidity will revert if denominator == 0, unlike the div opcode on its own.\n                // The surrounding unchecked block does not change this fact.\n                // See https://docs.soliditylang.org/en/latest/control-structures.html#checked-or-unchecked-arithmetic.\n                return prod0 / denominator;\n            }\n\n            // Make sure the result is less than 2^256. Also prevents denominator == 0.\n            require(denominator > prod1, \"Math: mulDiv overflow\");\n\n            ///////////////////////////////////////////////\n            // 512 by 256 division.\n            ///////////////////////////////////////////////\n\n            // Make division exact by subtracting the remainder from [prod1 prod0].\n            uint256 remainder;\n            assembly {\n                // Compute remainder using mulmod.\n                remainder := mulmod(x, y, denominator)\n\n                // Subtract 256 bit number from 512 bit number.\n                prod1 := sub(prod1, gt(remainder, prod0))\n                prod0 := sub(prod0, remainder)\n            }\n\n            // Factor powers of two out of denominator and compute largest power of two divisor of denominator. Always >= 1.\n            // See https://cs.stackexchange.com/q/138556/92363.\n\n            // Does not overflow because the denominator cannot be zero at this stage in the function.\n            uint256 twos = denominator & (~denominator + 1);\n            assembly {\n                // Divide denominator by twos.\n                denominator := div(denominator, twos)\n\n                // Divide [prod1 prod0] by twos.\n                prod0 := div(prod0, twos)\n\n                // Flip twos such that it is 2^256 / twos. If twos is zero, then it becomes one.\n                twos := add(div(sub(0, twos), twos), 1)\n            }\n\n            // Shift in bits from prod1 into prod0.\n            prod0 |= prod1 * twos;\n\n            // Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such\n            // that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for\n            // four bits. That is, denominator * inv = 1 mod 2^4.\n            uint256 inverse = (3 * denominator) ^ 2;\n\n            // Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also works\n            // in modular arithmetic, doubling the correct bits in each step.\n            inverse *= 2 - denominator * inverse; // inverse mod 2^8\n            inverse *= 2 - denominator * inverse; // inverse mod 2^16\n            inverse *= 2 - denominator * inverse; // inverse mod 2^32\n            inverse *= 2 - denominator * inverse; // inverse mod 2^64\n            inverse *= 2 - denominator * inverse; // inverse mod 2^128\n            inverse *= 2 - denominator * inverse; // inverse mod 2^256\n\n            // Because the division is now exact we can divide by multiplying with the modular inverse of denominator.\n            // This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is\n            // less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1\n            // is no longer required.\n            result = prod0 * inverse;\n            return result;\n        }\n    }\n\n    /**\n     * @notice Calculates x * y / denominator with full precision, following the selected rounding direction.\n     */\n    function mulDiv(uint256 x, uint256 y, uint256 denominator, Rounding rounding) internal pure returns (uint256) {\n        uint256 result = mulDiv(x, y, denominator);\n        if (rounding == Rounding.Up && mulmod(x, y, denominator) > 0) {\n            result += 1;\n        }\n        return result;\n    }\n\n    /**\n     * @dev Returns the square root of a number. If the number is not a perfect square, the value is rounded down.\n     *\n     * Inspired by Henry S. Warren, Jr.'s \"Hacker's Delight\" (Chapter 11).\n     */\n    function sqrt(uint256 a) internal pure returns (uint256) {\n        if (a == 0) {\n            return 0;\n        }\n\n        // For our first guess, we get the biggest power of 2 which is smaller than the square root of the target.\n        //\n        // We know that the \"msb\" (most significant bit) of our target number `a` is a power of 2 such that we have\n        // `msb(a) <= a < 2*msb(a)`. This value can be written `msb(a)=2**k` with `k=log2(a)`.\n        //\n        // This can be rewritten `2**log2(a) <= a < 2**(log2(a) + 1)`\n        // → `sqrt(2**k) <= sqrt(a) < sqrt(2**(k+1))`\n        // → `2**(k/2) <= sqrt(a) < 2**((k+1)/2) <= 2**(k/2 + 1)`\n        //\n        // Consequently, `2**(log2(a) / 2)` is a good first approximation of `sqrt(a)` with at least 1 correct bit.\n        uint256 result = 1 << (log2(a) >> 1);\n\n        // At this point `result` is an estimation with one bit of precision. We know the true value is a uint128,\n        // since it is the square root of a uint256. Newton's method converges quadratically (precision doubles at\n        // every iteration). We thus need at most 7 iteration to turn our partial result with one bit of precision\n        // into the expected uint128 result.\n        unchecked {\n            result = (result + a / result) >> 1;\n            result = (result + a / result) >> 1;\n            result = (result + a / result) >> 1;\n            result = (result + a / result) >> 1;\n            result = (result + a / result) >> 1;\n            result = (result + a / result) >> 1;\n            result = (result + a / result) >> 1;\n            return min(result, a / result);\n        }\n    }\n\n    /**\n     * @notice Calculates sqrt(a), following the selected rounding direction.\n     */\n    function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) {\n        unchecked {\n            uint256 result = sqrt(a);\n            return result + (rounding == Rounding.Up && result * result < a ? 1 : 0);\n        }\n    }\n\n    /**\n     * @dev Return the log in base 2, rounded down, of a positive value.\n     * Returns 0 if given 0.\n     */\n    function log2(uint256 value) internal pure returns (uint256) {\n        uint256 result = 0;\n        unchecked {\n            if (value >> 128 > 0) {\n                value >>= 128;\n                result += 128;\n            }\n            if (value >> 64 > 0) {\n                value >>= 64;\n                result += 64;\n            }\n            if (value >> 32 > 0) {\n                value >>= 32;\n                result += 32;\n            }\n            if (value >> 16 > 0) {\n                value >>= 16;\n                result += 16;\n            }\n            if (value >> 8 > 0) {\n                value >>= 8;\n                result += 8;\n            }\n            if (value >> 4 > 0) {\n                value >>= 4;\n                result += 4;\n            }\n            if (value >> 2 > 0) {\n                value >>= 2;\n                result += 2;\n            }\n            if (value >> 1 > 0) {\n                result += 1;\n            }\n        }\n        return result;\n    }\n\n    /**\n     * @dev Return the log in base 2, following the selected rounding direction, of a positive value.\n     * Returns 0 if given 0.\n     */\n    function log2(uint256 value, Rounding rounding) internal pure returns (uint256) {\n        unchecked {\n            uint256 result = log2(value);\n            return result + (rounding == Rounding.Up && 1 << result < value ? 1 : 0);\n        }\n    }\n\n    /**\n     * @dev Return the log in base 10, rounded down, of a positive value.\n     * Returns 0 if given 0.\n     */\n    function log10(uint256 value) internal pure returns (uint256) {\n        uint256 result = 0;\n        unchecked {\n            if (value >= 10 ** 64) {\n                value /= 10 ** 64;\n                result += 64;\n            }\n            if (value >= 10 ** 32) {\n                value /= 10 ** 32;\n                result += 32;\n            }\n            if (value >= 10 ** 16) {\n                value /= 10 ** 16;\n                result += 16;\n            }\n            if (value >= 10 ** 8) {\n                value /= 10 ** 8;\n                result += 8;\n            }\n            if (value >= 10 ** 4) {\n                value /= 10 ** 4;\n                result += 4;\n            }\n            if (value >= 10 ** 2) {\n                value /= 10 ** 2;\n                result += 2;\n            }\n            if (value >= 10 ** 1) {\n                result += 1;\n            }\n        }\n        return result;\n    }\n\n    /**\n     * @dev Return the log in base 10, following the selected rounding direction, of a positive value.\n     * Returns 0 if given 0.\n     */\n    function log10(uint256 value, Rounding rounding) internal pure returns (uint256) {\n        unchecked {\n            uint256 result = log10(value);\n            return result + (rounding == Rounding.Up && 10 ** result < value ? 1 : 0);\n        }\n    }\n\n    /**\n     * @dev Return the log in base 256, rounded down, of a positive value.\n     * Returns 0 if given 0.\n     *\n     * Adding one to the result gives the number of pairs of hex symbols needed to represent `value` as a hex string.\n     */\n    function log256(uint256 value) internal pure returns (uint256) {\n        uint256 result = 0;\n        unchecked {\n            if (value >> 128 > 0) {\n                value >>= 128;\n                result += 16;\n            }\n            if (value >> 64 > 0) {\n                value >>= 64;\n                result += 8;\n            }\n            if (value >> 32 > 0) {\n                value >>= 32;\n                result += 4;\n            }\n            if (value >> 16 > 0) {\n                value >>= 16;\n                result += 2;\n            }\n            if (value >> 8 > 0) {\n                result += 1;\n            }\n        }\n        return result;\n    }\n\n    /**\n     * @dev Return the log in base 256, following the selected rounding direction, of a positive value.\n     * Returns 0 if given 0.\n     */\n    function log256(uint256 value, Rounding rounding) internal pure returns (uint256) {\n        unchecked {\n            uint256 result = log256(value);\n            return result + (rounding == Rounding.Up && 1 << (result << 3) < value ? 1 : 0);\n        }\n    }\n}\n"},"@openzeppelin/contracts-upgradeable/utils/math/SafeCastUpgradeable.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 SafeCastUpgradeable {\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-upgradeable/utils/math/SignedMathUpgradeable.sol":{"content":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.8.0) (utils/math/SignedMath.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Standard signed math utilities missing in the Solidity language.\n */\nlibrary SignedMathUpgradeable {\n    /**\n     * @dev Returns the largest of two signed numbers.\n     */\n    function max(int256 a, int256 b) internal pure returns (int256) {\n        return a > b ? a : b;\n    }\n\n    /**\n     * @dev Returns the smallest of two signed numbers.\n     */\n    function min(int256 a, int256 b) internal pure returns (int256) {\n        return a < b ? a : b;\n    }\n\n    /**\n     * @dev Returns the average of two signed numbers without overflow.\n     * The result is rounded towards zero.\n     */\n    function average(int256 a, int256 b) internal pure returns (int256) {\n        // Formula from the book \"Hacker's Delight\"\n        int256 x = (a & b) + ((a ^ b) >> 1);\n        return x + (int256(uint256(x) >> 255) & (a ^ b));\n    }\n\n    /**\n     * @dev Returns the absolute unsigned value of a signed value.\n     */\n    function abs(int256 n) internal pure returns (uint256) {\n        unchecked {\n            // must be unchecked in order to support `n = type(int256).min`\n            return uint256(n >= 0 ? n : -n);\n        }\n    }\n}\n"},"@openzeppelin/contracts-upgradeable/utils/StringsUpgradeable.sol":{"content":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/Strings.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./math/MathUpgradeable.sol\";\nimport \"./math/SignedMathUpgradeable.sol\";\n\n/**\n * @dev String operations.\n */\nlibrary StringsUpgradeable {\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 = MathUpgradeable.log10(value) + 1;\n            string memory buffer = new string(length);\n            uint256 ptr;\n            /// @solidity memory-safe-assembly\n            assembly {\n                ptr := add(buffer, add(32, length))\n            }\n            while (true) {\n                ptr--;\n                /// @solidity memory-safe-assembly\n                assembly {\n                    mstore8(ptr, byte(mod(value, 10), _SYMBOLS))\n                }\n                value /= 10;\n                if (value == 0) break;\n            }\n            return buffer;\n        }\n    }\n\n    /**\n     * @dev Converts a `int256` to its ASCII `string` decimal representation.\n     */\n    function toString(int256 value) internal pure returns (string memory) {\n        return string(abi.encodePacked(value < 0 ? \"-\" : \"\", toString(SignedMathUpgradeable.abs(value))));\n    }\n\n    /**\n     * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n     */\n    function toHexString(uint256 value) internal pure returns (string memory) {\n        unchecked {\n            return toHexString(value, MathUpgradeable.log256(value) + 1);\n        }\n    }\n\n    /**\n     * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n     */\n    function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n        bytes memory buffer = new bytes(2 * length + 2);\n        buffer[0] = \"0\";\n        buffer[1] = \"x\";\n        for (uint256 i = 2 * length + 1; i > 1; --i) {\n            buffer[i] = _SYMBOLS[value & 0xf];\n            value >>= 4;\n        }\n        require(value == 0, \"Strings: hex length insufficient\");\n        return string(buffer);\n    }\n\n    /**\n     * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation.\n     */\n    function toHexString(address addr) internal pure returns (string memory) {\n        return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);\n    }\n\n    /**\n     * @dev Returns true if the two strings are equal.\n     */\n    function equal(string memory a, string memory b) internal pure returns (bool) {\n        return keccak256(bytes(a)) == keccak256(bytes(b));\n    }\n}\n"},"@openzeppelin/contracts/access/AccessControl.sol":{"content":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (access/AccessControl.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IAccessControl.sol\";\nimport \"../utils/Context.sol\";\nimport \"../utils/Strings.sol\";\nimport \"../utils/introspection/ERC165.sol\";\n\n/**\n * @dev Contract module that allows children to implement role-based access\n * control mechanisms. This is a lightweight version that doesn't allow enumerating role\n * members except through off-chain means by accessing the contract event logs. Some\n * applications may benefit from on-chain enumerability, for those cases see\n * {AccessControlEnumerable}.\n *\n * Roles are referred to by their `bytes32` identifier. These should be exposed\n * in the external API and be unique. The best way to achieve this is by\n * using `public constant` hash digests:\n *\n * ```solidity\n * bytes32 public constant MY_ROLE = keccak256(\"MY_ROLE\");\n * ```\n *\n * Roles can be used to represent a set of permissions. To restrict access to a\n * function call, use {hasRole}:\n *\n * ```solidity\n * function foo() public {\n *     require(hasRole(MY_ROLE, msg.sender));\n *     ...\n * }\n * ```\n *\n * Roles can be granted and revoked dynamically via the {grantRole} and\n * {revokeRole} functions. Each role has an associated admin role, and only\n * accounts that have a role's admin role can call {grantRole} and {revokeRole}.\n *\n * By default, the admin role for all roles is `DEFAULT_ADMIN_ROLE`, which means\n * that only accounts with this role will be able to grant or revoke other\n * roles. More complex role relationships can be created by using\n * {_setRoleAdmin}.\n *\n * WARNING: The `DEFAULT_ADMIN_ROLE` is also its own admin: it has permission to\n * grant and revoke this role. Extra precautions should be taken to secure\n * accounts that have been granted it. We recommend using {AccessControlDefaultAdminRules}\n * to enforce additional security measures for this role.\n */\nabstract contract AccessControl is Context, IAccessControl, ERC165 {\n    struct RoleData {\n        mapping(address => bool) members;\n        bytes32 adminRole;\n    }\n\n    mapping(bytes32 => RoleData) private _roles;\n\n    bytes32 public constant DEFAULT_ADMIN_ROLE = 0x00;\n\n    /**\n     * @dev Modifier that checks that an account has a specific role. Reverts\n     * with a standardized message including the required role.\n     *\n     * The format of the revert reason is given by the following regular expression:\n     *\n     *  /^AccessControl: account (0x[0-9a-f]{40}) is missing role (0x[0-9a-f]{64})$/\n     *\n     * _Available since v4.1._\n     */\n    modifier onlyRole(bytes32 role) {\n        _checkRole(role);\n        _;\n    }\n\n    /**\n     * @dev See {IERC165-supportsInterface}.\n     */\n    function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n        return interfaceId == type(IAccessControl).interfaceId || super.supportsInterface(interfaceId);\n    }\n\n    /**\n     * @dev Returns `true` if `account` has been granted `role`.\n     */\n    function hasRole(bytes32 role, address account) public view virtual override returns (bool) {\n        return _roles[role].members[account];\n    }\n\n    /**\n     * @dev Revert with a standard message if `_msgSender()` is missing `role`.\n     * Overriding this function changes the behavior of the {onlyRole} modifier.\n     *\n     * Format of the revert message is described in {_checkRole}.\n     *\n     * _Available since v4.6._\n     */\n    function _checkRole(bytes32 role) internal view virtual {\n        _checkRole(role, _msgSender());\n    }\n\n    /**\n     * @dev Revert with a standard message if `account` is missing `role`.\n     *\n     * The format of the revert reason is given by the following regular expression:\n     *\n     *  /^AccessControl: account (0x[0-9a-f]{40}) is missing role (0x[0-9a-f]{64})$/\n     */\n    function _checkRole(bytes32 role, address account) internal view virtual {\n        if (!hasRole(role, account)) {\n            revert(\n                string(\n                    abi.encodePacked(\n                        \"AccessControl: account \",\n                        Strings.toHexString(account),\n                        \" is missing role \",\n                        Strings.toHexString(uint256(role), 32)\n                    )\n                )\n            );\n        }\n    }\n\n    /**\n     * @dev Returns the admin role that controls `role`. See {grantRole} and\n     * {revokeRole}.\n     *\n     * To change a role's admin, use {_setRoleAdmin}.\n     */\n    function getRoleAdmin(bytes32 role) public view virtual override returns (bytes32) {\n        return _roles[role].adminRole;\n    }\n\n    /**\n     * @dev Grants `role` to `account`.\n     *\n     * If `account` had not been already granted `role`, emits a {RoleGranted}\n     * event.\n     *\n     * Requirements:\n     *\n     * - the caller must have ``role``'s admin role.\n     *\n     * May emit a {RoleGranted} event.\n     */\n    function grantRole(bytes32 role, address account) public virtual override onlyRole(getRoleAdmin(role)) {\n        _grantRole(role, account);\n    }\n\n    /**\n     * @dev Revokes `role` from `account`.\n     *\n     * If `account` had been granted `role`, emits a {RoleRevoked} event.\n     *\n     * Requirements:\n     *\n     * - the caller must have ``role``'s admin role.\n     *\n     * May emit a {RoleRevoked} event.\n     */\n    function revokeRole(bytes32 role, address account) public virtual override onlyRole(getRoleAdmin(role)) {\n        _revokeRole(role, account);\n    }\n\n    /**\n     * @dev Revokes `role` from the calling account.\n     *\n     * Roles are often managed via {grantRole} and {revokeRole}: this function's\n     * purpose is to provide a mechanism for accounts to lose their privileges\n     * if they are compromised (such as when a trusted device is misplaced).\n     *\n     * If the calling account had been revoked `role`, emits a {RoleRevoked}\n     * event.\n     *\n     * Requirements:\n     *\n     * - the caller must be `account`.\n     *\n     * May emit a {RoleRevoked} event.\n     */\n    function renounceRole(bytes32 role, address account) public virtual override {\n        require(account == _msgSender(), \"AccessControl: can only renounce roles for self\");\n\n        _revokeRole(role, account);\n    }\n\n    /**\n     * @dev Grants `role` to `account`.\n     *\n     * If `account` had not been already granted `role`, emits a {RoleGranted}\n     * event. Note that unlike {grantRole}, this function doesn't perform any\n     * checks on the calling account.\n     *\n     * May emit a {RoleGranted} event.\n     *\n     * [WARNING]\n     * ====\n     * This function should only be called from the constructor when setting\n     * up the initial roles for the system.\n     *\n     * Using this function in any other way is effectively circumventing the admin\n     * system imposed by {AccessControl}.\n     * ====\n     *\n     * NOTE: This function is deprecated in favor of {_grantRole}.\n     */\n    function _setupRole(bytes32 role, address account) internal virtual {\n        _grantRole(role, account);\n    }\n\n    /**\n     * @dev Sets `adminRole` as ``role``'s admin role.\n     *\n     * Emits a {RoleAdminChanged} event.\n     */\n    function _setRoleAdmin(bytes32 role, bytes32 adminRole) internal virtual {\n        bytes32 previousAdminRole = getRoleAdmin(role);\n        _roles[role].adminRole = adminRole;\n        emit RoleAdminChanged(role, previousAdminRole, adminRole);\n    }\n\n    /**\n     * @dev Grants `role` to `account`.\n     *\n     * Internal function without access restriction.\n     *\n     * May emit a {RoleGranted} event.\n     */\n    function _grantRole(bytes32 role, address account) internal virtual {\n        if (!hasRole(role, account)) {\n            _roles[role].members[account] = true;\n            emit RoleGranted(role, account, _msgSender());\n        }\n    }\n\n    /**\n     * @dev Revokes `role` from `account`.\n     *\n     * Internal function without access restriction.\n     *\n     * May emit a {RoleRevoked} event.\n     */\n    function _revokeRole(bytes32 role, address account) internal virtual {\n        if (hasRole(role, account)) {\n            _roles[role].members[account] = false;\n            emit RoleRevoked(role, account, _msgSender());\n        }\n    }\n}\n"},"@openzeppelin/contracts/access/IAccessControl.sol":{"content":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (access/IAccessControl.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev External interface of AccessControl declared to support ERC165 detection.\n */\ninterface IAccessControl {\n    /**\n     * @dev Emitted when `newAdminRole` is set as ``role``'s admin role, replacing `previousAdminRole`\n     *\n     * `DEFAULT_ADMIN_ROLE` is the starting admin for all roles, despite\n     * {RoleAdminChanged} not being emitted signaling this.\n     *\n     * _Available since v3.1._\n     */\n    event RoleAdminChanged(bytes32 indexed role, bytes32 indexed previousAdminRole, bytes32 indexed newAdminRole);\n\n    /**\n     * @dev Emitted when `account` is granted `role`.\n     *\n     * `sender` is the account that originated the contract call, an admin role\n     * bearer except when using {AccessControl-_setupRole}.\n     */\n    event RoleGranted(bytes32 indexed role, address indexed account, address indexed sender);\n\n    /**\n     * @dev Emitted when `account` is revoked `role`.\n     *\n     * `sender` is the account that originated the contract call:\n     *   - if using `revokeRole`, it is the admin role bearer\n     *   - if using `renounceRole`, it is the role bearer (i.e. `account`)\n     */\n    event RoleRevoked(bytes32 indexed role, address indexed account, address indexed sender);\n\n    /**\n     * @dev Returns `true` if `account` has been granted `role`.\n     */\n    function hasRole(bytes32 role, address account) external view returns (bool);\n\n    /**\n     * @dev Returns the admin role that controls `role`. See {grantRole} and\n     * {revokeRole}.\n     *\n     * To change a role's admin, use {AccessControl-_setRoleAdmin}.\n     */\n    function getRoleAdmin(bytes32 role) external view returns (bytes32);\n\n    /**\n     * @dev Grants `role` to `account`.\n     *\n     * If `account` had not been already granted `role`, emits a {RoleGranted}\n     * event.\n     *\n     * Requirements:\n     *\n     * - the caller must have ``role``'s admin role.\n     */\n    function grantRole(bytes32 role, address account) external;\n\n    /**\n     * @dev Revokes `role` from `account`.\n     *\n     * If `account` had been granted `role`, emits a {RoleRevoked} event.\n     *\n     * Requirements:\n     *\n     * - the caller must have ``role``'s admin role.\n     */\n    function revokeRole(bytes32 role, address account) external;\n\n    /**\n     * @dev Revokes `role` from the calling account.\n     *\n     * Roles are often managed via {grantRole} and {revokeRole}: this function's\n     * purpose is to provide a mechanism for accounts to lose their privileges\n     * if they are compromised (such as when a trusted device is misplaced).\n     *\n     * If the calling account had been granted `role`, emits a {RoleRevoked}\n     * event.\n     *\n     * Requirements:\n     *\n     * - the caller must be `account`.\n     */\n    function renounceRole(bytes32 role, address account) external;\n}\n"},"@openzeppelin/contracts/access/Ownable.sol":{"content":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (access/Ownable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../utils/Context.sol\";\n\n/**\n * @dev Contract module which provides a basic access control mechanism, where\n * there is an account (an owner) that can be granted exclusive access to\n * specific functions.\n *\n * By default, the owner account will be the one that deploys the contract. This\n * can later be changed with {transferOwnership}.\n *\n * This module is used through inheritance. It will make available the modifier\n * `onlyOwner`, which can be applied to your functions to restrict their use to\n * the owner.\n */\nabstract contract Ownable is Context {\n    address private _owner;\n\n    event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n    /**\n     * @dev Initializes the contract setting the deployer as the initial owner.\n     */\n    constructor() {\n        _transferOwnership(_msgSender());\n    }\n\n    /**\n     * @dev Throws if called by any account other than the owner.\n     */\n    modifier onlyOwner() {\n        _checkOwner();\n        _;\n    }\n\n    /**\n     * @dev Returns the address of the current owner.\n     */\n    function owner() public view virtual returns (address) {\n        return _owner;\n    }\n\n    /**\n     * @dev Throws if the sender is not the owner.\n     */\n    function _checkOwner() internal view virtual {\n        require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n    }\n\n    /**\n     * @dev Leaves the contract without owner. It will not be possible to call\n     * `onlyOwner` functions. Can only be called by the current owner.\n     *\n     * NOTE: Renouncing ownership will leave the contract without an owner,\n     * thereby disabling any functionality that is only available to the owner.\n     */\n    function renounceOwnership() public virtual onlyOwner {\n        _transferOwnership(address(0));\n    }\n\n    /**\n     * @dev Transfers ownership of the contract to a new account (`newOwner`).\n     * Can only be called by the current owner.\n     */\n    function transferOwnership(address newOwner) public virtual onlyOwner {\n        require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n        _transferOwnership(newOwner);\n    }\n\n    /**\n     * @dev Transfers ownership of the contract to a new account (`newOwner`).\n     * Internal function without access restriction.\n     */\n    function _transferOwnership(address newOwner) internal virtual {\n        address oldOwner = _owner;\n        _owner = newOwner;\n        emit OwnershipTransferred(oldOwner, newOwner);\n    }\n}\n"},"@openzeppelin/contracts/crosschain/arbitrum/CrossChainEnabledArbitrumL1.sol":{"content":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (crosschain/arbitrum/CrossChainEnabledArbitrumL1.sol)\n\npragma solidity ^0.8.4;\n\nimport \"../CrossChainEnabled.sol\";\nimport \"./LibArbitrumL1.sol\";\n\n/**\n * @dev https://arbitrum.io/[Arbitrum] specialization or the\n * {CrossChainEnabled} abstraction the L1 side (mainnet).\n *\n * This version should only be deployed on L1 to process cross-chain messages\n * originating from L2. For the other side, use {CrossChainEnabledArbitrumL2}.\n *\n * The bridge contract is provided and maintained by the arbitrum team. You can\n * find the address of this contract on the rinkeby testnet in\n * https://developer.offchainlabs.com/docs/useful_addresses[Arbitrum's developer documentation].\n *\n * _Available since v4.6._\n */\nabstract contract CrossChainEnabledArbitrumL1 is CrossChainEnabled {\n    /// @custom:oz-upgrades-unsafe-allow state-variable-immutable\n    address private immutable _bridge;\n\n    /// @custom:oz-upgrades-unsafe-allow constructor\n    constructor(address bridge) {\n        _bridge = bridge;\n    }\n\n    /**\n     * @dev see {CrossChainEnabled-_isCrossChain}\n     */\n    function _isCrossChain() internal view virtual override returns (bool) {\n        return LibArbitrumL1.isCrossChain(_bridge);\n    }\n\n    /**\n     * @dev see {CrossChainEnabled-_crossChainSender}\n     */\n    function _crossChainSender() internal view virtual override onlyCrossChain returns (address) {\n        return LibArbitrumL1.crossChainSender(_bridge);\n    }\n}\n"},"@openzeppelin/contracts/crosschain/arbitrum/LibArbitrumL1.sol":{"content":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.8.0) (crosschain/arbitrum/LibArbitrumL1.sol)\n\npragma solidity ^0.8.4;\n\nimport {IBridge as ArbitrumL1_Bridge} from \"../../vendor/arbitrum/IBridge.sol\";\nimport {IOutbox as ArbitrumL1_Outbox} from \"../../vendor/arbitrum/IOutbox.sol\";\nimport \"../errors.sol\";\n\n/**\n * @dev Primitives for cross-chain aware contracts for\n * https://arbitrum.io/[Arbitrum].\n *\n * This version should only be used on L1 to process cross-chain messages\n * originating from L2. For the other side, use {LibArbitrumL2}.\n */\nlibrary LibArbitrumL1 {\n    /**\n     * @dev Returns whether the current function call is the result of a\n     * cross-chain message relayed by the `bridge`.\n     */\n    function isCrossChain(address bridge) internal view returns (bool) {\n        return msg.sender == bridge;\n    }\n\n    /**\n     * @dev Returns the address of the sender that triggered the current\n     * cross-chain message through the `bridge`.\n     *\n     * NOTE: {isCrossChain} should be checked before trying to recover the\n     * sender, as it will revert with `NotCrossChainCall` if the current\n     * function call is not the result of a cross-chain message.\n     */\n    function crossChainSender(address bridge) internal view returns (address) {\n        if (!isCrossChain(bridge)) revert NotCrossChainCall();\n\n        address sender = ArbitrumL1_Outbox(ArbitrumL1_Bridge(bridge).activeOutbox()).l2ToL1Sender();\n        require(sender != address(0), \"LibArbitrumL1: system messages without sender\");\n\n        return sender;\n    }\n}\n"},"@openzeppelin/contracts/crosschain/CrossChainEnabled.sol":{"content":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.6.0) (crosschain/CrossChainEnabled.sol)\n\npragma solidity ^0.8.4;\n\nimport \"./errors.sol\";\n\n/**\n * @dev Provides information for building cross-chain aware contracts. This\n * abstract contract provides accessors and modifiers to control the execution\n * flow when receiving cross-chain messages.\n *\n * Actual implementations of cross-chain aware contracts, which are based on\n * this abstraction, will  have to inherit from a bridge-specific\n * specialization. Such specializations are provided under\n * `crosschain/<chain>/CrossChainEnabled<chain>.sol`.\n *\n * _Available since v4.6._\n */\nabstract contract CrossChainEnabled {\n    /**\n     * @dev Throws if the current function call is not the result of a\n     * cross-chain execution.\n     */\n    modifier onlyCrossChain() {\n        if (!_isCrossChain()) revert NotCrossChainCall();\n        _;\n    }\n\n    /**\n     * @dev Throws if the current function call is not the result of a\n     * cross-chain execution initiated by `account`.\n     */\n    modifier onlyCrossChainSender(address expected) {\n        address actual = _crossChainSender();\n        if (expected != actual) revert InvalidCrossChainSender(actual, expected);\n        _;\n    }\n\n    /**\n     * @dev Returns whether the current function call is the result of a\n     * cross-chain message.\n     */\n    function _isCrossChain() internal view virtual returns (bool);\n\n    /**\n     * @dev Returns the address of the sender of the cross-chain message that\n     * triggered the current function call.\n     *\n     * IMPORTANT: Should revert with `NotCrossChainCall` if the current function\n     * call is not the result of a cross-chain message.\n     */\n    function _crossChainSender() internal view virtual returns (address);\n}\n"},"@openzeppelin/contracts/crosschain/errors.sol":{"content":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.6.0) (crosschain/errors.sol)\n\npragma solidity ^0.8.4;\n\nerror NotCrossChainCall();\nerror InvalidCrossChainSender(address actual, address expected);\n"},"@openzeppelin/contracts/crosschain/optimism/CrossChainEnabledOptimism.sol":{"content":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (crosschain/optimism/CrossChainEnabledOptimism.sol)\n\npragma solidity ^0.8.4;\n\nimport \"../CrossChainEnabled.sol\";\nimport \"./LibOptimism.sol\";\n\n/**\n * @dev https://www.optimism.io/[Optimism] specialization or the\n * {CrossChainEnabled} abstraction.\n *\n * The messenger (`CrossDomainMessenger`) contract is provided and maintained by\n * the optimism team. You can find the address of this contract on mainnet and\n * kovan in the https://github.com/ethereum-optimism/optimism/tree/develop/packages/contracts/deployments[deployments section of Optimism monorepo].\n *\n * _Available since v4.6._\n */\nabstract contract CrossChainEnabledOptimism is CrossChainEnabled {\n    /// @custom:oz-upgrades-unsafe-allow state-variable-immutable\n    address private immutable _messenger;\n\n    /// @custom:oz-upgrades-unsafe-allow constructor\n    constructor(address messenger) {\n        _messenger = messenger;\n    }\n\n    /**\n     * @dev see {CrossChainEnabled-_isCrossChain}\n     */\n    function _isCrossChain() internal view virtual override returns (bool) {\n        return LibOptimism.isCrossChain(_messenger);\n    }\n\n    /**\n     * @dev see {CrossChainEnabled-_crossChainSender}\n     */\n    function _crossChainSender() internal view virtual override onlyCrossChain returns (address) {\n        return LibOptimism.crossChainSender(_messenger);\n    }\n}\n"},"@openzeppelin/contracts/crosschain/optimism/LibOptimism.sol":{"content":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (crosschain/optimism/LibOptimism.sol)\n\npragma solidity ^0.8.4;\n\nimport {ICrossDomainMessenger as Optimism_Bridge} from \"../../vendor/optimism/ICrossDomainMessenger.sol\";\nimport \"../errors.sol\";\n\n/**\n * @dev Primitives for cross-chain aware contracts for https://www.optimism.io/[Optimism].\n * See the https://community.optimism.io/docs/developers/bridge/messaging/#accessing-msg-sender[documentation]\n * for the functionality used here.\n */\nlibrary LibOptimism {\n    /**\n     * @dev Returns whether the current function call is the result of a\n     * cross-chain message relayed by `messenger`.\n     */\n    function isCrossChain(address messenger) internal view returns (bool) {\n        return msg.sender == messenger;\n    }\n\n    /**\n     * @dev Returns the address of the sender that triggered the current\n     * cross-chain message through `messenger`.\n     *\n     * NOTE: {isCrossChain} should be checked before trying to recover the\n     * sender, as it will revert with `NotCrossChainCall` if the current\n     * function call is not the result of a cross-chain message.\n     */\n    function crossChainSender(address messenger) internal view returns (address) {\n        if (!isCrossChain(messenger)) revert NotCrossChainCall();\n\n        return Optimism_Bridge(messenger).xDomainMessageSender();\n    }\n}\n"},"@openzeppelin/contracts/governance/TimelockController.sol":{"content":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (governance/TimelockController.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../access/AccessControl.sol\";\nimport \"../token/ERC721/IERC721Receiver.sol\";\nimport \"../token/ERC1155/IERC1155Receiver.sol\";\n\n/**\n * @dev Contract module which acts as a timelocked controller. When set as the\n * owner of an `Ownable` smart contract, it enforces a timelock on all\n * `onlyOwner` maintenance operations. This gives time for users of the\n * controlled contract to exit before a potentially dangerous maintenance\n * operation is applied.\n *\n * By default, this contract is self administered, meaning administration tasks\n * have to go through the timelock process. The proposer (resp executor) role\n * is in charge of proposing (resp executing) operations. A common use case is\n * to position this {TimelockController} as the owner of a smart contract, with\n * a multisig or a DAO as the sole proposer.\n *\n * _Available since v3.3._\n */\ncontract TimelockController is AccessControl, IERC721Receiver, IERC1155Receiver {\n    bytes32 public constant TIMELOCK_ADMIN_ROLE = keccak256(\"TIMELOCK_ADMIN_ROLE\");\n    bytes32 public constant PROPOSER_ROLE = keccak256(\"PROPOSER_ROLE\");\n    bytes32 public constant EXECUTOR_ROLE = keccak256(\"EXECUTOR_ROLE\");\n    bytes32 public constant CANCELLER_ROLE = keccak256(\"CANCELLER_ROLE\");\n    uint256 internal constant _DONE_TIMESTAMP = uint256(1);\n\n    mapping(bytes32 => uint256) private _timestamps;\n    uint256 private _minDelay;\n\n    /**\n     * @dev Emitted when a call is scheduled as part of operation `id`.\n     */\n    event CallScheduled(\n        bytes32 indexed id,\n        uint256 indexed index,\n        address target,\n        uint256 value,\n        bytes data,\n        bytes32 predecessor,\n        uint256 delay\n    );\n\n    /**\n     * @dev Emitted when a call is performed as part of operation `id`.\n     */\n    event CallExecuted(bytes32 indexed id, uint256 indexed index, address target, uint256 value, bytes data);\n\n    /**\n     * @dev Emitted when new proposal is scheduled with non-zero salt.\n     */\n    event CallSalt(bytes32 indexed id, bytes32 salt);\n\n    /**\n     * @dev Emitted when operation `id` is cancelled.\n     */\n    event Cancelled(bytes32 indexed id);\n\n    /**\n     * @dev Emitted when the minimum delay for future operations is modified.\n     */\n    event MinDelayChange(uint256 oldDuration, uint256 newDuration);\n\n    /**\n     * @dev Initializes the contract with the following parameters:\n     *\n     * - `minDelay`: initial minimum delay for operations\n     * - `proposers`: accounts to be granted proposer and canceller roles\n     * - `executors`: accounts to be granted executor role\n     * - `admin`: optional account to be granted admin role; disable with zero address\n     *\n     * IMPORTANT: The optional admin can aid with initial configuration of roles after deployment\n     * without being subject to delay, but this role should be subsequently renounced in favor of\n     * administration through timelocked proposals. Previous versions of this contract would assign\n     * this admin to the deployer automatically and should be renounced as well.\n     */\n    constructor(uint256 minDelay, address[] memory proposers, address[] memory executors, address admin) {\n        _setRoleAdmin(TIMELOCK_ADMIN_ROLE, TIMELOCK_ADMIN_ROLE);\n        _setRoleAdmin(PROPOSER_ROLE, TIMELOCK_ADMIN_ROLE);\n        _setRoleAdmin(EXECUTOR_ROLE, TIMELOCK_ADMIN_ROLE);\n        _setRoleAdmin(CANCELLER_ROLE, TIMELOCK_ADMIN_ROLE);\n\n        // self administration\n        _setupRole(TIMELOCK_ADMIN_ROLE, address(this));\n\n        // optional admin\n        if (admin != address(0)) {\n            _setupRole(TIMELOCK_ADMIN_ROLE, admin);\n        }\n\n        // register proposers and cancellers\n        for (uint256 i = 0; i < proposers.length; ++i) {\n            _setupRole(PROPOSER_ROLE, proposers[i]);\n            _setupRole(CANCELLER_ROLE, proposers[i]);\n        }\n\n        // register executors\n        for (uint256 i = 0; i < executors.length; ++i) {\n            _setupRole(EXECUTOR_ROLE, executors[i]);\n        }\n\n        _minDelay = minDelay;\n        emit MinDelayChange(0, minDelay);\n    }\n\n    /**\n     * @dev Modifier to make a function callable only by a certain role. In\n     * addition to checking the sender's role, `address(0)` 's role is also\n     * considered. Granting a role to `address(0)` is equivalent to enabling\n     * this role for everyone.\n     */\n    modifier onlyRoleOrOpenRole(bytes32 role) {\n        if (!hasRole(role, address(0))) {\n            _checkRole(role, _msgSender());\n        }\n        _;\n    }\n\n    /**\n     * @dev Contract might receive/hold ETH as part of the maintenance process.\n     */\n    receive() external payable {}\n\n    /**\n     * @dev See {IERC165-supportsInterface}.\n     */\n    function supportsInterface(bytes4 interfaceId) public view virtual override(IERC165, AccessControl) returns (bool) {\n        return interfaceId == type(IERC1155Receiver).interfaceId || super.supportsInterface(interfaceId);\n    }\n\n    /**\n     * @dev Returns whether an id correspond to a registered operation. This\n     * includes both Pending, Ready and Done operations.\n     */\n    function isOperation(bytes32 id) public view virtual returns (bool) {\n        return getTimestamp(id) > 0;\n    }\n\n    /**\n     * @dev Returns whether an operation is pending or not. Note that a \"pending\" operation may also be \"ready\".\n     */\n    function isOperationPending(bytes32 id) public view virtual returns (bool) {\n        return getTimestamp(id) > _DONE_TIMESTAMP;\n    }\n\n    /**\n     * @dev Returns whether an operation is ready for execution. Note that a \"ready\" operation is also \"pending\".\n     */\n    function isOperationReady(bytes32 id) public view virtual returns (bool) {\n        uint256 timestamp = getTimestamp(id);\n        return timestamp > _DONE_TIMESTAMP && timestamp <= block.timestamp;\n    }\n\n    /**\n     * @dev Returns whether an operation is done or not.\n     */\n    function isOperationDone(bytes32 id) public view virtual returns (bool) {\n        return getTimestamp(id) == _DONE_TIMESTAMP;\n    }\n\n    /**\n     * @dev Returns the timestamp at which an operation becomes ready (0 for\n     * unset operations, 1 for done operations).\n     */\n    function getTimestamp(bytes32 id) public view virtual returns (uint256) {\n        return _timestamps[id];\n    }\n\n    /**\n     * @dev Returns the minimum delay for an operation to become valid.\n     *\n     * This value can be changed by executing an operation that calls `updateDelay`.\n     */\n    function getMinDelay() public view virtual returns (uint256) {\n        return _minDelay;\n    }\n\n    /**\n     * @dev Returns the identifier of an operation containing a single\n     * transaction.\n     */\n    function hashOperation(\n        address target,\n        uint256 value,\n        bytes calldata data,\n        bytes32 predecessor,\n        bytes32 salt\n    ) public pure virtual returns (bytes32) {\n        return keccak256(abi.encode(target, value, data, predecessor, salt));\n    }\n\n    /**\n     * @dev Returns the identifier of an operation containing a batch of\n     * transactions.\n     */\n    function hashOperationBatch(\n        address[] calldata targets,\n        uint256[] calldata values,\n        bytes[] calldata payloads,\n        bytes32 predecessor,\n        bytes32 salt\n    ) public pure virtual returns (bytes32) {\n        return keccak256(abi.encode(targets, values, payloads, predecessor, salt));\n    }\n\n    /**\n     * @dev Schedule an operation containing a single transaction.\n     *\n     * Emits {CallSalt} if salt is nonzero, and {CallScheduled}.\n     *\n     * Requirements:\n     *\n     * - the caller must have the 'proposer' role.\n     */\n    function schedule(\n        address target,\n        uint256 value,\n        bytes calldata data,\n        bytes32 predecessor,\n        bytes32 salt,\n        uint256 delay\n    ) public virtual onlyRole(PROPOSER_ROLE) {\n        bytes32 id = hashOperation(target, value, data, predecessor, salt);\n        _schedule(id, delay);\n        emit CallScheduled(id, 0, target, value, data, predecessor, delay);\n        if (salt != bytes32(0)) {\n            emit CallSalt(id, salt);\n        }\n    }\n\n    /**\n     * @dev Schedule an operation containing a batch of transactions.\n     *\n     * Emits {CallSalt} if salt is nonzero, and one {CallScheduled} event per transaction in the batch.\n     *\n     * Requirements:\n     *\n     * - the caller must have the 'proposer' role.\n     */\n    function scheduleBatch(\n        address[] calldata targets,\n        uint256[] calldata values,\n        bytes[] calldata payloads,\n        bytes32 predecessor,\n        bytes32 salt,\n        uint256 delay\n    ) public virtual onlyRole(PROPOSER_ROLE) {\n        require(targets.length == values.length, \"TimelockController: length mismatch\");\n        require(targets.length == payloads.length, \"TimelockController: length mismatch\");\n\n        bytes32 id = hashOperationBatch(targets, values, payloads, predecessor, salt);\n        _schedule(id, delay);\n        for (uint256 i = 0; i < targets.length; ++i) {\n            emit CallScheduled(id, i, targets[i], values[i], payloads[i], predecessor, delay);\n        }\n        if (salt != bytes32(0)) {\n            emit CallSalt(id, salt);\n        }\n    }\n\n    /**\n     * @dev Schedule an operation that is to become valid after a given delay.\n     */\n    function _schedule(bytes32 id, uint256 delay) private {\n        require(!isOperation(id), \"TimelockController: operation already scheduled\");\n        require(delay >= getMinDelay(), \"TimelockController: insufficient delay\");\n        _timestamps[id] = block.timestamp + delay;\n    }\n\n    /**\n     * @dev Cancel an operation.\n     *\n     * Requirements:\n     *\n     * - the caller must have the 'canceller' role.\n     */\n    function cancel(bytes32 id) public virtual onlyRole(CANCELLER_ROLE) {\n        require(isOperationPending(id), \"TimelockController: operation cannot be cancelled\");\n        delete _timestamps[id];\n\n        emit Cancelled(id);\n    }\n\n    /**\n     * @dev Execute an (ready) operation containing a single transaction.\n     *\n     * Emits a {CallExecuted} event.\n     *\n     * Requirements:\n     *\n     * - the caller must have the 'executor' role.\n     */\n    // This function can reenter, but it doesn't pose a risk because _afterCall checks that the proposal is pending,\n    // thus any modifications to the operation during reentrancy should be caught.\n    // slither-disable-next-line reentrancy-eth\n    function execute(\n        address target,\n        uint256 value,\n        bytes calldata payload,\n        bytes32 predecessor,\n        bytes32 salt\n    ) public payable virtual onlyRoleOrOpenRole(EXECUTOR_ROLE) {\n        bytes32 id = hashOperation(target, value, payload, predecessor, salt);\n\n        _beforeCall(id, predecessor);\n        _execute(target, value, payload);\n        emit CallExecuted(id, 0, target, value, payload);\n        _afterCall(id);\n    }\n\n    /**\n     * @dev Execute an (ready) operation containing a batch of transactions.\n     *\n     * Emits one {CallExecuted} event per transaction in the batch.\n     *\n     * Requirements:\n     *\n     * - the caller must have the 'executor' role.\n     */\n    // This function can reenter, but it doesn't pose a risk because _afterCall checks that the proposal is pending,\n    // thus any modifications to the operation during reentrancy should be caught.\n    // slither-disable-next-line reentrancy-eth\n    function executeBatch(\n        address[] calldata targets,\n        uint256[] calldata values,\n        bytes[] calldata payloads,\n        bytes32 predecessor,\n        bytes32 salt\n    ) public payable virtual onlyRoleOrOpenRole(EXECUTOR_ROLE) {\n        require(targets.length == values.length, \"TimelockController: length mismatch\");\n        require(targets.length == payloads.length, \"TimelockController: length mismatch\");\n\n        bytes32 id = hashOperationBatch(targets, values, payloads, predecessor, salt);\n\n        _beforeCall(id, predecessor);\n        for (uint256 i = 0; i < targets.length; ++i) {\n            address target = targets[i];\n            uint256 value = values[i];\n            bytes calldata payload = payloads[i];\n            _execute(target, value, payload);\n            emit CallExecuted(id, i, target, value, payload);\n        }\n        _afterCall(id);\n    }\n\n    /**\n     * @dev Execute an operation's call.\n     */\n    function _execute(address target, uint256 value, bytes calldata data) internal virtual {\n        (bool success, ) = target.call{value: value}(data);\n        require(success, \"TimelockController: underlying transaction reverted\");\n    }\n\n    /**\n     * @dev Checks before execution of an operation's calls.\n     */\n    function _beforeCall(bytes32 id, bytes32 predecessor) private view {\n        require(isOperationReady(id), \"TimelockController: operation is not ready\");\n        require(predecessor == bytes32(0) || isOperationDone(predecessor), \"TimelockController: missing dependency\");\n    }\n\n    /**\n     * @dev Checks after execution of an operation's calls.\n     */\n    function _afterCall(bytes32 id) private {\n        require(isOperationReady(id), \"TimelockController: operation is not ready\");\n        _timestamps[id] = _DONE_TIMESTAMP;\n    }\n\n    /**\n     * @dev Changes the minimum timelock duration for future operations.\n     *\n     * Emits a {MinDelayChange} event.\n     *\n     * Requirements:\n     *\n     * - the caller must be the timelock itself. This can only be achieved by scheduling and later executing\n     * an operation where the timelock is the target and the data is the ABI-encoded call to this function.\n     */\n    function updateDelay(uint256 newDelay) external virtual {\n        require(msg.sender == address(this), \"TimelockController: caller must be timelock\");\n        emit MinDelayChange(_minDelay, newDelay);\n        _minDelay = newDelay;\n    }\n\n    /**\n     * @dev See {IERC721Receiver-onERC721Received}.\n     */\n    function onERC721Received(address, address, uint256, bytes memory) public virtual override returns (bytes4) {\n        return this.onERC721Received.selector;\n    }\n\n    /**\n     * @dev See {IERC1155Receiver-onERC1155Received}.\n     */\n    function onERC1155Received(\n        address,\n        address,\n        uint256,\n        uint256,\n        bytes memory\n    ) public virtual override returns (bytes4) {\n        return this.onERC1155Received.selector;\n    }\n\n    /**\n     * @dev See {IERC1155Receiver-onERC1155BatchReceived}.\n     */\n    function onERC1155BatchReceived(\n        address,\n        address,\n        uint256[] memory,\n        uint256[] memory,\n        bytes memory\n    ) public virtual override returns (bytes4) {\n        return this.onERC1155BatchReceived.selector;\n    }\n}\n"},"@openzeppelin/contracts/interfaces/draft-IERC1822.sol":{"content":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0) (interfaces/draft-IERC1822.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev ERC1822: Universal Upgradeable Proxy Standard (UUPS) documents a method for upgradeability through a simplified\n * proxy whose upgrades are fully controlled by the current implementation.\n */\ninterface IERC1822Proxiable {\n    /**\n     * @dev Returns the storage slot that the proxiable contract assumes is being used to store the implementation\n     * address.\n     *\n     * IMPORTANT: A proxy pointing at a proxiable contract should not be considered proxiable itself, because this risks\n     * bricking a proxy that upgrades to it, by delegating to itself until out of gas. Thus it is critical that this\n     * function revert if invoked through a proxy.\n     */\n    function proxiableUUID() external view returns (bytes32);\n}\n"},"@openzeppelin/contracts/interfaces/IERC1967.sol":{"content":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (interfaces/IERC1967.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev ERC-1967: Proxy Storage Slots. This interface contains the events defined in the ERC.\n *\n * _Available since v4.8.3._\n */\ninterface IERC1967 {\n    /**\n     * @dev Emitted when the implementation is upgraded.\n     */\n    event Upgraded(address indexed implementation);\n\n    /**\n     * @dev Emitted when the admin account has changed.\n     */\n    event AdminChanged(address previousAdmin, address newAdmin);\n\n    /**\n     * @dev Emitted when the beacon is changed.\n     */\n    event BeaconUpgraded(address indexed beacon);\n}\n"},"@openzeppelin/contracts/interfaces/IERC20.sol":{"content":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (interfaces/IERC20.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../token/ERC20/IERC20.sol\";\n"},"@openzeppelin/contracts/interfaces/IERC4626.sol":{"content":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (interfaces/IERC4626.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../token/ERC20/IERC20.sol\";\nimport \"../token/ERC20/extensions/IERC20Metadata.sol\";\n\n/**\n * @dev Interface of the ERC4626 \"Tokenized Vault Standard\", as defined in\n * https://eips.ethereum.org/EIPS/eip-4626[ERC-4626].\n *\n * _Available since v4.7._\n */\ninterface IERC4626 is IERC20, IERC20Metadata {\n    event Deposit(address indexed sender, address indexed owner, uint256 assets, uint256 shares);\n\n    event Withdraw(\n        address indexed sender,\n        address indexed receiver,\n        address indexed owner,\n        uint256 assets,\n        uint256 shares\n    );\n\n    /**\n     * @dev Returns the address of the underlying token used for the Vault for accounting, depositing, and withdrawing.\n     *\n     * - MUST be an ERC-20 token contract.\n     * - MUST NOT revert.\n     */\n    function asset() external view returns (address assetTokenAddress);\n\n    /**\n     * @dev Returns the total amount of the underlying asset that is “managed” by Vault.\n     *\n     * - SHOULD include any compounding that occurs from yield.\n     * - MUST be inclusive of any fees that are charged against assets in the Vault.\n     * - MUST NOT revert.\n     */\n    function totalAssets() external view returns (uint256 totalManagedAssets);\n\n    /**\n     * @dev Returns the amount of shares that the Vault would exchange for the amount of assets provided, in an ideal\n     * scenario where all the conditions are met.\n     *\n     * - MUST NOT be inclusive of any fees that are charged against assets in the Vault.\n     * - MUST NOT show any variations depending on the caller.\n     * - MUST NOT reflect slippage or other on-chain conditions, when performing the actual exchange.\n     * - MUST NOT revert.\n     *\n     * NOTE: This calculation MAY NOT reflect the “per-user” price-per-share, and instead should reflect the\n     * “average-user’s” price-per-share, meaning what the average user should expect to see when exchanging to and\n     * from.\n     */\n    function convertToShares(uint256 assets) external view returns (uint256 shares);\n\n    /**\n     * @dev Returns the amount of assets that the Vault would exchange for the amount of shares provided, in an ideal\n     * scenario where all the conditions are met.\n     *\n     * - MUST NOT be inclusive of any fees that are charged against assets in the Vault.\n     * - MUST NOT show any variations depending on the caller.\n     * - MUST NOT reflect slippage or other on-chain conditions, when performing the actual exchange.\n     * - MUST NOT revert.\n     *\n     * NOTE: This calculation MAY NOT reflect the “per-user” price-per-share, and instead should reflect the\n     * “average-user’s” price-per-share, meaning what the average user should expect to see when exchanging to and\n     * from.\n     */\n    function convertToAssets(uint256 shares) external view returns (uint256 assets);\n\n    /**\n     * @dev Returns the maximum amount of the underlying asset that can be deposited into the Vault for the receiver,\n     * through a deposit call.\n     *\n     * - MUST return a limited value if receiver is subject to some deposit limit.\n     * - MUST return 2 ** 256 - 1 if there is no limit on the maximum amount of assets that may be deposited.\n     * - MUST NOT revert.\n     */\n    function maxDeposit(address receiver) external view returns (uint256 maxAssets);\n\n    /**\n     * @dev Allows an on-chain or off-chain user to simulate the effects of their deposit at the current block, given\n     * current on-chain conditions.\n     *\n     * - MUST return as close to and no more than the exact amount of Vault shares that would be minted in a deposit\n     *   call in the same transaction. I.e. deposit should return the same or more shares as previewDeposit if called\n     *   in the same transaction.\n     * - MUST NOT account for deposit limits like those returned from maxDeposit and should always act as though the\n     *   deposit would be accepted, regardless if the user has enough tokens approved, etc.\n     * - MUST be inclusive of deposit fees. Integrators should be aware of the existence of deposit fees.\n     * - MUST NOT revert.\n     *\n     * NOTE: any unfavorable discrepancy between convertToShares and previewDeposit SHOULD be considered slippage in\n     * share price or some other type of condition, meaning the depositor will lose assets by depositing.\n     */\n    function previewDeposit(uint256 assets) external view returns (uint256 shares);\n\n    /**\n     * @dev Mints shares Vault shares to receiver by depositing exactly amount of underlying tokens.\n     *\n     * - MUST emit the Deposit event.\n     * - MAY support an additional flow in which the underlying tokens are owned by the Vault contract before the\n     *   deposit execution, and are accounted for during deposit.\n     * - MUST revert if all of assets cannot be deposited (due to deposit limit being reached, slippage, the user not\n     *   approving enough underlying tokens to the Vault contract, etc).\n     *\n     * NOTE: most implementations will require pre-approval of the Vault with the Vault’s underlying asset token.\n     */\n    function deposit(uint256 assets, address receiver) external returns (uint256 shares);\n\n    /**\n     * @dev Returns the maximum amount of the Vault shares that can be minted for the receiver, through a mint call.\n     * - MUST return a limited value if receiver is subject to some mint limit.\n     * - MUST return 2 ** 256 - 1 if there is no limit on the maximum amount of shares that may be minted.\n     * - MUST NOT revert.\n     */\n    function maxMint(address receiver) external view returns (uint256 maxShares);\n\n    /**\n     * @dev Allows an on-chain or off-chain user to simulate the effects of their mint at the current block, given\n     * current on-chain conditions.\n     *\n     * - MUST return as close to and no fewer than the exact amount of assets that would be deposited in a mint call\n     *   in the same transaction. I.e. mint should return the same or fewer assets as previewMint if called in the\n     *   same transaction.\n     * - MUST NOT account for mint limits like those returned from maxMint and should always act as though the mint\n     *   would be accepted, regardless if the user has enough tokens approved, etc.\n     * - MUST be inclusive of deposit fees. Integrators should be aware of the existence of deposit fees.\n     * - MUST NOT revert.\n     *\n     * NOTE: any unfavorable discrepancy between convertToAssets and previewMint SHOULD be considered slippage in\n     * share price or some other type of condition, meaning the depositor will lose assets by minting.\n     */\n    function previewMint(uint256 shares) external view returns (uint256 assets);\n\n    /**\n     * @dev Mints exactly shares Vault shares to receiver by depositing amount of underlying tokens.\n     *\n     * - MUST emit the Deposit event.\n     * - MAY support an additional flow in which the underlying tokens are owned by the Vault contract before the mint\n     *   execution, and are accounted for during mint.\n     * - MUST revert if all of shares cannot be minted (due to deposit limit being reached, slippage, the user not\n     *   approving enough underlying tokens to the Vault contract, etc).\n     *\n     * NOTE: most implementations will require pre-approval of the Vault with the Vault’s underlying asset token.\n     */\n    function mint(uint256 shares, address receiver) external returns (uint256 assets);\n\n    /**\n     * @dev Returns the maximum amount of the underlying asset that can be withdrawn from the owner balance in the\n     * Vault, through a withdraw call.\n     *\n     * - MUST return a limited value if owner is subject to some withdrawal limit or timelock.\n     * - MUST NOT revert.\n     */\n    function maxWithdraw(address owner) external view returns (uint256 maxAssets);\n\n    /**\n     * @dev Allows an on-chain or off-chain user to simulate the effects of their withdrawal at the current block,\n     * given current on-chain conditions.\n     *\n     * - MUST return as close to and no fewer than the exact amount of Vault shares that would be burned in a withdraw\n     *   call in the same transaction. I.e. withdraw should return the same or fewer shares as previewWithdraw if\n     *   called\n     *   in the same transaction.\n     * - MUST NOT account for withdrawal limits like those returned from maxWithdraw and should always act as though\n     *   the withdrawal would be accepted, regardless if the user has enough shares, etc.\n     * - MUST be inclusive of withdrawal fees. Integrators should be aware of the existence of withdrawal fees.\n     * - MUST NOT revert.\n     *\n     * NOTE: any unfavorable discrepancy between convertToShares and previewWithdraw SHOULD be considered slippage in\n     * share price or some other type of condition, meaning the depositor will lose assets by depositing.\n     */\n    function previewWithdraw(uint256 assets) external view returns (uint256 shares);\n\n    /**\n     * @dev Burns shares from owner and sends exactly assets of underlying tokens to receiver.\n     *\n     * - MUST emit the Withdraw event.\n     * - MAY support an additional flow in which the underlying tokens are owned by the Vault contract before the\n     *   withdraw execution, and are accounted for during withdraw.\n     * - MUST revert if all of assets cannot be withdrawn (due to withdrawal limit being reached, slippage, the owner\n     *   not having enough shares, etc).\n     *\n     * Note that some implementations will require pre-requesting to the Vault before a withdrawal may be performed.\n     * Those methods should be performed separately.\n     */\n    function withdraw(uint256 assets, address receiver, address owner) external returns (uint256 shares);\n\n    /**\n     * @dev Returns the maximum amount of Vault shares that can be redeemed from the owner balance in the Vault,\n     * through a redeem call.\n     *\n     * - MUST return a limited value if owner is subject to some withdrawal limit or timelock.\n     * - MUST return balanceOf(owner) if owner is not subject to any withdrawal limit or timelock.\n     * - MUST NOT revert.\n     */\n    function maxRedeem(address owner) external view returns (uint256 maxShares);\n\n    /**\n     * @dev Allows an on-chain or off-chain user to simulate the effects of their redeemption at the current block,\n     * given current on-chain conditions.\n     *\n     * - MUST return as close to and no more than the exact amount of assets that would be withdrawn in a redeem call\n     *   in the same transaction. I.e. redeem should return the same or more assets as previewRedeem if called in the\n     *   same transaction.\n     * - MUST NOT account for redemption limits like those returned from maxRedeem and should always act as though the\n     *   redemption would be accepted, regardless if the user has enough shares, etc.\n     * - MUST be inclusive of withdrawal fees. Integrators should be aware of the existence of withdrawal fees.\n     * - MUST NOT revert.\n     *\n     * NOTE: any unfavorable discrepancy between convertToAssets and previewRedeem SHOULD be considered slippage in\n     * share price or some other type of condition, meaning the depositor will lose assets by redeeming.\n     */\n    function previewRedeem(uint256 shares) external view returns (uint256 assets);\n\n    /**\n     * @dev Burns exactly shares from owner and sends assets of underlying tokens to receiver.\n     *\n     * - MUST emit the Withdraw event.\n     * - MAY support an additional flow in which the underlying tokens are owned by the Vault contract before the\n     *   redeem execution, and are accounted for during redeem.\n     * - MUST revert if all of shares cannot be redeemed (due to withdrawal limit being reached, slippage, the owner\n     *   not having enough shares, etc).\n     *\n     * NOTE: some implementations will require pre-requesting to the Vault before a withdrawal may be performed.\n     * Those methods should be performed separately.\n     */\n    function redeem(uint256 shares, address receiver, address owner) external returns (uint256 assets);\n}\n"},"@openzeppelin/contracts/proxy/beacon/IBeacon.sol":{"content":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (proxy/beacon/IBeacon.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev This is the interface that {BeaconProxy} expects of its beacon.\n */\ninterface IBeacon {\n    /**\n     * @dev Must return an address that can be used as a delegate call target.\n     *\n     * {BeaconProxy} will check that this address is a contract.\n     */\n    function implementation() external view returns (address);\n}\n"},"@openzeppelin/contracts/proxy/ERC1967/ERC1967Proxy.sol":{"content":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (proxy/ERC1967/ERC1967Proxy.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../Proxy.sol\";\nimport \"./ERC1967Upgrade.sol\";\n\n/**\n * @dev This contract implements an upgradeable proxy. It is upgradeable because calls are delegated to an\n * implementation address that can be changed. This address is stored in storage in the location specified by\n * https://eips.ethereum.org/EIPS/eip-1967[EIP1967], so that it doesn't conflict with the storage layout of the\n * implementation behind the proxy.\n */\ncontract ERC1967Proxy is Proxy, ERC1967Upgrade {\n    /**\n     * @dev Initializes the upgradeable proxy with an initial implementation specified by `_logic`.\n     *\n     * If `_data` is nonempty, it's used as data in a delegate call to `_logic`. This will typically be an encoded\n     * function call, and allows initializing the storage of the proxy like a Solidity constructor.\n     */\n    constructor(address _logic, bytes memory _data) payable {\n        _upgradeToAndCall(_logic, _data, false);\n    }\n\n    /**\n     * @dev Returns the current implementation address.\n     */\n    function _implementation() internal view virtual override returns (address impl) {\n        return ERC1967Upgrade._getImplementation();\n    }\n}\n"},"@openzeppelin/contracts/proxy/ERC1967/ERC1967Upgrade.sol":{"content":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (proxy/ERC1967/ERC1967Upgrade.sol)\n\npragma solidity ^0.8.2;\n\nimport \"../beacon/IBeacon.sol\";\nimport \"../../interfaces/IERC1967.sol\";\nimport \"../../interfaces/draft-IERC1822.sol\";\nimport \"../../utils/Address.sol\";\nimport \"../../utils/StorageSlot.sol\";\n\n/**\n * @dev This abstract contract provides getters and event emitting update functions for\n * https://eips.ethereum.org/EIPS/eip-1967[EIP1967] slots.\n *\n * _Available since v4.1._\n */\nabstract contract ERC1967Upgrade is IERC1967 {\n    // This is the keccak-256 hash of \"eip1967.proxy.rollback\" subtracted by 1\n    bytes32 private constant _ROLLBACK_SLOT = 0x4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd9143;\n\n    /**\n     * @dev Storage slot with the address of the current implementation.\n     * This is the keccak-256 hash of \"eip1967.proxy.implementation\" subtracted by 1, and is\n     * validated in the constructor.\n     */\n    bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\n\n    /**\n     * @dev Returns the current implementation address.\n     */\n    function _getImplementation() internal view returns (address) {\n        return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value;\n    }\n\n    /**\n     * @dev Stores a new address in the EIP1967 implementation slot.\n     */\n    function _setImplementation(address newImplementation) private {\n        require(Address.isContract(newImplementation), \"ERC1967: new implementation is not a contract\");\n        StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation;\n    }\n\n    /**\n     * @dev Perform implementation upgrade\n     *\n     * Emits an {Upgraded} event.\n     */\n    function _upgradeTo(address newImplementation) internal {\n        _setImplementation(newImplementation);\n        emit Upgraded(newImplementation);\n    }\n\n    /**\n     * @dev Perform implementation upgrade with additional setup call.\n     *\n     * Emits an {Upgraded} event.\n     */\n    function _upgradeToAndCall(address newImplementation, bytes memory data, bool forceCall) internal {\n        _upgradeTo(newImplementation);\n        if (data.length > 0 || forceCall) {\n            Address.functionDelegateCall(newImplementation, data);\n        }\n    }\n\n    /**\n     * @dev Perform implementation upgrade with security checks for UUPS proxies, and additional setup call.\n     *\n     * Emits an {Upgraded} event.\n     */\n    function _upgradeToAndCallUUPS(address newImplementation, bytes memory data, bool forceCall) internal {\n        // Upgrades from old implementations will perform a rollback test. This test requires the new\n        // implementation to upgrade back to the old, non-ERC1822 compliant, implementation. Removing\n        // this special case will break upgrade paths from old UUPS implementation to new ones.\n        if (StorageSlot.getBooleanSlot(_ROLLBACK_SLOT).value) {\n            _setImplementation(newImplementation);\n        } else {\n            try IERC1822Proxiable(newImplementation).proxiableUUID() returns (bytes32 slot) {\n                require(slot == _IMPLEMENTATION_SLOT, \"ERC1967Upgrade: unsupported proxiableUUID\");\n            } catch {\n                revert(\"ERC1967Upgrade: new implementation is not UUPS\");\n            }\n            _upgradeToAndCall(newImplementation, data, forceCall);\n        }\n    }\n\n    /**\n     * @dev Storage slot with the admin of the contract.\n     * This is the keccak-256 hash of \"eip1967.proxy.admin\" subtracted by 1, and is\n     * validated in the constructor.\n     */\n    bytes32 internal constant _ADMIN_SLOT = 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103;\n\n    /**\n     * @dev Returns the current admin.\n     */\n    function _getAdmin() internal view returns (address) {\n        return StorageSlot.getAddressSlot(_ADMIN_SLOT).value;\n    }\n\n    /**\n     * @dev Stores a new address in the EIP1967 admin slot.\n     */\n    function _setAdmin(address newAdmin) private {\n        require(newAdmin != address(0), \"ERC1967: new admin is the zero address\");\n        StorageSlot.getAddressSlot(_ADMIN_SLOT).value = newAdmin;\n    }\n\n    /**\n     * @dev Changes the admin of the proxy.\n     *\n     * Emits an {AdminChanged} event.\n     */\n    function _changeAdmin(address newAdmin) internal {\n        emit AdminChanged(_getAdmin(), newAdmin);\n        _setAdmin(newAdmin);\n    }\n\n    /**\n     * @dev The storage slot of the UpgradeableBeacon contract which defines the implementation for this proxy.\n     * This is bytes32(uint256(keccak256('eip1967.proxy.beacon')) - 1)) and is validated in the constructor.\n     */\n    bytes32 internal constant _BEACON_SLOT = 0xa3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6cb3582b35133d50;\n\n    /**\n     * @dev Returns the current beacon.\n     */\n    function _getBeacon() internal view returns (address) {\n        return StorageSlot.getAddressSlot(_BEACON_SLOT).value;\n    }\n\n    /**\n     * @dev Stores a new beacon in the EIP1967 beacon slot.\n     */\n    function _setBeacon(address newBeacon) private {\n        require(Address.isContract(newBeacon), \"ERC1967: new beacon is not a contract\");\n        require(\n            Address.isContract(IBeacon(newBeacon).implementation()),\n            \"ERC1967: beacon implementation is not a contract\"\n        );\n        StorageSlot.getAddressSlot(_BEACON_SLOT).value = newBeacon;\n    }\n\n    /**\n     * @dev Perform beacon upgrade with additional setup call. Note: This upgrades the address of the beacon, it does\n     * not upgrade the implementation contained in the beacon (see {UpgradeableBeacon-_setImplementation} for that).\n     *\n     * Emits a {BeaconUpgraded} event.\n     */\n    function _upgradeBeaconToAndCall(address newBeacon, bytes memory data, bool forceCall) internal {\n        _setBeacon(newBeacon);\n        emit BeaconUpgraded(newBeacon);\n        if (data.length > 0 || forceCall) {\n            Address.functionDelegateCall(IBeacon(newBeacon).implementation(), data);\n        }\n    }\n}\n"},"@openzeppelin/contracts/proxy/Proxy.sol":{"content":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.6.0) (proxy/Proxy.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev This abstract contract provides a fallback function that delegates all calls to another contract using the EVM\n * instruction `delegatecall`. We refer to the second contract as the _implementation_ behind the proxy, and it has to\n * be specified by overriding the virtual {_implementation} function.\n *\n * Additionally, delegation to the implementation can be triggered manually through the {_fallback} function, or to a\n * different contract through the {_delegate} function.\n *\n * The success and return data of the delegated call will be returned back to the caller of the proxy.\n */\nabstract contract Proxy {\n    /**\n     * @dev Delegates the current call to `implementation`.\n     *\n     * This function does not return to its internal call site, it will return directly to the external caller.\n     */\n    function _delegate(address implementation) internal virtual {\n        assembly {\n            // Copy msg.data. We take full control of memory in this inline assembly\n            // block because it will not return to Solidity code. We overwrite the\n            // Solidity scratch pad at memory position 0.\n            calldatacopy(0, 0, calldatasize())\n\n            // Call the implementation.\n            // out and outsize are 0 because we don't know the size yet.\n            let result := delegatecall(gas(), implementation, 0, calldatasize(), 0, 0)\n\n            // Copy the returned data.\n            returndatacopy(0, 0, returndatasize())\n\n            switch result\n            // delegatecall returns 0 on error.\n            case 0 {\n                revert(0, returndatasize())\n            }\n            default {\n                return(0, returndatasize())\n            }\n        }\n    }\n\n    /**\n     * @dev This is a virtual function that should be overridden so it returns the address to which the fallback function\n     * and {_fallback} should delegate.\n     */\n    function _implementation() internal view virtual returns (address);\n\n    /**\n     * @dev Delegates the current call to the address returned by `_implementation()`.\n     *\n     * This function does not return to its internal call site, it will return directly to the external caller.\n     */\n    function _fallback() internal virtual {\n        _beforeFallback();\n        _delegate(_implementation());\n    }\n\n    /**\n     * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if no other\n     * function in the contract matches the call data.\n     */\n    fallback() external payable virtual {\n        _fallback();\n    }\n\n    /**\n     * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if call data\n     * is empty.\n     */\n    receive() external payable virtual {\n        _fallback();\n    }\n\n    /**\n     * @dev Hook that is called before falling back to the implementation. Can happen as part of a manual `_fallback`\n     * call, or as part of the Solidity `fallback` or `receive` functions.\n     *\n     * If overridden should call `super._beforeFallback()`.\n     */\n    function _beforeFallback() internal virtual {}\n}\n"},"@openzeppelin/contracts/proxy/transparent/ProxyAdmin.sol":{"content":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.8.3) (proxy/transparent/ProxyAdmin.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./TransparentUpgradeableProxy.sol\";\nimport \"../../access/Ownable.sol\";\n\n/**\n * @dev This is an auxiliary contract meant to be assigned as the admin of a {TransparentUpgradeableProxy}. For an\n * explanation of why you would want to use this see the documentation for {TransparentUpgradeableProxy}.\n */\ncontract ProxyAdmin is Ownable {\n    /**\n     * @dev Returns the current implementation of `proxy`.\n     *\n     * Requirements:\n     *\n     * - This contract must be the admin of `proxy`.\n     */\n    function getProxyImplementation(ITransparentUpgradeableProxy proxy) public view virtual returns (address) {\n        // We need to manually run the static call since the getter cannot be flagged as view\n        // bytes4(keccak256(\"implementation()\")) == 0x5c60da1b\n        (bool success, bytes memory returndata) = address(proxy).staticcall(hex\"5c60da1b\");\n        require(success);\n        return abi.decode(returndata, (address));\n    }\n\n    /**\n     * @dev Returns the current admin of `proxy`.\n     *\n     * Requirements:\n     *\n     * - This contract must be the admin of `proxy`.\n     */\n    function getProxyAdmin(ITransparentUpgradeableProxy proxy) public view virtual returns (address) {\n        // We need to manually run the static call since the getter cannot be flagged as view\n        // bytes4(keccak256(\"admin()\")) == 0xf851a440\n        (bool success, bytes memory returndata) = address(proxy).staticcall(hex\"f851a440\");\n        require(success);\n        return abi.decode(returndata, (address));\n    }\n\n    /**\n     * @dev Changes the admin of `proxy` to `newAdmin`.\n     *\n     * Requirements:\n     *\n     * - This contract must be the current admin of `proxy`.\n     */\n    function changeProxyAdmin(ITransparentUpgradeableProxy proxy, address newAdmin) public virtual onlyOwner {\n        proxy.changeAdmin(newAdmin);\n    }\n\n    /**\n     * @dev Upgrades `proxy` to `implementation`. See {TransparentUpgradeableProxy-upgradeTo}.\n     *\n     * Requirements:\n     *\n     * - This contract must be the admin of `proxy`.\n     */\n    function upgrade(ITransparentUpgradeableProxy proxy, address implementation) public virtual onlyOwner {\n        proxy.upgradeTo(implementation);\n    }\n\n    /**\n     * @dev Upgrades `proxy` to `implementation` and calls a function on the new implementation. See\n     * {TransparentUpgradeableProxy-upgradeToAndCall}.\n     *\n     * Requirements:\n     *\n     * - This contract must be the admin of `proxy`.\n     */\n    function upgradeAndCall(\n        ITransparentUpgradeableProxy proxy,\n        address implementation,\n        bytes memory data\n    ) public payable virtual onlyOwner {\n        proxy.upgradeToAndCall{value: msg.value}(implementation, data);\n    }\n}\n"},"@openzeppelin/contracts/proxy/transparent/TransparentUpgradeableProxy.sol":{"content":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (proxy/transparent/TransparentUpgradeableProxy.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../ERC1967/ERC1967Proxy.sol\";\n\n/**\n * @dev Interface for {TransparentUpgradeableProxy}. In order to implement transparency, {TransparentUpgradeableProxy}\n * does not implement this interface directly, and some of its functions are implemented by an internal dispatch\n * mechanism. The compiler is unaware that these functions are implemented by {TransparentUpgradeableProxy} and will not\n * include them in the ABI so this interface must be used to interact with it.\n */\ninterface ITransparentUpgradeableProxy is IERC1967 {\n    function admin() external view returns (address);\n\n    function implementation() external view returns (address);\n\n    function changeAdmin(address) external;\n\n    function upgradeTo(address) external;\n\n    function upgradeToAndCall(address, bytes memory) external payable;\n}\n\n/**\n * @dev This contract implements a proxy that is upgradeable by an admin.\n *\n * To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector\n * clashing], which can potentially be used in an attack, this contract uses the\n * https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two\n * things that go hand in hand:\n *\n * 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if\n * that call matches one of the admin functions exposed by the proxy itself.\n * 2. If the admin calls the proxy, it can access the admin functions, but its calls will never be forwarded to the\n * implementation. If the admin tries to call a function on the implementation it will fail with an error that says\n * \"admin cannot fallback to proxy target\".\n *\n * These properties mean that the admin account can only be used for admin actions like upgrading the proxy or changing\n * the admin, so it's best if it's a dedicated account that is not used for anything else. This will avoid headaches due\n * to sudden errors when trying to call a function from the proxy implementation.\n *\n * Our recommendation is for the dedicated account to be an instance of the {ProxyAdmin} contract. If set up this way,\n * you should think of the `ProxyAdmin` instance as the real administrative interface of your proxy.\n *\n * NOTE: The real interface of this proxy is that defined in `ITransparentUpgradeableProxy`. This contract does not\n * inherit from that interface, and instead the admin functions are implicitly implemented using a custom dispatch\n * mechanism in `_fallback`. Consequently, the compiler will not produce an ABI for this contract. This is necessary to\n * fully implement transparency without decoding reverts caused by selector clashes between the proxy and the\n * implementation.\n *\n * WARNING: It is not recommended to extend this contract to add additional external functions. If you do so, the compiler\n * will not check that there are no selector conflicts, due to the note above. A selector clash between any new function\n * and the functions declared in {ITransparentUpgradeableProxy} will be resolved in favor of the new one. This could\n * render the admin operations inaccessible, which could prevent upgradeability. Transparency may also be compromised.\n */\ncontract TransparentUpgradeableProxy is ERC1967Proxy {\n    /**\n     * @dev Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and\n     * optionally initialized with `_data` as explained in {ERC1967Proxy-constructor}.\n     */\n    constructor(address _logic, address admin_, bytes memory _data) payable ERC1967Proxy(_logic, _data) {\n        _changeAdmin(admin_);\n    }\n\n    /**\n     * @dev Modifier used internally that will delegate the call to the implementation unless the sender is the admin.\n     *\n     * CAUTION: This modifier is deprecated, as it could cause issues if the modified function has arguments, and the\n     * implementation provides a function with the same selector.\n     */\n    modifier ifAdmin() {\n        if (msg.sender == _getAdmin()) {\n            _;\n        } else {\n            _fallback();\n        }\n    }\n\n    /**\n     * @dev If caller is the admin process the call internally, otherwise transparently fallback to the proxy behavior\n     */\n    function _fallback() internal virtual override {\n        if (msg.sender == _getAdmin()) {\n            bytes memory ret;\n            bytes4 selector = msg.sig;\n            if (selector == ITransparentUpgradeableProxy.upgradeTo.selector) {\n                ret = _dispatchUpgradeTo();\n            } else if (selector == ITransparentUpgradeableProxy.upgradeToAndCall.selector) {\n                ret = _dispatchUpgradeToAndCall();\n            } else if (selector == ITransparentUpgradeableProxy.changeAdmin.selector) {\n                ret = _dispatchChangeAdmin();\n            } else if (selector == ITransparentUpgradeableProxy.admin.selector) {\n                ret = _dispatchAdmin();\n            } else if (selector == ITransparentUpgradeableProxy.implementation.selector) {\n                ret = _dispatchImplementation();\n            } else {\n                revert(\"TransparentUpgradeableProxy: admin cannot fallback to proxy target\");\n            }\n            assembly {\n                return(add(ret, 0x20), mload(ret))\n            }\n        } else {\n            super._fallback();\n        }\n    }\n\n    /**\n     * @dev Returns the current admin.\n     *\n     * TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the\n     * https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.\n     * `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`\n     */\n    function _dispatchAdmin() private returns (bytes memory) {\n        _requireZeroValue();\n\n        address admin = _getAdmin();\n        return abi.encode(admin);\n    }\n\n    /**\n     * @dev Returns the current implementation.\n     *\n     * TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the\n     * https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.\n     * `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`\n     */\n    function _dispatchImplementation() private returns (bytes memory) {\n        _requireZeroValue();\n\n        address implementation = _implementation();\n        return abi.encode(implementation);\n    }\n\n    /**\n     * @dev Changes the admin of the proxy.\n     *\n     * Emits an {AdminChanged} event.\n     */\n    function _dispatchChangeAdmin() private returns (bytes memory) {\n        _requireZeroValue();\n\n        address newAdmin = abi.decode(msg.data[4:], (address));\n        _changeAdmin(newAdmin);\n\n        return \"\";\n    }\n\n    /**\n     * @dev Upgrade the implementation of the proxy.\n     */\n    function _dispatchUpgradeTo() private returns (bytes memory) {\n        _requireZeroValue();\n\n        address newImplementation = abi.decode(msg.data[4:], (address));\n        _upgradeToAndCall(newImplementation, bytes(\"\"), false);\n\n        return \"\";\n    }\n\n    /**\n     * @dev Upgrade the implementation of the proxy, and then call a function from the new implementation as specified\n     * by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the\n     * proxied contract.\n     */\n    function _dispatchUpgradeToAndCall() private returns (bytes memory) {\n        (address newImplementation, bytes memory data) = abi.decode(msg.data[4:], (address, bytes));\n        _upgradeToAndCall(newImplementation, data, true);\n\n        return \"\";\n    }\n\n    /**\n     * @dev Returns the current admin.\n     *\n     * CAUTION: This function is deprecated. Use {ERC1967Upgrade-_getAdmin} instead.\n     */\n    function _admin() internal view virtual returns (address) {\n        return _getAdmin();\n    }\n\n    /**\n     * @dev To keep this contract fully transparent, all `ifAdmin` functions must be payable. This helper is here to\n     * emulate some proxy functions being non-payable while still allowing value to pass through.\n     */\n    function _requireZeroValue() private {\n        require(msg.value == 0);\n    }\n}\n"},"@openzeppelin/contracts/security/Pausable.sol":{"content":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (security/Pausable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../utils/Context.sol\";\n\n/**\n * @dev Contract module which allows children to implement an emergency stop\n * mechanism that can be triggered by an authorized account.\n *\n * This module is used through inheritance. It will make available the\n * modifiers `whenNotPaused` and `whenPaused`, which can be applied to\n * the functions of your contract. Note that they will not be pausable by\n * simply including this module, only once the modifiers are put in place.\n */\nabstract contract Pausable is Context {\n    /**\n     * @dev Emitted when the pause is triggered by `account`.\n     */\n    event Paused(address account);\n\n    /**\n     * @dev Emitted when the pause is lifted by `account`.\n     */\n    event Unpaused(address account);\n\n    bool private _paused;\n\n    /**\n     * @dev Initializes the contract in unpaused state.\n     */\n    constructor() {\n        _paused = false;\n    }\n\n    /**\n     * @dev Modifier to make a function callable only when the contract is not paused.\n     *\n     * Requirements:\n     *\n     * - The contract must not be paused.\n     */\n    modifier whenNotPaused() {\n        _requireNotPaused();\n        _;\n    }\n\n    /**\n     * @dev Modifier to make a function callable only when the contract is paused.\n     *\n     * Requirements:\n     *\n     * - The contract must be paused.\n     */\n    modifier whenPaused() {\n        _requirePaused();\n        _;\n    }\n\n    /**\n     * @dev Returns true if the contract is paused, and false otherwise.\n     */\n    function paused() public view virtual returns (bool) {\n        return _paused;\n    }\n\n    /**\n     * @dev Throws if the contract is paused.\n     */\n    function _requireNotPaused() internal view virtual {\n        require(!paused(), \"Pausable: paused\");\n    }\n\n    /**\n     * @dev Throws if the contract is not paused.\n     */\n    function _requirePaused() internal view virtual {\n        require(paused(), \"Pausable: not paused\");\n    }\n\n    /**\n     * @dev Triggers stopped state.\n     *\n     * Requirements:\n     *\n     * - The contract must not be paused.\n     */\n    function _pause() internal virtual whenNotPaused {\n        _paused = true;\n        emit Paused(_msgSender());\n    }\n\n    /**\n     * @dev Returns to normal state.\n     *\n     * Requirements:\n     *\n     * - The contract must be paused.\n     */\n    function _unpause() internal virtual whenPaused {\n        _paused = false;\n        emit Unpaused(_msgSender());\n    }\n}\n"},"@openzeppelin/contracts/token/ERC1155/IERC1155Receiver.sol":{"content":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC1155/IERC1155Receiver.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../../utils/introspection/IERC165.sol\";\n\n/**\n * @dev _Available since v3.1._\n */\ninterface IERC1155Receiver is IERC165 {\n    /**\n     * @dev Handles the receipt of a single ERC1155 token type. This function is\n     * called at the end of a `safeTransferFrom` after the balance has been updated.\n     *\n     * NOTE: To accept the transfer, this must return\n     * `bytes4(keccak256(\"onERC1155Received(address,address,uint256,uint256,bytes)\"))`\n     * (i.e. 0xf23a6e61, or its own function selector).\n     *\n     * @param operator The address which initiated the transfer (i.e. msg.sender)\n     * @param from The address which previously owned the token\n     * @param id The ID of the token being transferred\n     * @param value The amount of tokens being transferred\n     * @param data Additional data with no specified format\n     * @return `bytes4(keccak256(\"onERC1155Received(address,address,uint256,uint256,bytes)\"))` if transfer is allowed\n     */\n    function onERC1155Received(\n        address operator,\n        address from,\n        uint256 id,\n        uint256 value,\n        bytes calldata data\n    ) external returns (bytes4);\n\n    /**\n     * @dev Handles the receipt of a multiple ERC1155 token types. This function\n     * is called at the end of a `safeBatchTransferFrom` after the balances have\n     * been updated.\n     *\n     * NOTE: To accept the transfer(s), this must return\n     * `bytes4(keccak256(\"onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)\"))`\n     * (i.e. 0xbc197c81, or its own function selector).\n     *\n     * @param operator The address which initiated the batch transfer (i.e. msg.sender)\n     * @param from The address which previously owned the token\n     * @param ids An array containing ids of each token being transferred (order and length must match values array)\n     * @param values An array containing amounts of each token being transferred (order and length must match ids array)\n     * @param data Additional data with no specified format\n     * @return `bytes4(keccak256(\"onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)\"))` if transfer is allowed\n     */\n    function onERC1155BatchReceived(\n        address operator,\n        address from,\n        uint256[] calldata ids,\n        uint256[] calldata values,\n        bytes calldata data\n    ) external returns (bytes4);\n}\n"},"@openzeppelin/contracts/token/ERC20/ERC20.sol":{"content":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/ERC20.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC20.sol\";\nimport \"./extensions/IERC20Metadata.sol\";\nimport \"../../utils/Context.sol\";\n\n/**\n * @dev Implementation of the {IERC20} interface.\n *\n * This implementation is agnostic to the way tokens are created. This means\n * that a supply mechanism has to be added in a derived contract using {_mint}.\n * For a generic mechanism see {ERC20PresetMinterPauser}.\n *\n * TIP: For a detailed writeup see our guide\n * https://forum.openzeppelin.com/t/how-to-implement-erc20-supply-mechanisms/226[How\n * to implement supply mechanisms].\n *\n * The default value of {decimals} is 18. To change this, you should override\n * this function so it returns a different value.\n *\n * We have followed general OpenZeppelin Contracts guidelines: functions revert\n * instead returning `false` on failure. This behavior is nonetheless\n * conventional and does not conflict with the expectations of ERC20\n * applications.\n *\n * Additionally, an {Approval} event is emitted on calls to {transferFrom}.\n * This allows applications to reconstruct the allowance for all accounts just\n * by listening to said events. Other implementations of the EIP may not emit\n * these events, as it isn't required by the specification.\n *\n * Finally, the non-standard {decreaseAllowance} and {increaseAllowance}\n * functions have been added to mitigate the well-known issues around setting\n * allowances. See {IERC20-approve}.\n */\ncontract ERC20 is Context, IERC20, IERC20Metadata {\n    mapping(address => uint256) private _balances;\n\n    mapping(address => mapping(address => uint256)) private _allowances;\n\n    uint256 private _totalSupply;\n\n    string private _name;\n    string private _symbol;\n\n    /**\n     * @dev Sets the values for {name} and {symbol}.\n     *\n     * All two of these values are immutable: they can only be set once during\n     * construction.\n     */\n    constructor(string memory name_, string memory symbol_) {\n        _name = name_;\n        _symbol = symbol_;\n    }\n\n    /**\n     * @dev Returns the name of the token.\n     */\n    function name() public view virtual override returns (string memory) {\n        return _name;\n    }\n\n    /**\n     * @dev Returns the symbol of the token, usually a shorter version of the\n     * name.\n     */\n    function symbol() public view virtual override returns (string memory) {\n        return _symbol;\n    }\n\n    /**\n     * @dev Returns the number of decimals used to get its user representation.\n     * For example, if `decimals` equals `2`, a balance of `505` tokens should\n     * be displayed to a user as `5.05` (`505 / 10 ** 2`).\n     *\n     * Tokens usually opt for a value of 18, imitating the relationship between\n     * Ether and Wei. This is the default value returned by this function, unless\n     * it's overridden.\n     *\n     * NOTE: This information is only used for _display_ purposes: it in\n     * no way affects any of the arithmetic of the contract, including\n     * {IERC20-balanceOf} and {IERC20-transfer}.\n     */\n    function decimals() public view virtual override returns (uint8) {\n        return 18;\n    }\n\n    /**\n     * @dev See {IERC20-totalSupply}.\n     */\n    function totalSupply() public view virtual override returns (uint256) {\n        return _totalSupply;\n    }\n\n    /**\n     * @dev See {IERC20-balanceOf}.\n     */\n    function balanceOf(address account) public view virtual override returns (uint256) {\n        return _balances[account];\n    }\n\n    /**\n     * @dev See {IERC20-transfer}.\n     *\n     * Requirements:\n     *\n     * - `to` cannot be the zero address.\n     * - the caller must have a balance of at least `amount`.\n     */\n    function transfer(address to, uint256 amount) public virtual override returns (bool) {\n        address owner = _msgSender();\n        _transfer(owner, to, amount);\n        return true;\n    }\n\n    /**\n     * @dev See {IERC20-allowance}.\n     */\n    function allowance(address owner, address spender) public view virtual override returns (uint256) {\n        return _allowances[owner][spender];\n    }\n\n    /**\n     * @dev See {IERC20-approve}.\n     *\n     * NOTE: If `amount` is the maximum `uint256`, the allowance is not updated on\n     * `transferFrom`. This is semantically equivalent to an infinite approval.\n     *\n     * Requirements:\n     *\n     * - `spender` cannot be the zero address.\n     */\n    function approve(address spender, uint256 amount) public virtual override returns (bool) {\n        address owner = _msgSender();\n        _approve(owner, spender, amount);\n        return true;\n    }\n\n    /**\n     * @dev See {IERC20-transferFrom}.\n     *\n     * Emits an {Approval} event indicating the updated allowance. This is not\n     * required by the EIP. See the note at the beginning of {ERC20}.\n     *\n     * NOTE: Does not update the allowance if the current allowance\n     * is the maximum `uint256`.\n     *\n     * Requirements:\n     *\n     * - `from` and `to` cannot be the zero address.\n     * - `from` must have a balance of at least `amount`.\n     * - the caller must have allowance for ``from``'s tokens of at least\n     * `amount`.\n     */\n    function transferFrom(address from, address to, uint256 amount) public virtual override returns (bool) {\n        address spender = _msgSender();\n        _spendAllowance(from, spender, amount);\n        _transfer(from, to, amount);\n        return true;\n    }\n\n    /**\n     * @dev Atomically increases the allowance granted to `spender` by the caller.\n     *\n     * This is an alternative to {approve} that can be used as a mitigation for\n     * problems described in {IERC20-approve}.\n     *\n     * Emits an {Approval} event indicating the updated allowance.\n     *\n     * Requirements:\n     *\n     * - `spender` cannot be the zero address.\n     */\n    function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {\n        address owner = _msgSender();\n        _approve(owner, spender, allowance(owner, spender) + addedValue);\n        return true;\n    }\n\n    /**\n     * @dev Atomically decreases the allowance granted to `spender` by the caller.\n     *\n     * This is an alternative to {approve} that can be used as a mitigation for\n     * problems described in {IERC20-approve}.\n     *\n     * Emits an {Approval} event indicating the updated allowance.\n     *\n     * Requirements:\n     *\n     * - `spender` cannot be the zero address.\n     * - `spender` must have allowance for the caller of at least\n     * `subtractedValue`.\n     */\n    function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) {\n        address owner = _msgSender();\n        uint256 currentAllowance = allowance(owner, spender);\n        require(currentAllowance >= subtractedValue, \"ERC20: decreased allowance below zero\");\n        unchecked {\n            _approve(owner, spender, currentAllowance - subtractedValue);\n        }\n\n        return true;\n    }\n\n    /**\n     * @dev Moves `amount` of tokens from `from` to `to`.\n     *\n     * This internal function is equivalent to {transfer}, and can be used to\n     * e.g. implement automatic token fees, slashing mechanisms, etc.\n     *\n     * Emits a {Transfer} event.\n     *\n     * Requirements:\n     *\n     * - `from` cannot be the zero address.\n     * - `to` cannot be the zero address.\n     * - `from` must have a balance of at least `amount`.\n     */\n    function _transfer(address from, address to, uint256 amount) internal virtual {\n        require(from != address(0), \"ERC20: transfer from the zero address\");\n        require(to != address(0), \"ERC20: transfer to the zero address\");\n\n        _beforeTokenTransfer(from, to, amount);\n\n        uint256 fromBalance = _balances[from];\n        require(fromBalance >= amount, \"ERC20: transfer amount exceeds balance\");\n        unchecked {\n            _balances[from] = fromBalance - amount;\n            // Overflow not possible: the sum of all balances is capped by totalSupply, and the sum is preserved by\n            // decrementing then incrementing.\n            _balances[to] += amount;\n        }\n\n        emit Transfer(from, to, amount);\n\n        _afterTokenTransfer(from, to, amount);\n    }\n\n    /** @dev Creates `amount` tokens and assigns them to `account`, increasing\n     * the total supply.\n     *\n     * Emits a {Transfer} event with `from` set to the zero address.\n     *\n     * Requirements:\n     *\n     * - `account` cannot be the zero address.\n     */\n    function _mint(address account, uint256 amount) internal virtual {\n        require(account != address(0), \"ERC20: mint to the zero address\");\n\n        _beforeTokenTransfer(address(0), account, amount);\n\n        _totalSupply += amount;\n        unchecked {\n            // Overflow not possible: balance + amount is at most totalSupply + amount, which is checked above.\n            _balances[account] += amount;\n        }\n        emit Transfer(address(0), account, amount);\n\n        _afterTokenTransfer(address(0), account, amount);\n    }\n\n    /**\n     * @dev Destroys `amount` tokens from `account`, reducing the\n     * total supply.\n     *\n     * Emits a {Transfer} event with `to` set to the zero address.\n     *\n     * Requirements:\n     *\n     * - `account` cannot be the zero address.\n     * - `account` must have at least `amount` tokens.\n     */\n    function _burn(address account, uint256 amount) internal virtual {\n        require(account != address(0), \"ERC20: burn from the zero address\");\n\n        _beforeTokenTransfer(account, address(0), amount);\n\n        uint256 accountBalance = _balances[account];\n        require(accountBalance >= amount, \"ERC20: burn amount exceeds balance\");\n        unchecked {\n            _balances[account] = accountBalance - amount;\n            // Overflow not possible: amount <= accountBalance <= totalSupply.\n            _totalSupply -= amount;\n        }\n\n        emit Transfer(account, address(0), amount);\n\n        _afterTokenTransfer(account, address(0), amount);\n    }\n\n    /**\n     * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens.\n     *\n     * This internal function is equivalent to `approve`, and can be used to\n     * e.g. set automatic allowances for certain subsystems, etc.\n     *\n     * Emits an {Approval} event.\n     *\n     * Requirements:\n     *\n     * - `owner` cannot be the zero address.\n     * - `spender` cannot be the zero address.\n     */\n    function _approve(address owner, address spender, uint256 amount) internal virtual {\n        require(owner != address(0), \"ERC20: approve from the zero address\");\n        require(spender != address(0), \"ERC20: approve to the zero address\");\n\n        _allowances[owner][spender] = amount;\n        emit Approval(owner, spender, amount);\n    }\n\n    /**\n     * @dev Updates `owner` s allowance for `spender` based on spent `amount`.\n     *\n     * Does not update the allowance amount in case of infinite allowance.\n     * Revert if not enough allowance is available.\n     *\n     * Might emit an {Approval} event.\n     */\n    function _spendAllowance(address owner, address spender, uint256 amount) internal virtual {\n        uint256 currentAllowance = allowance(owner, spender);\n        if (currentAllowance != type(uint256).max) {\n            require(currentAllowance >= amount, \"ERC20: insufficient allowance\");\n            unchecked {\n                _approve(owner, spender, currentAllowance - amount);\n            }\n        }\n    }\n\n    /**\n     * @dev Hook that is called before any transfer of tokens. This includes\n     * minting and burning.\n     *\n     * Calling conditions:\n     *\n     * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n     * will be transferred to `to`.\n     * - when `from` is zero, `amount` tokens will be minted for `to`.\n     * - when `to` is zero, `amount` of ``from``'s tokens will be burned.\n     * - `from` and `to` are never both zero.\n     *\n     * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n     */\n    function _beforeTokenTransfer(address from, address to, uint256 amount) internal virtual {}\n\n    /**\n     * @dev Hook that is called after any transfer of tokens. This includes\n     * minting and burning.\n     *\n     * Calling conditions:\n     *\n     * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n     * has been transferred to `to`.\n     * - when `from` is zero, `amount` tokens have been minted for `to`.\n     * - when `to` is zero, `amount` of ``from``'s tokens have been burned.\n     * - `from` and `to` are never both zero.\n     *\n     * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n     */\n    function _afterTokenTransfer(address from, address to, uint256 amount) internal virtual {}\n}\n"},"@openzeppelin/contracts/token/ERC20/extensions/ERC4626.sol":{"content":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/extensions/ERC4626.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../ERC20.sol\";\nimport \"../utils/SafeERC20.sol\";\nimport \"../../../interfaces/IERC4626.sol\";\nimport \"../../../utils/math/Math.sol\";\n\n/**\n * @dev Implementation of the ERC4626 \"Tokenized Vault Standard\" as defined in\n * https://eips.ethereum.org/EIPS/eip-4626[EIP-4626].\n *\n * This extension allows the minting and burning of \"shares\" (represented using the ERC20 inheritance) in exchange for\n * underlying \"assets\" through standardized {deposit}, {mint}, {redeem} and {burn} workflows. This contract extends\n * the ERC20 standard. Any additional extensions included along it would affect the \"shares\" token represented by this\n * contract and not the \"assets\" token which is an independent contract.\n *\n * [CAUTION]\n * ====\n * In empty (or nearly empty) ERC-4626 vaults, deposits are at high risk of being stolen through frontrunning\n * with a \"donation\" to the vault that inflates the price of a share. This is variously known as a donation or inflation\n * attack and is essentially a problem of slippage. Vault deployers can protect against this attack by making an initial\n * deposit of a non-trivial amount of the asset, such that price manipulation becomes infeasible. Withdrawals may\n * similarly be affected by slippage. Users can protect against this attack as well as unexpected slippage in general by\n * verifying the amount received is as expected, using a wrapper that performs these checks such as\n * https://github.com/fei-protocol/ERC4626#erc4626router-and-base[ERC4626Router].\n *\n * Since v4.9, this implementation uses virtual assets and shares to mitigate that risk. The `_decimalsOffset()`\n * corresponds to an offset in the decimal representation between the underlying asset's decimals and the vault\n * decimals. This offset also determines the rate of virtual shares to virtual assets in the vault, which itself\n * determines the initial exchange rate. While not fully preventing the attack, analysis shows that the default offset\n * (0) makes it non-profitable, as a result of the value being captured by the virtual shares (out of the attacker's\n * donation) matching the attacker's expected gains. With a larger offset, the attack becomes orders of magnitude more\n * expensive than it is profitable. More details about the underlying math can be found\n * xref:erc4626.adoc#inflation-attack[here].\n *\n * The drawback of this approach is that the virtual shares do capture (a very small) part of the value being accrued\n * to the vault. Also, if the vault experiences losses, the users try to exit the vault, the virtual shares and assets\n * will cause the first user to exit to experience reduced losses in detriment to the last users that will experience\n * bigger losses. Developers willing to revert back to the pre-v4.9 behavior just need to override the\n * `_convertToShares` and `_convertToAssets` functions.\n *\n * To learn more, check out our xref:ROOT:erc4626.adoc[ERC-4626 guide].\n * ====\n *\n * _Available since v4.7._\n */\nabstract contract ERC4626 is ERC20, IERC4626 {\n    using Math for uint256;\n\n    IERC20 private immutable _asset;\n    uint8 private immutable _underlyingDecimals;\n\n    /**\n     * @dev Set the underlying asset contract. This must be an ERC20-compatible contract (ERC20 or ERC777).\n     */\n    constructor(IERC20 asset_) {\n        (bool success, uint8 assetDecimals) = _tryGetAssetDecimals(asset_);\n        _underlyingDecimals = success ? assetDecimals : 18;\n        _asset = asset_;\n    }\n\n    /**\n     * @dev Attempts to fetch the asset decimals. A return value of false indicates that the attempt failed in some way.\n     */\n    function _tryGetAssetDecimals(IERC20 asset_) private view returns (bool, uint8) {\n        (bool success, bytes memory encodedDecimals) = address(asset_).staticcall(\n            abi.encodeWithSelector(IERC20Metadata.decimals.selector)\n        );\n        if (success && encodedDecimals.length >= 32) {\n            uint256 returnedDecimals = abi.decode(encodedDecimals, (uint256));\n            if (returnedDecimals <= type(uint8).max) {\n                return (true, uint8(returnedDecimals));\n            }\n        }\n        return (false, 0);\n    }\n\n    /**\n     * @dev Decimals are computed by adding the decimal offset on top of the underlying asset's decimals. This\n     * \"original\" value is cached during construction of the vault contract. If this read operation fails (e.g., the\n     * asset has not been created yet), a default of 18 is used to represent the underlying asset's decimals.\n     *\n     * See {IERC20Metadata-decimals}.\n     */\n    function decimals() public view virtual override(IERC20Metadata, ERC20) returns (uint8) {\n        return _underlyingDecimals + _decimalsOffset();\n    }\n\n    /** @dev See {IERC4626-asset}. */\n    function asset() public view virtual override returns (address) {\n        return address(_asset);\n    }\n\n    /** @dev See {IERC4626-totalAssets}. */\n    function totalAssets() public view virtual override returns (uint256) {\n        return _asset.balanceOf(address(this));\n    }\n\n    /** @dev See {IERC4626-convertToShares}. */\n    function convertToShares(uint256 assets) public view virtual override returns (uint256) {\n        return _convertToShares(assets, Math.Rounding.Down);\n    }\n\n    /** @dev See {IERC4626-convertToAssets}. */\n    function convertToAssets(uint256 shares) public view virtual override returns (uint256) {\n        return _convertToAssets(shares, Math.Rounding.Down);\n    }\n\n    /** @dev See {IERC4626-maxDeposit}. */\n    function maxDeposit(address) public view virtual override returns (uint256) {\n        return type(uint256).max;\n    }\n\n    /** @dev See {IERC4626-maxMint}. */\n    function maxMint(address) public view virtual override returns (uint256) {\n        return type(uint256).max;\n    }\n\n    /** @dev See {IERC4626-maxWithdraw}. */\n    function maxWithdraw(address owner) public view virtual override returns (uint256) {\n        return _convertToAssets(balanceOf(owner), Math.Rounding.Down);\n    }\n\n    /** @dev See {IERC4626-maxRedeem}. */\n    function maxRedeem(address owner) public view virtual override returns (uint256) {\n        return balanceOf(owner);\n    }\n\n    /** @dev See {IERC4626-previewDeposit}. */\n    function previewDeposit(uint256 assets) public view virtual override returns (uint256) {\n        return _convertToShares(assets, Math.Rounding.Down);\n    }\n\n    /** @dev See {IERC4626-previewMint}. */\n    function previewMint(uint256 shares) public view virtual override returns (uint256) {\n        return _convertToAssets(shares, Math.Rounding.Up);\n    }\n\n    /** @dev See {IERC4626-previewWithdraw}. */\n    function previewWithdraw(uint256 assets) public view virtual override returns (uint256) {\n        return _convertToShares(assets, Math.Rounding.Up);\n    }\n\n    /** @dev See {IERC4626-previewRedeem}. */\n    function previewRedeem(uint256 shares) public view virtual override returns (uint256) {\n        return _convertToAssets(shares, Math.Rounding.Down);\n    }\n\n    /** @dev See {IERC4626-deposit}. */\n    function deposit(uint256 assets, address receiver) public virtual override returns (uint256) {\n        require(assets <= maxDeposit(receiver), \"ERC4626: deposit more than max\");\n\n        uint256 shares = previewDeposit(assets);\n        _deposit(_msgSender(), receiver, assets, shares);\n\n        return shares;\n    }\n\n    /** @dev See {IERC4626-mint}.\n     *\n     * As opposed to {deposit}, minting is allowed even if the vault is in a state where the price of a share is zero.\n     * In this case, the shares will be minted without requiring any assets to be deposited.\n     */\n    function mint(uint256 shares, address receiver) public virtual override returns (uint256) {\n        require(shares <= maxMint(receiver), \"ERC4626: mint more than max\");\n\n        uint256 assets = previewMint(shares);\n        _deposit(_msgSender(), receiver, assets, shares);\n\n        return assets;\n    }\n\n    /** @dev See {IERC4626-withdraw}. */\n    function withdraw(uint256 assets, address receiver, address owner) public virtual override returns (uint256) {\n        require(assets <= maxWithdraw(owner), \"ERC4626: withdraw more than max\");\n\n        uint256 shares = previewWithdraw(assets);\n        _withdraw(_msgSender(), receiver, owner, assets, shares);\n\n        return shares;\n    }\n\n    /** @dev See {IERC4626-redeem}. */\n    function redeem(uint256 shares, address receiver, address owner) public virtual override returns (uint256) {\n        require(shares <= maxRedeem(owner), \"ERC4626: redeem more than max\");\n\n        uint256 assets = previewRedeem(shares);\n        _withdraw(_msgSender(), receiver, owner, assets, shares);\n\n        return assets;\n    }\n\n    /**\n     * @dev Internal conversion function (from assets to shares) with support for rounding direction.\n     */\n    function _convertToShares(uint256 assets, Math.Rounding rounding) internal view virtual returns (uint256) {\n        return assets.mulDiv(totalSupply() + 10 ** _decimalsOffset(), totalAssets() + 1, rounding);\n    }\n\n    /**\n     * @dev Internal conversion function (from shares to assets) with support for rounding direction.\n     */\n    function _convertToAssets(uint256 shares, Math.Rounding rounding) internal view virtual returns (uint256) {\n        return shares.mulDiv(totalAssets() + 1, totalSupply() + 10 ** _decimalsOffset(), rounding);\n    }\n\n    /**\n     * @dev Deposit/mint common workflow.\n     */\n    function _deposit(address caller, address receiver, uint256 assets, uint256 shares) internal virtual {\n        // If _asset is ERC777, `transferFrom` can trigger a reentrancy BEFORE the transfer happens through the\n        // `tokensToSend` hook. On the other hand, the `tokenReceived` hook, that is triggered after the transfer,\n        // calls the vault, which is assumed not malicious.\n        //\n        // Conclusion: we need to do the transfer before we mint so that any reentrancy would happen before the\n        // assets are transferred and before the shares are minted, which is a valid state.\n        // slither-disable-next-line reentrancy-no-eth\n        SafeERC20.safeTransferFrom(_asset, caller, address(this), assets);\n        _mint(receiver, shares);\n\n        emit Deposit(caller, receiver, assets, shares);\n    }\n\n    /**\n     * @dev Withdraw/redeem common workflow.\n     */\n    function _withdraw(\n        address caller,\n        address receiver,\n        address owner,\n        uint256 assets,\n        uint256 shares\n    ) internal virtual {\n        if (caller != owner) {\n            _spendAllowance(owner, caller, shares);\n        }\n\n        // If _asset is ERC777, `transfer` can trigger a reentrancy AFTER the transfer happens through the\n        // `tokensReceived` hook. On the other hand, the `tokensToSend` hook, that is triggered before the transfer,\n        // calls the vault, which is assumed not malicious.\n        //\n        // Conclusion: we need to do the transfer after the burn so that any reentrancy would happen after the\n        // shares are burned and after the assets are transferred, which is a valid state.\n        _burn(owner, shares);\n        SafeERC20.safeTransfer(_asset, receiver, assets);\n\n        emit Withdraw(caller, receiver, owner, assets, shares);\n    }\n\n    function _decimalsOffset() internal view virtual returns (uint8) {\n        return 0;\n    }\n}\n"},"@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol":{"content":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/IERC20Metadata.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC20.sol\";\n\n/**\n * @dev Interface for the optional metadata functions from the ERC20 standard.\n *\n * _Available since v4.1._\n */\ninterface IERC20Metadata is IERC20 {\n    /**\n     * @dev Returns the name of the token.\n     */\n    function name() external view returns (string memory);\n\n    /**\n     * @dev Returns the symbol of the token.\n     */\n    function symbol() external view returns (string memory);\n\n    /**\n     * @dev Returns the decimals places of the token.\n     */\n    function decimals() external view returns (uint8);\n}\n"},"@openzeppelin/contracts/token/ERC20/extensions/IERC20Permit.sol":{"content":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/extensions/IERC20Permit.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in\n * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].\n *\n * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by\n * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't\n * need to send a transaction, and thus is not required to hold Ether at all.\n */\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.9.0) (token/ERC20/IERC20.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC20 standard as defined in the EIP.\n */\ninterface IERC20 {\n    /**\n     * @dev Emitted when `value` tokens are moved from one account (`from`) to\n     * another (`to`).\n     *\n     * Note that `value` may be zero.\n     */\n    event Transfer(address indexed from, address indexed to, uint256 value);\n\n    /**\n     * @dev Emitted when the allowance of a `spender` for an `owner` is set by\n     * a call to {approve}. `value` is the new allowance.\n     */\n    event Approval(address indexed owner, address indexed spender, uint256 value);\n\n    /**\n     * @dev Returns the amount of tokens in existence.\n     */\n    function totalSupply() external view returns (uint256);\n\n    /**\n     * @dev Returns the amount of tokens owned by `account`.\n     */\n    function balanceOf(address account) external view returns (uint256);\n\n    /**\n     * @dev Moves `amount` tokens from the caller's account to `to`.\n     *\n     * Returns a boolean value indicating whether the operation succeeded.\n     *\n     * Emits a {Transfer} event.\n     */\n    function transfer(address to, uint256 amount) external returns (bool);\n\n    /**\n     * @dev Returns the remaining number of tokens that `spender` will be\n     * allowed to spend on behalf of `owner` through {transferFrom}. This is\n     * zero by default.\n     *\n     * This value changes when {approve} or {transferFrom} are called.\n     */\n    function allowance(address owner, address spender) external view returns (uint256);\n\n    /**\n     * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\n     *\n     * Returns a boolean value indicating whether the operation succeeded.\n     *\n     * IMPORTANT: Beware that changing an allowance with this method brings the risk\n     * that someone may use both the old and the new allowance by unfortunate\n     * transaction ordering. One possible solution to mitigate this race\n     * condition is to first reduce the spender's allowance to 0 and set the\n     * desired value afterwards:\n     * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\n     *\n     * Emits an {Approval} event.\n     */\n    function approve(address spender, uint256 amount) external returns (bool);\n\n    /**\n     * @dev Moves `amount` tokens from `from` to `to` using the\n     * allowance mechanism. `amount` is then deducted from the caller's\n     * allowance.\n     *\n     * Returns a boolean value indicating whether the operation succeeded.\n     *\n     * Emits a {Transfer} event.\n     */\n    function transferFrom(address from, address to, uint256 amount) external returns (bool);\n}\n"},"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol":{"content":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.3) (token/ERC20/utils/SafeERC20.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC20.sol\";\nimport \"../extensions/IERC20Permit.sol\";\nimport \"../../../utils/Address.sol\";\n\n/**\n * @title SafeERC20\n * @dev Wrappers around ERC20 operations that throw on failure (when the token\n * contract returns false). Tokens that return no value (and instead revert or\n * throw on failure) are also supported, non-reverting calls are assumed to be\n * successful.\n * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,\n * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\n */\nlibrary SafeERC20 {\n    using Address for address;\n\n    /**\n     * @dev Transfer `value` amount of `token` from the calling contract to `to`. If `token` returns no value,\n     * non-reverting calls are assumed to be successful.\n     */\n    function safeTransfer(IERC20 token, address to, uint256 value) internal {\n        _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\n    }\n\n    /**\n     * @dev Transfer `value` amount of `token` from `from` to `to`, spending the approval given by `from` to the\n     * calling contract. If `token` returns no value, non-reverting calls are assumed to be successful.\n     */\n    function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal {\n        _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));\n    }\n\n    /**\n     * @dev Deprecated. This function has issues similar to the ones found in\n     * {IERC20-approve}, and its usage is discouraged.\n     *\n     * Whenever possible, use {safeIncreaseAllowance} and\n     * {safeDecreaseAllowance} instead.\n     */\n    function safeApprove(IERC20 token, address spender, uint256 value) internal {\n        // safeApprove should only be called when setting an initial allowance,\n        // or when resetting it to zero. To increase and decrease it, use\n        // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'\n        require(\n            (value == 0) || (token.allowance(address(this), spender) == 0),\n            \"SafeERC20: approve from non-zero to non-zero allowance\"\n        );\n        _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));\n    }\n\n    /**\n     * @dev Increase the calling contract's allowance toward `spender` by `value`. If `token` returns no value,\n     * non-reverting calls are assumed to be successful.\n     */\n    function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal {\n        uint256 oldAllowance = token.allowance(address(this), spender);\n        _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance + value));\n    }\n\n    /**\n     * @dev Decrease the calling contract's allowance toward `spender` by `value`. If `token` returns no value,\n     * non-reverting calls are assumed to be successful.\n     */\n    function safeDecreaseAllowance(IERC20 token, address spender, uint256 value) internal {\n        unchecked {\n            uint256 oldAllowance = token.allowance(address(this), spender);\n            require(oldAllowance >= value, \"SafeERC20: decreased allowance below zero\");\n            _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance - value));\n        }\n    }\n\n    /**\n     * @dev Set the calling contract's allowance toward `spender` to `value`. If `token` returns no value,\n     * non-reverting calls are assumed to be successful. Meant to be used with tokens that require the approval\n     * to be set to zero before setting it to a non-zero value, such as USDT.\n     */\n    function forceApprove(IERC20 token, address spender, uint256 value) internal {\n        bytes memory approvalCall = abi.encodeWithSelector(token.approve.selector, spender, value);\n\n        if (!_callOptionalReturnBool(token, approvalCall)) {\n            _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, 0));\n            _callOptionalReturn(token, approvalCall);\n        }\n    }\n\n    /**\n     * @dev Use a ERC-2612 signature to set the `owner` approval toward `spender` on `token`.\n     * Revert on invalid signature.\n     */\n    function safePermit(\n        IERC20Permit token,\n        address owner,\n        address spender,\n        uint256 value,\n        uint256 deadline,\n        uint8 v,\n        bytes32 r,\n        bytes32 s\n    ) internal {\n        uint256 nonceBefore = token.nonces(owner);\n        token.permit(owner, spender, value, deadline, v, r, s);\n        uint256 nonceAfter = token.nonces(owner);\n        require(nonceAfter == nonceBefore + 1, \"SafeERC20: permit did not succeed\");\n    }\n\n    /**\n     * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\n     * on the return value: the return value is optional (but if data is returned, it must not be false).\n     * @param token The token targeted by the call.\n     * @param data The call data (encoded using abi.encode or one of its variants).\n     */\n    function _callOptionalReturn(IERC20 token, bytes memory data) private {\n        // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\n        // we're implementing it ourselves. We use {Address-functionCall} to perform this call, which verifies that\n        // the target address contains contract code and also asserts for success in the low-level call.\n\n        bytes memory returndata = address(token).functionCall(data, \"SafeERC20: low-level call failed\");\n        require(returndata.length == 0 || abi.decode(returndata, (bool)), \"SafeERC20: ERC20 operation did not succeed\");\n    }\n\n    /**\n     * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\n     * on the return value: the return value is optional (but if data is returned, it must not be false).\n     * @param token The token targeted by the call.\n     * @param data The call data (encoded using abi.encode or one of its variants).\n     *\n     * This is a variant of {_callOptionalReturn} that silents catches all reverts and returns a bool instead.\n     */\n    function _callOptionalReturnBool(IERC20 token, bytes memory data) private returns (bool) {\n        // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\n        // we're implementing it ourselves. We cannot use {Address-functionCall} here since this should return false\n        // and not revert is the subcall reverts.\n\n        (bool success, bytes memory returndata) = address(token).call(data);\n        return\n            success && (returndata.length == 0 || abi.decode(returndata, (bool))) && Address.isContract(address(token));\n    }\n}\n"},"@openzeppelin/contracts/token/ERC721/ERC721.sol":{"content":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC721/ERC721.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC721.sol\";\nimport \"./IERC721Receiver.sol\";\nimport \"./extensions/IERC721Metadata.sol\";\nimport \"../../utils/Address.sol\";\nimport \"../../utils/Context.sol\";\nimport \"../../utils/Strings.sol\";\nimport \"../../utils/introspection/ERC165.sol\";\n\n/**\n * @dev Implementation of https://eips.ethereum.org/EIPS/eip-721[ERC721] Non-Fungible Token Standard, including\n * the Metadata extension, but not including the Enumerable extension, which is available separately as\n * {ERC721Enumerable}.\n */\ncontract ERC721 is Context, ERC165, IERC721, IERC721Metadata {\n    using Address for address;\n    using Strings for uint256;\n\n    // Token name\n    string private _name;\n\n    // Token symbol\n    string private _symbol;\n\n    // Mapping from token ID to owner address\n    mapping(uint256 => address) private _owners;\n\n    // Mapping owner address to token count\n    mapping(address => uint256) private _balances;\n\n    // Mapping from token ID to approved address\n    mapping(uint256 => address) private _tokenApprovals;\n\n    // Mapping from owner to operator approvals\n    mapping(address => mapping(address => bool)) private _operatorApprovals;\n\n    /**\n     * @dev Initializes the contract by setting a `name` and a `symbol` to the token collection.\n     */\n    constructor(string memory name_, string memory symbol_) {\n        _name = name_;\n        _symbol = symbol_;\n    }\n\n    /**\n     * @dev See {IERC165-supportsInterface}.\n     */\n    function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165, IERC165) returns (bool) {\n        return\n            interfaceId == type(IERC721).interfaceId ||\n            interfaceId == type(IERC721Metadata).interfaceId ||\n            super.supportsInterface(interfaceId);\n    }\n\n    /**\n     * @dev See {IERC721-balanceOf}.\n     */\n    function balanceOf(address owner) public view virtual override returns (uint256) {\n        require(owner != address(0), \"ERC721: address zero is not a valid owner\");\n        return _balances[owner];\n    }\n\n    /**\n     * @dev See {IERC721-ownerOf}.\n     */\n    function ownerOf(uint256 tokenId) public view virtual override returns (address) {\n        address owner = _ownerOf(tokenId);\n        require(owner != address(0), \"ERC721: invalid token ID\");\n        return owner;\n    }\n\n    /**\n     * @dev See {IERC721Metadata-name}.\n     */\n    function name() public view virtual override returns (string memory) {\n        return _name;\n    }\n\n    /**\n     * @dev See {IERC721Metadata-symbol}.\n     */\n    function symbol() public view virtual override returns (string memory) {\n        return _symbol;\n    }\n\n    /**\n     * @dev See {IERC721Metadata-tokenURI}.\n     */\n    function tokenURI(uint256 tokenId) public view virtual override returns (string memory) {\n        _requireMinted(tokenId);\n\n        string memory baseURI = _baseURI();\n        return bytes(baseURI).length > 0 ? string(abi.encodePacked(baseURI, tokenId.toString())) : \"\";\n    }\n\n    /**\n     * @dev Base URI for computing {tokenURI}. If set, the resulting URI for each\n     * token will be the concatenation of the `baseURI` and the `tokenId`. Empty\n     * by default, can be overridden in child contracts.\n     */\n    function _baseURI() internal view virtual returns (string memory) {\n        return \"\";\n    }\n\n    /**\n     * @dev See {IERC721-approve}.\n     */\n    function approve(address to, uint256 tokenId) public virtual override {\n        address owner = ERC721.ownerOf(tokenId);\n        require(to != owner, \"ERC721: approval to current owner\");\n\n        require(\n            _msgSender() == owner || isApprovedForAll(owner, _msgSender()),\n            \"ERC721: approve caller is not token owner or approved for all\"\n        );\n\n        _approve(to, tokenId);\n    }\n\n    /**\n     * @dev See {IERC721-getApproved}.\n     */\n    function getApproved(uint256 tokenId) public view virtual override returns (address) {\n        _requireMinted(tokenId);\n\n        return _tokenApprovals[tokenId];\n    }\n\n    /**\n     * @dev See {IERC721-setApprovalForAll}.\n     */\n    function setApprovalForAll(address operator, bool approved) public virtual override {\n        _setApprovalForAll(_msgSender(), operator, approved);\n    }\n\n    /**\n     * @dev See {IERC721-isApprovedForAll}.\n     */\n    function isApprovedForAll(address owner, address operator) public view virtual override returns (bool) {\n        return _operatorApprovals[owner][operator];\n    }\n\n    /**\n     * @dev See {IERC721-transferFrom}.\n     */\n    function transferFrom(address from, address to, uint256 tokenId) public virtual override {\n        //solhint-disable-next-line max-line-length\n        require(_isApprovedOrOwner(_msgSender(), tokenId), \"ERC721: caller is not token owner or approved\");\n\n        _transfer(from, to, tokenId);\n    }\n\n    /**\n     * @dev See {IERC721-safeTransferFrom}.\n     */\n    function safeTransferFrom(address from, address to, uint256 tokenId) public virtual override {\n        safeTransferFrom(from, to, tokenId, \"\");\n    }\n\n    /**\n     * @dev See {IERC721-safeTransferFrom}.\n     */\n    function safeTransferFrom(address from, address to, uint256 tokenId, bytes memory data) public virtual override {\n        require(_isApprovedOrOwner(_msgSender(), tokenId), \"ERC721: caller is not token owner or approved\");\n        _safeTransfer(from, to, tokenId, data);\n    }\n\n    /**\n     * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients\n     * are aware of the ERC721 protocol to prevent tokens from being forever locked.\n     *\n     * `data` is additional data, it has no specified format and it is sent in call to `to`.\n     *\n     * This internal function is equivalent to {safeTransferFrom}, and can be used to e.g.\n     * implement alternative mechanisms to perform token transfer, such as signature-based.\n     *\n     * Requirements:\n     *\n     * - `from` cannot be the zero address.\n     * - `to` cannot be the zero address.\n     * - `tokenId` token must exist and be owned by `from`.\n     * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n     *\n     * Emits a {Transfer} event.\n     */\n    function _safeTransfer(address from, address to, uint256 tokenId, bytes memory data) internal virtual {\n        _transfer(from, to, tokenId);\n        require(_checkOnERC721Received(from, to, tokenId, data), \"ERC721: transfer to non ERC721Receiver implementer\");\n    }\n\n    /**\n     * @dev Returns the owner of the `tokenId`. Does NOT revert if token doesn't exist\n     */\n    function _ownerOf(uint256 tokenId) internal view virtual returns (address) {\n        return _owners[tokenId];\n    }\n\n    /**\n     * @dev Returns whether `tokenId` exists.\n     *\n     * Tokens can be managed by their owner or approved accounts via {approve} or {setApprovalForAll}.\n     *\n     * Tokens start existing when they are minted (`_mint`),\n     * and stop existing when they are burned (`_burn`).\n     */\n    function _exists(uint256 tokenId) internal view virtual returns (bool) {\n        return _ownerOf(tokenId) != address(0);\n    }\n\n    /**\n     * @dev Returns whether `spender` is allowed to manage `tokenId`.\n     *\n     * Requirements:\n     *\n     * - `tokenId` must exist.\n     */\n    function _isApprovedOrOwner(address spender, uint256 tokenId) internal view virtual returns (bool) {\n        address owner = ERC721.ownerOf(tokenId);\n        return (spender == owner || isApprovedForAll(owner, spender) || getApproved(tokenId) == spender);\n    }\n\n    /**\n     * @dev Safely mints `tokenId` and transfers it to `to`.\n     *\n     * Requirements:\n     *\n     * - `tokenId` must not exist.\n     * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n     *\n     * Emits a {Transfer} event.\n     */\n    function _safeMint(address to, uint256 tokenId) internal virtual {\n        _safeMint(to, tokenId, \"\");\n    }\n\n    /**\n     * @dev Same as {xref-ERC721-_safeMint-address-uint256-}[`_safeMint`], with an additional `data` parameter which is\n     * forwarded in {IERC721Receiver-onERC721Received} to contract recipients.\n     */\n    function _safeMint(address to, uint256 tokenId, bytes memory data) internal virtual {\n        _mint(to, tokenId);\n        require(\n            _checkOnERC721Received(address(0), to, tokenId, data),\n            \"ERC721: transfer to non ERC721Receiver implementer\"\n        );\n    }\n\n    /**\n     * @dev Mints `tokenId` and transfers it to `to`.\n     *\n     * WARNING: Usage of this method is discouraged, use {_safeMint} whenever possible\n     *\n     * Requirements:\n     *\n     * - `tokenId` must not exist.\n     * - `to` cannot be the zero address.\n     *\n     * Emits a {Transfer} event.\n     */\n    function _mint(address to, uint256 tokenId) internal virtual {\n        require(to != address(0), \"ERC721: mint to the zero address\");\n        require(!_exists(tokenId), \"ERC721: token already minted\");\n\n        _beforeTokenTransfer(address(0), to, tokenId, 1);\n\n        // Check that tokenId was not minted by `_beforeTokenTransfer` hook\n        require(!_exists(tokenId), \"ERC721: token already minted\");\n\n        unchecked {\n            // Will not overflow unless all 2**256 token ids are minted to the same owner.\n            // Given that tokens are minted one by one, it is impossible in practice that\n            // this ever happens. Might change if we allow batch minting.\n            // The ERC fails to describe this case.\n            _balances[to] += 1;\n        }\n\n        _owners[tokenId] = to;\n\n        emit Transfer(address(0), to, tokenId);\n\n        _afterTokenTransfer(address(0), to, tokenId, 1);\n    }\n\n    /**\n     * @dev Destroys `tokenId`.\n     * The approval is cleared when the token is burned.\n     * This is an internal function that does not check if the sender is authorized to operate on the token.\n     *\n     * Requirements:\n     *\n     * - `tokenId` must exist.\n     *\n     * Emits a {Transfer} event.\n     */\n    function _burn(uint256 tokenId) internal virtual {\n        address owner = ERC721.ownerOf(tokenId);\n\n        _beforeTokenTransfer(owner, address(0), tokenId, 1);\n\n        // Update ownership in case tokenId was transferred by `_beforeTokenTransfer` hook\n        owner = ERC721.ownerOf(tokenId);\n\n        // Clear approvals\n        delete _tokenApprovals[tokenId];\n\n        unchecked {\n            // Cannot overflow, as that would require more tokens to be burned/transferred\n            // out than the owner initially received through minting and transferring in.\n            _balances[owner] -= 1;\n        }\n        delete _owners[tokenId];\n\n        emit Transfer(owner, address(0), tokenId);\n\n        _afterTokenTransfer(owner, address(0), tokenId, 1);\n    }\n\n    /**\n     * @dev Transfers `tokenId` from `from` to `to`.\n     *  As opposed to {transferFrom}, this imposes no restrictions on msg.sender.\n     *\n     * Requirements:\n     *\n     * - `to` cannot be the zero address.\n     * - `tokenId` token must be owned by `from`.\n     *\n     * Emits a {Transfer} event.\n     */\n    function _transfer(address from, address to, uint256 tokenId) internal virtual {\n        require(ERC721.ownerOf(tokenId) == from, \"ERC721: transfer from incorrect owner\");\n        require(to != address(0), \"ERC721: transfer to the zero address\");\n\n        _beforeTokenTransfer(from, to, tokenId, 1);\n\n        // Check that tokenId was not transferred by `_beforeTokenTransfer` hook\n        require(ERC721.ownerOf(tokenId) == from, \"ERC721: transfer from incorrect owner\");\n\n        // Clear approvals from the previous owner\n        delete _tokenApprovals[tokenId];\n\n        unchecked {\n            // `_balances[from]` cannot overflow for the same reason as described in `_burn`:\n            // `from`'s balance is the number of token held, which is at least one before the current\n            // transfer.\n            // `_balances[to]` could overflow in the conditions described in `_mint`. That would require\n            // all 2**256 token ids to be minted, which in practice is impossible.\n            _balances[from] -= 1;\n            _balances[to] += 1;\n        }\n        _owners[tokenId] = to;\n\n        emit Transfer(from, to, tokenId);\n\n        _afterTokenTransfer(from, to, tokenId, 1);\n    }\n\n    /**\n     * @dev Approve `to` to operate on `tokenId`\n     *\n     * Emits an {Approval} event.\n     */\n    function _approve(address to, uint256 tokenId) internal virtual {\n        _tokenApprovals[tokenId] = to;\n        emit Approval(ERC721.ownerOf(tokenId), to, tokenId);\n    }\n\n    /**\n     * @dev Approve `operator` to operate on all of `owner` tokens\n     *\n     * Emits an {ApprovalForAll} event.\n     */\n    function _setApprovalForAll(address owner, address operator, bool approved) internal virtual {\n        require(owner != operator, \"ERC721: approve to caller\");\n        _operatorApprovals[owner][operator] = approved;\n        emit ApprovalForAll(owner, operator, approved);\n    }\n\n    /**\n     * @dev Reverts if the `tokenId` has not been minted yet.\n     */\n    function _requireMinted(uint256 tokenId) internal view virtual {\n        require(_exists(tokenId), \"ERC721: invalid token ID\");\n    }\n\n    /**\n     * @dev Internal function to invoke {IERC721Receiver-onERC721Received} on a target address.\n     * The call is not executed if the target address is not a contract.\n     *\n     * @param from address representing the previous owner of the given token ID\n     * @param to target address that will receive the tokens\n     * @param tokenId uint256 ID of the token to be transferred\n     * @param data bytes optional data to send along with the call\n     * @return bool whether the call correctly returned the expected magic value\n     */\n    function _checkOnERC721Received(\n        address from,\n        address to,\n        uint256 tokenId,\n        bytes memory data\n    ) private returns (bool) {\n        if (to.isContract()) {\n            try IERC721Receiver(to).onERC721Received(_msgSender(), from, tokenId, data) returns (bytes4 retval) {\n                return retval == IERC721Receiver.onERC721Received.selector;\n            } catch (bytes memory reason) {\n                if (reason.length == 0) {\n                    revert(\"ERC721: transfer to non ERC721Receiver implementer\");\n                } else {\n                    /// @solidity memory-safe-assembly\n                    assembly {\n                        revert(add(32, reason), mload(reason))\n                    }\n                }\n            }\n        } else {\n            return true;\n        }\n    }\n\n    /**\n     * @dev Hook that is called before any token transfer. This includes minting and burning. If {ERC721Consecutive} is\n     * used, the hook may be called as part of a consecutive (batch) mint, as indicated by `batchSize` greater than 1.\n     *\n     * Calling conditions:\n     *\n     * - When `from` and `to` are both non-zero, ``from``'s tokens will be transferred to `to`.\n     * - When `from` is zero, the tokens will be minted for `to`.\n     * - When `to` is zero, ``from``'s tokens will be burned.\n     * - `from` and `to` are never both zero.\n     * - `batchSize` is non-zero.\n     *\n     * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n     */\n    function _beforeTokenTransfer(address from, address to, uint256 firstTokenId, uint256 batchSize) internal virtual {}\n\n    /**\n     * @dev Hook that is called after any token transfer. This includes minting and burning. If {ERC721Consecutive} is\n     * used, the hook may be called as part of a consecutive (batch) mint, as indicated by `batchSize` greater than 1.\n     *\n     * Calling conditions:\n     *\n     * - When `from` and `to` are both non-zero, ``from``'s tokens were transferred to `to`.\n     * - When `from` is zero, the tokens were minted for `to`.\n     * - When `to` is zero, ``from``'s tokens were burned.\n     * - `from` and `to` are never both zero.\n     * - `batchSize` is non-zero.\n     *\n     * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n     */\n    function _afterTokenTransfer(address from, address to, uint256 firstTokenId, uint256 batchSize) internal virtual {}\n\n    /**\n     * @dev Unsafe write access to the balances, used by extensions that \"mint\" tokens using an {ownerOf} override.\n     *\n     * WARNING: Anyone calling this MUST ensure that the balances remain consistent with the ownership. The invariant\n     * being that for any address `a` the value returned by `balanceOf(a)` must be equal to the number of tokens such\n     * that `ownerOf(tokenId)` is `a`.\n     */\n    // solhint-disable-next-line func-name-mixedcase\n    function __unsafe_increaseBalance(address account, uint256 amount) internal {\n        _balances[account] += amount;\n    }\n}\n"},"@openzeppelin/contracts/token/ERC721/extensions/ERC721Enumerable.sol":{"content":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.8.0) (token/ERC721/extensions/ERC721Enumerable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../ERC721.sol\";\nimport \"./IERC721Enumerable.sol\";\n\n/**\n * @dev This implements an optional extension of {ERC721} defined in the EIP that adds\n * enumerability of all the token ids in the contract as well as all token ids owned by each\n * account.\n */\nabstract contract ERC721Enumerable is ERC721, IERC721Enumerable {\n    // Mapping from owner to list of owned token IDs\n    mapping(address => mapping(uint256 => uint256)) private _ownedTokens;\n\n    // Mapping from token ID to index of the owner tokens list\n    mapping(uint256 => uint256) private _ownedTokensIndex;\n\n    // Array with all token ids, used for enumeration\n    uint256[] private _allTokens;\n\n    // Mapping from token id to position in the allTokens array\n    mapping(uint256 => uint256) private _allTokensIndex;\n\n    /**\n     * @dev See {IERC165-supportsInterface}.\n     */\n    function supportsInterface(bytes4 interfaceId) public view virtual override(IERC165, ERC721) returns (bool) {\n        return interfaceId == type(IERC721Enumerable).interfaceId || super.supportsInterface(interfaceId);\n    }\n\n    /**\n     * @dev See {IERC721Enumerable-tokenOfOwnerByIndex}.\n     */\n    function tokenOfOwnerByIndex(address owner, uint256 index) public view virtual override returns (uint256) {\n        require(index < ERC721.balanceOf(owner), \"ERC721Enumerable: owner index out of bounds\");\n        return _ownedTokens[owner][index];\n    }\n\n    /**\n     * @dev See {IERC721Enumerable-totalSupply}.\n     */\n    function totalSupply() public view virtual override returns (uint256) {\n        return _allTokens.length;\n    }\n\n    /**\n     * @dev See {IERC721Enumerable-tokenByIndex}.\n     */\n    function tokenByIndex(uint256 index) public view virtual override returns (uint256) {\n        require(index < ERC721Enumerable.totalSupply(), \"ERC721Enumerable: global index out of bounds\");\n        return _allTokens[index];\n    }\n\n    /**\n     * @dev See {ERC721-_beforeTokenTransfer}.\n     */\n    function _beforeTokenTransfer(\n        address from,\n        address to,\n        uint256 firstTokenId,\n        uint256 batchSize\n    ) internal virtual override {\n        super._beforeTokenTransfer(from, to, firstTokenId, batchSize);\n\n        if (batchSize > 1) {\n            // Will only trigger during construction. Batch transferring (minting) is not available afterwards.\n            revert(\"ERC721Enumerable: consecutive transfers not supported\");\n        }\n\n        uint256 tokenId = firstTokenId;\n\n        if (from == address(0)) {\n            _addTokenToAllTokensEnumeration(tokenId);\n        } else if (from != to) {\n            _removeTokenFromOwnerEnumeration(from, tokenId);\n        }\n        if (to == address(0)) {\n            _removeTokenFromAllTokensEnumeration(tokenId);\n        } else if (to != from) {\n            _addTokenToOwnerEnumeration(to, tokenId);\n        }\n    }\n\n    /**\n     * @dev Private function to add a token to this extension's ownership-tracking data structures.\n     * @param to address representing the new owner of the given token ID\n     * @param tokenId uint256 ID of the token to be added to the tokens list of the given address\n     */\n    function _addTokenToOwnerEnumeration(address to, uint256 tokenId) private {\n        uint256 length = ERC721.balanceOf(to);\n        _ownedTokens[to][length] = tokenId;\n        _ownedTokensIndex[tokenId] = length;\n    }\n\n    /**\n     * @dev Private function to add a token to this extension's token tracking data structures.\n     * @param tokenId uint256 ID of the token to be added to the tokens list\n     */\n    function _addTokenToAllTokensEnumeration(uint256 tokenId) private {\n        _allTokensIndex[tokenId] = _allTokens.length;\n        _allTokens.push(tokenId);\n    }\n\n    /**\n     * @dev Private function to remove a token from this extension's ownership-tracking data structures. Note that\n     * while the token is not assigned a new owner, the `_ownedTokensIndex` mapping is _not_ updated: this allows for\n     * gas optimizations e.g. when performing a transfer operation (avoiding double writes).\n     * This has O(1) time complexity, but alters the order of the _ownedTokens array.\n     * @param from address representing the previous owner of the given token ID\n     * @param tokenId uint256 ID of the token to be removed from the tokens list of the given address\n     */\n    function _removeTokenFromOwnerEnumeration(address from, uint256 tokenId) private {\n        // To prevent a gap in from's tokens array, we store the last token in the index of the token to delete, and\n        // then delete the last slot (swap and pop).\n\n        uint256 lastTokenIndex = ERC721.balanceOf(from) - 1;\n        uint256 tokenIndex = _ownedTokensIndex[tokenId];\n\n        // When the token to delete is the last token, the swap operation is unnecessary\n        if (tokenIndex != lastTokenIndex) {\n            uint256 lastTokenId = _ownedTokens[from][lastTokenIndex];\n\n            _ownedTokens[from][tokenIndex] = lastTokenId; // Move the last token to the slot of the to-delete token\n            _ownedTokensIndex[lastTokenId] = tokenIndex; // Update the moved token's index\n        }\n\n        // This also deletes the contents at the last position of the array\n        delete _ownedTokensIndex[tokenId];\n        delete _ownedTokens[from][lastTokenIndex];\n    }\n\n    /**\n     * @dev Private function to remove a token from this extension's token tracking data structures.\n     * This has O(1) time complexity, but alters the order of the _allTokens array.\n     * @param tokenId uint256 ID of the token to be removed from the tokens list\n     */\n    function _removeTokenFromAllTokensEnumeration(uint256 tokenId) private {\n        // To prevent a gap in the tokens array, we store the last token in the index of the token to delete, and\n        // then delete the last slot (swap and pop).\n\n        uint256 lastTokenIndex = _allTokens.length - 1;\n        uint256 tokenIndex = _allTokensIndex[tokenId];\n\n        // When the token to delete is the last token, the swap operation is unnecessary. However, since this occurs so\n        // rarely (when the last minted token is burnt) that we still do the swap here to avoid the gas cost of adding\n        // an 'if' statement (like in _removeTokenFromOwnerEnumeration)\n        uint256 lastTokenId = _allTokens[lastTokenIndex];\n\n        _allTokens[tokenIndex] = lastTokenId; // Move the last token to the slot of the to-delete token\n        _allTokensIndex[lastTokenId] = tokenIndex; // Update the moved token's index\n\n        // This also deletes the contents at the last position of the array\n        delete _allTokensIndex[tokenId];\n        _allTokens.pop();\n    }\n}\n"},"@openzeppelin/contracts/token/ERC721/extensions/IERC721Enumerable.sol":{"content":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC721/extensions/IERC721Enumerable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC721.sol\";\n\n/**\n * @title ERC-721 Non-Fungible Token Standard, optional enumeration extension\n * @dev See https://eips.ethereum.org/EIPS/eip-721\n */\ninterface IERC721Enumerable is IERC721 {\n    /**\n     * @dev Returns the total amount of tokens stored by the contract.\n     */\n    function totalSupply() external view returns (uint256);\n\n    /**\n     * @dev Returns a token ID owned by `owner` at a given `index` of its token list.\n     * Use along with {balanceOf} to enumerate all of ``owner``'s tokens.\n     */\n    function tokenOfOwnerByIndex(address owner, uint256 index) external view returns (uint256);\n\n    /**\n     * @dev Returns a token ID at a given `index` of all the tokens stored by the contract.\n     * Use along with {totalSupply} to enumerate all tokens.\n     */\n    function tokenByIndex(uint256 index) external view returns (uint256);\n}\n"},"@openzeppelin/contracts/token/ERC721/extensions/IERC721Metadata.sol":{"content":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC721/extensions/IERC721Metadata.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC721.sol\";\n\n/**\n * @title ERC-721 Non-Fungible Token Standard, optional metadata extension\n * @dev See https://eips.ethereum.org/EIPS/eip-721\n */\ninterface IERC721Metadata is IERC721 {\n    /**\n     * @dev Returns the token collection name.\n     */\n    function name() external view returns (string memory);\n\n    /**\n     * @dev Returns the token collection symbol.\n     */\n    function symbol() external view returns (string memory);\n\n    /**\n     * @dev Returns the Uniform Resource Identifier (URI) for `tokenId` token.\n     */\n    function tokenURI(uint256 tokenId) external view returns (string memory);\n}\n"},"@openzeppelin/contracts/token/ERC721/IERC721.sol":{"content":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC721/IERC721.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../../utils/introspection/IERC165.sol\";\n\n/**\n * @dev Required interface of an ERC721 compliant contract.\n */\ninterface IERC721 is IERC165 {\n    /**\n     * @dev Emitted when `tokenId` token is transferred from `from` to `to`.\n     */\n    event Transfer(address indexed from, address indexed to, uint256 indexed tokenId);\n\n    /**\n     * @dev Emitted when `owner` enables `approved` to manage the `tokenId` token.\n     */\n    event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId);\n\n    /**\n     * @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets.\n     */\n    event ApprovalForAll(address indexed owner, address indexed operator, bool approved);\n\n    /**\n     * @dev Returns the number of tokens in ``owner``'s account.\n     */\n    function balanceOf(address owner) external view returns (uint256 balance);\n\n    /**\n     * @dev Returns the owner of the `tokenId` token.\n     *\n     * Requirements:\n     *\n     * - `tokenId` must exist.\n     */\n    function ownerOf(uint256 tokenId) external view returns (address owner);\n\n    /**\n     * @dev Safely transfers `tokenId` token from `from` to `to`.\n     *\n     * Requirements:\n     *\n     * - `from` cannot be the zero address.\n     * - `to` cannot be the zero address.\n     * - `tokenId` token must exist and be owned by `from`.\n     * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\n     * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n     *\n     * Emits a {Transfer} event.\n     */\n    function safeTransferFrom(address from, address to, uint256 tokenId, bytes calldata data) external;\n\n    /**\n     * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients\n     * are aware of the ERC721 protocol to prevent tokens from being forever locked.\n     *\n     * Requirements:\n     *\n     * - `from` cannot be the zero address.\n     * - `to` cannot be the zero address.\n     * - `tokenId` token must exist and be owned by `from`.\n     * - If the caller is not `from`, it must have been allowed to move this token by either {approve} or {setApprovalForAll}.\n     * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n     *\n     * Emits a {Transfer} event.\n     */\n    function safeTransferFrom(address from, address to, uint256 tokenId) external;\n\n    /**\n     * @dev Transfers `tokenId` token from `from` to `to`.\n     *\n     * WARNING: Note that the caller is responsible to confirm that the recipient is capable of receiving ERC721\n     * or else they may be permanently lost. Usage of {safeTransferFrom} prevents loss, though the caller must\n     * understand this adds an external call which potentially creates a reentrancy vulnerability.\n     *\n     * Requirements:\n     *\n     * - `from` cannot be the zero address.\n     * - `to` cannot be the zero address.\n     * - `tokenId` token must be owned by `from`.\n     * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\n     *\n     * Emits a {Transfer} event.\n     */\n    function transferFrom(address from, address to, uint256 tokenId) external;\n\n    /**\n     * @dev Gives permission to `to` to transfer `tokenId` token to another account.\n     * The approval is cleared when the token is transferred.\n     *\n     * Only a single account can be approved at a time, so approving the zero address clears previous approvals.\n     *\n     * Requirements:\n     *\n     * - The caller must own the token or be an approved operator.\n     * - `tokenId` must exist.\n     *\n     * Emits an {Approval} event.\n     */\n    function approve(address to, uint256 tokenId) external;\n\n    /**\n     * @dev Approve or remove `operator` as an operator for the caller.\n     * Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller.\n     *\n     * Requirements:\n     *\n     * - The `operator` cannot be the caller.\n     *\n     * Emits an {ApprovalForAll} event.\n     */\n    function setApprovalForAll(address operator, bool approved) external;\n\n    /**\n     * @dev Returns the account approved for `tokenId` token.\n     *\n     * Requirements:\n     *\n     * - `tokenId` must exist.\n     */\n    function getApproved(uint256 tokenId) external view returns (address operator);\n\n    /**\n     * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`.\n     *\n     * See {setApprovalForAll}\n     */\n    function isApprovedForAll(address owner, address operator) external view returns (bool);\n}\n"},"@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol":{"content":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC721/IERC721Receiver.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @title ERC721 token receiver interface\n * @dev Interface for any contract that wants to support safeTransfers\n * from ERC721 asset contracts.\n */\ninterface IERC721Receiver {\n    /**\n     * @dev Whenever an {IERC721} `tokenId` token is transferred to this contract via {IERC721-safeTransferFrom}\n     * by `operator` from `from`, this function is called.\n     *\n     * It must return its Solidity selector to confirm the token transfer.\n     * If any other value is returned or the interface is not implemented by the recipient, the transfer will be reverted.\n     *\n     * The selector can be obtained in Solidity with `IERC721Receiver.onERC721Received.selector`.\n     */\n    function onERC721Received(\n        address operator,\n        address from,\n        uint256 tokenId,\n        bytes calldata data\n    ) external returns (bytes4);\n}\n"},"@openzeppelin/contracts/utils/Address.sol":{"content":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/Address.sol)\n\npragma solidity ^0.8.1;\n\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary Address {\n    /**\n     * @dev Returns true if `account` is a contract.\n     *\n     * [IMPORTANT]\n     * ====\n     * It is unsafe to assume that an address for which this function returns\n     * false is an externally-owned account (EOA) and not a contract.\n     *\n     * Among others, `isContract` will return false for the following\n     * types of addresses:\n     *\n     *  - an externally-owned account\n     *  - a contract in construction\n     *  - an address where a contract will be created\n     *  - an address where a contract lived, but was destroyed\n     *\n     * Furthermore, `isContract` will also return true if the target contract within\n     * the same transaction is already scheduled for destruction by `SELFDESTRUCT`,\n     * which only has an effect at the end of a transaction.\n     * ====\n     *\n     * [IMPORTANT]\n     * ====\n     * You shouldn't rely on `isContract` to protect against flash loan attacks!\n     *\n     * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n     * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n     * constructor.\n     * ====\n     */\n    function isContract(address account) internal view returns (bool) {\n        // This method relies on extcodesize/address.code.length, which returns 0\n        // for contracts in construction, since the code is only stored at the end\n        // of the constructor execution.\n\n        return account.code.length > 0;\n    }\n\n    /**\n     * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n     * `recipient`, forwarding all available gas and reverting on errors.\n     *\n     * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n     * of certain opcodes, possibly making contracts go over the 2300 gas limit\n     * imposed by `transfer`, making them unable to receive funds via\n     * `transfer`. {sendValue} removes this limitation.\n     *\n     * https://consensys.net/diligence/blog/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n     *\n     * IMPORTANT: because control is transferred to `recipient`, care must be\n     * taken to not create reentrancy vulnerabilities. Consider using\n     * {ReentrancyGuard} or the\n     * https://solidity.readthedocs.io/en/v0.8.0/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n     */\n    function sendValue(address payable recipient, uint256 amount) internal {\n        require(address(this).balance >= amount, \"Address: insufficient balance\");\n\n        (bool success, ) = recipient.call{value: amount}(\"\");\n        require(success, \"Address: unable to send value, recipient may have reverted\");\n    }\n\n    /**\n     * @dev Performs a Solidity function call using a low level `call`. A\n     * plain `call` is an unsafe replacement for a function call: use this\n     * function instead.\n     *\n     * If `target` reverts with a revert reason, it is bubbled up by this\n     * function (like regular Solidity function calls).\n     *\n     * Returns the raw returned data. To convert to the expected return value,\n     * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n     *\n     * Requirements:\n     *\n     * - `target` must be a contract.\n     * - calling `target` with `data` must not revert.\n     *\n     * _Available since v3.1._\n     */\n    function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n        return functionCallWithValue(target, data, 0, \"Address: low-level call failed\");\n    }\n\n    /**\n     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n     * `errorMessage` as a fallback revert reason when `target` reverts.\n     *\n     * _Available since v3.1._\n     */\n    function functionCall(\n        address target,\n        bytes memory data,\n        string memory errorMessage\n    ) internal returns (bytes memory) {\n        return functionCallWithValue(target, data, 0, errorMessage);\n    }\n\n    /**\n     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n     * but also transferring `value` wei to `target`.\n     *\n     * Requirements:\n     *\n     * - the calling contract must have an ETH balance of at least `value`.\n     * - the called Solidity function must be `payable`.\n     *\n     * _Available since v3.1._\n     */\n    function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {\n        return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n    }\n\n    /**\n     * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n     * with `errorMessage` as a fallback revert reason when `target` reverts.\n     *\n     * _Available since v3.1._\n     */\n    function functionCallWithValue(\n        address target,\n        bytes memory data,\n        uint256 value,\n        string memory errorMessage\n    ) internal returns (bytes memory) {\n        require(address(this).balance >= value, \"Address: insufficient balance for call\");\n        (bool success, bytes memory returndata) = target.call{value: value}(data);\n        return verifyCallResultFromTarget(target, success, returndata, errorMessage);\n    }\n\n    /**\n     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n     * but performing a static call.\n     *\n     * _Available since v3.3._\n     */\n    function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n        return functionStaticCall(target, data, \"Address: low-level static call failed\");\n    }\n\n    /**\n     * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n     * but performing a static call.\n     *\n     * _Available since v3.3._\n     */\n    function functionStaticCall(\n        address target,\n        bytes memory data,\n        string memory errorMessage\n    ) internal view returns (bytes memory) {\n        (bool success, bytes memory returndata) = target.staticcall(data);\n        return verifyCallResultFromTarget(target, success, returndata, errorMessage);\n    }\n\n    /**\n     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n     * but performing a delegate call.\n     *\n     * _Available since v3.4._\n     */\n    function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\n        return functionDelegateCall(target, data, \"Address: low-level delegate call failed\");\n    }\n\n    /**\n     * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n     * but performing a delegate call.\n     *\n     * _Available since v3.4._\n     */\n    function functionDelegateCall(\n        address target,\n        bytes memory data,\n        string memory errorMessage\n    ) internal returns (bytes memory) {\n        (bool success, bytes memory returndata) = target.delegatecall(data);\n        return verifyCallResultFromTarget(target, success, returndata, errorMessage);\n    }\n\n    /**\n     * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling\n     * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract.\n     *\n     * _Available since v4.8._\n     */\n    function verifyCallResultFromTarget(\n        address target,\n        bool success,\n        bytes memory returndata,\n        string memory errorMessage\n    ) internal view returns (bytes memory) {\n        if (success) {\n            if (returndata.length == 0) {\n                // only check isContract if the call was successful and the return data is empty\n                // otherwise we already know that it was a contract\n                require(isContract(target), \"Address: call to non-contract\");\n            }\n            return returndata;\n        } else {\n            _revert(returndata, errorMessage);\n        }\n    }\n\n    /**\n     * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the\n     * revert reason or using the provided one.\n     *\n     * _Available since v4.3._\n     */\n    function verifyCallResult(\n        bool success,\n        bytes memory returndata,\n        string memory errorMessage\n    ) internal pure returns (bytes memory) {\n        if (success) {\n            return returndata;\n        } else {\n            _revert(returndata, errorMessage);\n        }\n    }\n\n    function _revert(bytes memory returndata, string memory errorMessage) private pure {\n        // Look for revert reason and bubble it up if present\n        if (returndata.length > 0) {\n            // The easiest way to bubble the revert reason is using memory via assembly\n            /// @solidity memory-safe-assembly\n            assembly {\n                let returndata_size := mload(returndata)\n                revert(add(32, returndata), returndata_size)\n            }\n        } else {\n            revert(errorMessage);\n        }\n    }\n}\n"},"@openzeppelin/contracts/utils/Context.sol":{"content":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts 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/Create2.sol":{"content":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/Create2.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Helper to make usage of the `CREATE2` EVM opcode easier and safer.\n * `CREATE2` can be used to compute in advance the address where a smart\n * contract will be deployed, which allows for interesting new mechanisms known\n * as 'counterfactual interactions'.\n *\n * See the https://eips.ethereum.org/EIPS/eip-1014#motivation[EIP] for more\n * information.\n */\nlibrary Create2 {\n    /**\n     * @dev Deploys a contract using `CREATE2`. The address where the contract\n     * will be deployed can be known in advance via {computeAddress}.\n     *\n     * The bytecode for a contract can be obtained from Solidity with\n     * `type(contractName).creationCode`.\n     *\n     * Requirements:\n     *\n     * - `bytecode` must not be empty.\n     * - `salt` must have not been used for `bytecode` already.\n     * - the factory must have a balance of at least `amount`.\n     * - if `amount` is non-zero, `bytecode` must have a `payable` constructor.\n     */\n    function deploy(uint256 amount, bytes32 salt, bytes memory bytecode) internal returns (address addr) {\n        require(address(this).balance >= amount, \"Create2: insufficient balance\");\n        require(bytecode.length != 0, \"Create2: bytecode length is zero\");\n        /// @solidity memory-safe-assembly\n        assembly {\n            addr := create2(amount, add(bytecode, 0x20), mload(bytecode), salt)\n        }\n        require(addr != address(0), \"Create2: Failed on deploy\");\n    }\n\n    /**\n     * @dev Returns the address where a contract will be stored if deployed via {deploy}. Any change in the\n     * `bytecodeHash` or `salt` will result in a new destination address.\n     */\n    function computeAddress(bytes32 salt, bytes32 bytecodeHash) internal view returns (address) {\n        return computeAddress(salt, bytecodeHash, address(this));\n    }\n\n    /**\n     * @dev Returns the address where a contract will be stored if deployed via {deploy} from a contract located at\n     * `deployer`. If `deployer` is this contract's address, returns the same value as {computeAddress}.\n     */\n    function computeAddress(bytes32 salt, bytes32 bytecodeHash, address deployer) internal pure returns (address addr) {\n        /// @solidity memory-safe-assembly\n        assembly {\n            let ptr := mload(0x40) // Get free memory pointer\n\n            // |                   | ↓ ptr ...  ↓ ptr + 0x0B (start) ...  ↓ ptr + 0x20 ...  ↓ ptr + 0x40 ...   |\n            // |-------------------|---------------------------------------------------------------------------|\n            // | bytecodeHash      |                                                        CCCCCCCCCCCCC...CC |\n            // | salt              |                                      BBBBBBBBBBBBB...BB                   |\n            // | deployer          | 000000...0000AAAAAAAAAAAAAAAAAAA...AA                                     |\n            // | 0xFF              |            FF                                                             |\n            // |-------------------|---------------------------------------------------------------------------|\n            // | memory            | 000000...00FFAAAAAAAAAAAAAAAAAAA...AABBBBBBBBBBBBB...BBCCCCCCCCCCCCC...CC |\n            // | keccak(start, 85) |            ↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑ |\n\n            mstore(add(ptr, 0x40), bytecodeHash)\n            mstore(add(ptr, 0x20), salt)\n            mstore(ptr, deployer) // Right-aligned with 12 preceding garbage bytes\n            let start := add(ptr, 0x0b) // The hashed data starts at the final garbage byte which we will set to 0xff\n            mstore8(start, 0xff)\n            addr := keccak256(start, 85)\n        }\n    }\n}\n"},"@openzeppelin/contracts/utils/cryptography/ECDSA.sol":{"content":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/cryptography/ECDSA.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../Strings.sol\";\n\n/**\n * @dev Elliptic Curve Digital Signature Algorithm (ECDSA) operations.\n *\n * These functions can be used to verify that a message was signed by the holder\n * of the private keys of a given address.\n */\nlibrary ECDSA {\n    enum RecoverError {\n        NoError,\n        InvalidSignature,\n        InvalidSignatureLength,\n        InvalidSignatureS,\n        InvalidSignatureV // Deprecated in v4.8\n    }\n\n    function _throwError(RecoverError error) private pure {\n        if (error == RecoverError.NoError) {\n            return; // no error: do nothing\n        } else if (error == RecoverError.InvalidSignature) {\n            revert(\"ECDSA: invalid signature\");\n        } else if (error == RecoverError.InvalidSignatureLength) {\n            revert(\"ECDSA: invalid signature length\");\n        } else if (error == RecoverError.InvalidSignatureS) {\n            revert(\"ECDSA: invalid signature 's' value\");\n        }\n    }\n\n    /**\n     * @dev Returns the address that signed a hashed message (`hash`) with\n     * `signature` or error string. This address can then be used for verification purposes.\n     *\n     * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n     * this function rejects them by requiring the `s` value to be in the lower\n     * half order, and the `v` value to be either 27 or 28.\n     *\n     * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n     * verification to be secure: it is possible to craft signatures that\n     * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n     * this is by receiving a hash of the original message (which may otherwise\n     * be too long), and then calling {toEthSignedMessageHash} on it.\n     *\n     * Documentation for signature generation:\n     * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n     * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n     *\n     * _Available since v4.3._\n     */\n    function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n        if (signature.length == 65) {\n            bytes32 r;\n            bytes32 s;\n            uint8 v;\n            // ecrecover takes the signature parameters, and the only way to get them\n            // currently is to use assembly.\n            /// @solidity memory-safe-assembly\n            assembly {\n                r := mload(add(signature, 0x20))\n                s := mload(add(signature, 0x40))\n                v := byte(0, mload(add(signature, 0x60)))\n            }\n            return tryRecover(hash, v, r, s);\n        } else {\n            return (address(0), RecoverError.InvalidSignatureLength);\n        }\n    }\n\n    /**\n     * @dev Returns the address that signed a hashed message (`hash`) with\n     * `signature`. This address can then be used for verification purposes.\n     *\n     * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n     * this function rejects them by requiring the `s` value to be in the lower\n     * half order, and the `v` value to be either 27 or 28.\n     *\n     * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n     * verification to be secure: it is possible to craft signatures that\n     * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n     * this is by receiving a hash of the original message (which may otherwise\n     * be too long), and then calling {toEthSignedMessageHash} on it.\n     */\n    function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n        (address recovered, RecoverError error) = tryRecover(hash, signature);\n        _throwError(error);\n        return recovered;\n    }\n\n    /**\n     * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n     *\n     * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n     *\n     * _Available since v4.3._\n     */\n    function tryRecover(bytes32 hash, bytes32 r, bytes32 vs) internal pure returns (address, RecoverError) {\n        bytes32 s = vs & bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n        uint8 v = uint8((uint256(vs) >> 255) + 27);\n        return tryRecover(hash, v, r, s);\n    }\n\n    /**\n     * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n     *\n     * _Available since v4.2._\n     */\n    function recover(bytes32 hash, bytes32 r, bytes32 vs) internal pure returns (address) {\n        (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n        _throwError(error);\n        return recovered;\n    }\n\n    /**\n     * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n     * `r` and `s` signature fields separately.\n     *\n     * _Available since v4.3._\n     */\n    function tryRecover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) internal pure returns (address, RecoverError) {\n        // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n        // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n        // the valid range for s in (301): 0 < s < secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n        // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n        //\n        // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n        // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n        // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n        // these malleable signatures as well.\n        if (uint256(s) > 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n            return (address(0), RecoverError.InvalidSignatureS);\n        }\n\n        // If the signature is valid (and not malleable), return the signer address\n        address signer = ecrecover(hash, v, r, s);\n        if (signer == address(0)) {\n            return (address(0), RecoverError.InvalidSignature);\n        }\n\n        return (signer, RecoverError.NoError);\n    }\n\n    /**\n     * @dev Overload of {ECDSA-recover} that receives the `v`,\n     * `r` and `s` signature fields separately.\n     */\n    function recover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) internal pure returns (address) {\n        (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n        _throwError(error);\n        return recovered;\n    }\n\n    /**\n     * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n     * produces hash corresponding to the one signed with the\n     * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n     * JSON-RPC method as part of EIP-191.\n     *\n     * See {recover}.\n     */\n    function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32 message) {\n        // 32 is the length in bytes of hash,\n        // enforced by the type signature above\n        /// @solidity memory-safe-assembly\n        assembly {\n            mstore(0x00, \"\\x19Ethereum Signed Message:\\n32\")\n            mstore(0x1c, hash)\n            message := keccak256(0x00, 0x3c)\n        }\n    }\n\n    /**\n     * @dev Returns an Ethereum Signed Message, created from `s`. This\n     * produces hash corresponding to the one signed with the\n     * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n     * JSON-RPC method as part of EIP-191.\n     *\n     * See {recover}.\n     */\n    function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n        return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", Strings.toString(s.length), s));\n    }\n\n    /**\n     * @dev Returns an Ethereum Signed Typed Data, created from a\n     * `domainSeparator` and a `structHash`. This produces hash corresponding\n     * to the one signed with the\n     * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n     * JSON-RPC method as part of EIP-712.\n     *\n     * See {recover}.\n     */\n    function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32 data) {\n        /// @solidity memory-safe-assembly\n        assembly {\n            let ptr := mload(0x40)\n            mstore(ptr, \"\\x19\\x01\")\n            mstore(add(ptr, 0x02), domainSeparator)\n            mstore(add(ptr, 0x22), structHash)\n            data := keccak256(ptr, 0x42)\n        }\n    }\n\n    /**\n     * @dev Returns an Ethereum Signed Data with intended validator, created from a\n     * `validator` and `data` according to the version 0 of EIP-191.\n     *\n     * See {recover}.\n     */\n    function toDataWithIntendedValidatorHash(address validator, bytes memory data) internal pure returns (bytes32) {\n        return keccak256(abi.encodePacked(\"\\x19\\x00\", validator, 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.9.0) (utils/math/Math.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Standard math utilities missing in the Solidity language.\n */\nlibrary Math {\n    enum Rounding {\n        Down, // Toward negative infinity\n        Up, // Toward infinity\n        Zero // Toward zero\n    }\n\n    /**\n     * @dev Returns the largest of two numbers.\n     */\n    function max(uint256 a, uint256 b) internal pure returns (uint256) {\n        return a > b ? a : b;\n    }\n\n    /**\n     * @dev Returns the smallest of two numbers.\n     */\n    function min(uint256 a, uint256 b) internal pure returns (uint256) {\n        return a < b ? a : b;\n    }\n\n    /**\n     * @dev Returns the average of two numbers. The result is rounded towards\n     * zero.\n     */\n    function average(uint256 a, uint256 b) internal pure returns (uint256) {\n        // (a + b) / 2 can overflow.\n        return (a & b) + (a ^ b) / 2;\n    }\n\n    /**\n     * @dev Returns the ceiling of the division of two numbers.\n     *\n     * This differs from standard division with `/` in that it rounds up instead\n     * of rounding down.\n     */\n    function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) {\n        // (a + b - 1) / b can overflow on addition, so we distribute.\n        return a == 0 ? 0 : (a - 1) / b + 1;\n    }\n\n    /**\n     * @notice Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or denominator == 0\n     * @dev Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv)\n     * with further edits by Uniswap Labs also under MIT license.\n     */\n    function mulDiv(uint256 x, uint256 y, uint256 denominator) internal pure returns (uint256 result) {\n        unchecked {\n            // 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use\n            // use the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256\n            // variables such that product = prod1 * 2^256 + prod0.\n            uint256 prod0; // Least significant 256 bits of the product\n            uint256 prod1; // Most significant 256 bits of the product\n            assembly {\n                let mm := mulmod(x, y, not(0))\n                prod0 := mul(x, y)\n                prod1 := sub(sub(mm, prod0), lt(mm, prod0))\n            }\n\n            // Handle non-overflow cases, 256 by 256 division.\n            if (prod1 == 0) {\n                // Solidity will revert if denominator == 0, unlike the div opcode on its own.\n                // The surrounding unchecked block does not change this fact.\n                // See https://docs.soliditylang.org/en/latest/control-structures.html#checked-or-unchecked-arithmetic.\n                return prod0 / denominator;\n            }\n\n            // Make sure the result is less than 2^256. Also prevents denominator == 0.\n            require(denominator > prod1, \"Math: mulDiv overflow\");\n\n            ///////////////////////////////////////////////\n            // 512 by 256 division.\n            ///////////////////////////////////////////////\n\n            // Make division exact by subtracting the remainder from [prod1 prod0].\n            uint256 remainder;\n            assembly {\n                // Compute remainder using mulmod.\n                remainder := mulmod(x, y, denominator)\n\n                // Subtract 256 bit number from 512 bit number.\n                prod1 := sub(prod1, gt(remainder, prod0))\n                prod0 := sub(prod0, remainder)\n            }\n\n            // Factor powers of two out of denominator and compute largest power of two divisor of denominator. Always >= 1.\n            // See https://cs.stackexchange.com/q/138556/92363.\n\n            // Does not overflow because the denominator cannot be zero at this stage in the function.\n            uint256 twos = denominator & (~denominator + 1);\n            assembly {\n                // Divide denominator by twos.\n                denominator := div(denominator, twos)\n\n                // Divide [prod1 prod0] by twos.\n                prod0 := div(prod0, twos)\n\n                // Flip twos such that it is 2^256 / twos. If twos is zero, then it becomes one.\n                twos := add(div(sub(0, twos), twos), 1)\n            }\n\n            // Shift in bits from prod1 into prod0.\n            prod0 |= prod1 * twos;\n\n            // Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such\n            // that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for\n            // four bits. That is, denominator * inv = 1 mod 2^4.\n            uint256 inverse = (3 * denominator) ^ 2;\n\n            // Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also works\n            // in modular arithmetic, doubling the correct bits in each step.\n            inverse *= 2 - denominator * inverse; // inverse mod 2^8\n            inverse *= 2 - denominator * inverse; // inverse mod 2^16\n            inverse *= 2 - denominator * inverse; // inverse mod 2^32\n            inverse *= 2 - denominator * inverse; // inverse mod 2^64\n            inverse *= 2 - denominator * inverse; // inverse mod 2^128\n            inverse *= 2 - denominator * inverse; // inverse mod 2^256\n\n            // Because the division is now exact we can divide by multiplying with the modular inverse of denominator.\n            // This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is\n            // less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1\n            // is no longer required.\n            result = prod0 * inverse;\n            return result;\n        }\n    }\n\n    /**\n     * @notice Calculates x * y / denominator with full precision, following the selected rounding direction.\n     */\n    function mulDiv(uint256 x, uint256 y, uint256 denominator, Rounding rounding) internal pure returns (uint256) {\n        uint256 result = mulDiv(x, y, denominator);\n        if (rounding == Rounding.Up && mulmod(x, y, denominator) > 0) {\n            result += 1;\n        }\n        return result;\n    }\n\n    /**\n     * @dev Returns the square root of a number. If the number is not a perfect square, the value is rounded down.\n     *\n     * Inspired by Henry S. Warren, Jr.'s \"Hacker's Delight\" (Chapter 11).\n     */\n    function sqrt(uint256 a) internal pure returns (uint256) {\n        if (a == 0) {\n            return 0;\n        }\n\n        // For our first guess, we get the biggest power of 2 which is smaller than the square root of the target.\n        //\n        // We know that the \"msb\" (most significant bit) of our target number `a` is a power of 2 such that we have\n        // `msb(a) <= a < 2*msb(a)`. This value can be written `msb(a)=2**k` with `k=log2(a)`.\n        //\n        // This can be rewritten `2**log2(a) <= a < 2**(log2(a) + 1)`\n        // → `sqrt(2**k) <= sqrt(a) < sqrt(2**(k+1))`\n        // → `2**(k/2) <= sqrt(a) < 2**((k+1)/2) <= 2**(k/2 + 1)`\n        //\n        // Consequently, `2**(log2(a) / 2)` is a good first approximation of `sqrt(a)` with at least 1 correct bit.\n        uint256 result = 1 << (log2(a) >> 1);\n\n        // At this point `result` is an estimation with one bit of precision. We know the true value is a uint128,\n        // since it is the square root of a uint256. Newton's method converges quadratically (precision doubles at\n        // every iteration). We thus need at most 7 iteration to turn our partial result with one bit of precision\n        // into the expected uint128 result.\n        unchecked {\n            result = (result + a / result) >> 1;\n            result = (result + a / result) >> 1;\n            result = (result + a / result) >> 1;\n            result = (result + a / result) >> 1;\n            result = (result + a / result) >> 1;\n            result = (result + a / result) >> 1;\n            result = (result + a / result) >> 1;\n            return min(result, a / result);\n        }\n    }\n\n    /**\n     * @notice Calculates sqrt(a), following the selected rounding direction.\n     */\n    function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) {\n        unchecked {\n            uint256 result = sqrt(a);\n            return result + (rounding == Rounding.Up && result * result < a ? 1 : 0);\n        }\n    }\n\n    /**\n     * @dev Return the log in base 2, rounded down, of a positive value.\n     * Returns 0 if given 0.\n     */\n    function log2(uint256 value) internal pure returns (uint256) {\n        uint256 result = 0;\n        unchecked {\n            if (value >> 128 > 0) {\n                value >>= 128;\n                result += 128;\n            }\n            if (value >> 64 > 0) {\n                value >>= 64;\n                result += 64;\n            }\n            if (value >> 32 > 0) {\n                value >>= 32;\n                result += 32;\n            }\n            if (value >> 16 > 0) {\n                value >>= 16;\n                result += 16;\n            }\n            if (value >> 8 > 0) {\n                value >>= 8;\n                result += 8;\n            }\n            if (value >> 4 > 0) {\n                value >>= 4;\n                result += 4;\n            }\n            if (value >> 2 > 0) {\n                value >>= 2;\n                result += 2;\n            }\n            if (value >> 1 > 0) {\n                result += 1;\n            }\n        }\n        return result;\n    }\n\n    /**\n     * @dev Return the log in base 2, following the selected rounding direction, of a positive value.\n     * Returns 0 if given 0.\n     */\n    function log2(uint256 value, Rounding rounding) internal pure returns (uint256) {\n        unchecked {\n            uint256 result = log2(value);\n            return result + (rounding == Rounding.Up && 1 << result < value ? 1 : 0);\n        }\n    }\n\n    /**\n     * @dev Return the log in base 10, rounded down, of a positive value.\n     * Returns 0 if given 0.\n     */\n    function log10(uint256 value) internal pure returns (uint256) {\n        uint256 result = 0;\n        unchecked {\n            if (value >= 10 ** 64) {\n                value /= 10 ** 64;\n                result += 64;\n            }\n            if (value >= 10 ** 32) {\n                value /= 10 ** 32;\n                result += 32;\n            }\n            if (value >= 10 ** 16) {\n                value /= 10 ** 16;\n                result += 16;\n            }\n            if (value >= 10 ** 8) {\n                value /= 10 ** 8;\n                result += 8;\n            }\n            if (value >= 10 ** 4) {\n                value /= 10 ** 4;\n                result += 4;\n            }\n            if (value >= 10 ** 2) {\n                value /= 10 ** 2;\n                result += 2;\n            }\n            if (value >= 10 ** 1) {\n                result += 1;\n            }\n        }\n        return result;\n    }\n\n    /**\n     * @dev Return the log in base 10, following the selected rounding direction, of a positive value.\n     * Returns 0 if given 0.\n     */\n    function log10(uint256 value, Rounding rounding) internal pure returns (uint256) {\n        unchecked {\n            uint256 result = log10(value);\n            return result + (rounding == Rounding.Up && 10 ** result < value ? 1 : 0);\n        }\n    }\n\n    /**\n     * @dev Return the log in base 256, rounded down, of a positive value.\n     * Returns 0 if given 0.\n     *\n     * Adding one to the result gives the number of pairs of hex symbols needed to represent `value` as a hex string.\n     */\n    function log256(uint256 value) internal pure returns (uint256) {\n        uint256 result = 0;\n        unchecked {\n            if (value >> 128 > 0) {\n                value >>= 128;\n                result += 16;\n            }\n            if (value >> 64 > 0) {\n                value >>= 64;\n                result += 8;\n            }\n            if (value >> 32 > 0) {\n                value >>= 32;\n                result += 4;\n            }\n            if (value >> 16 > 0) {\n                value >>= 16;\n                result += 2;\n            }\n            if (value >> 8 > 0) {\n                result += 1;\n            }\n        }\n        return result;\n    }\n\n    /**\n     * @dev Return the log in base 256, following the selected rounding direction, of a positive value.\n     * Returns 0 if given 0.\n     */\n    function log256(uint256 value, Rounding rounding) internal pure returns (uint256) {\n        unchecked {\n            uint256 result = log256(value);\n            return result + (rounding == Rounding.Up && 1 << (result << 3) < value ? 1 : 0);\n        }\n    }\n}\n"},"@openzeppelin/contracts/utils/math/SignedMath.sol":{"content":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.8.0) (utils/math/SignedMath.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Standard signed math utilities missing in the Solidity language.\n */\nlibrary SignedMath {\n    /**\n     * @dev Returns the largest of two signed numbers.\n     */\n    function max(int256 a, int256 b) internal pure returns (int256) {\n        return a > b ? a : b;\n    }\n\n    /**\n     * @dev Returns the smallest of two signed numbers.\n     */\n    function min(int256 a, int256 b) internal pure returns (int256) {\n        return a < b ? a : b;\n    }\n\n    /**\n     * @dev Returns the average of two signed numbers without overflow.\n     * The result is rounded towards zero.\n     */\n    function average(int256 a, int256 b) internal pure returns (int256) {\n        // Formula from the book \"Hacker's Delight\"\n        int256 x = (a & b) + ((a ^ b) >> 1);\n        return x + (int256(uint256(x) >> 255) & (a ^ b));\n    }\n\n    /**\n     * @dev Returns the absolute unsigned value of a signed value.\n     */\n    function abs(int256 n) internal pure returns (uint256) {\n        unchecked {\n            // must be unchecked in order to support `n = type(int256).min`\n            return uint256(n >= 0 ? n : -n);\n        }\n    }\n}\n"},"@openzeppelin/contracts/utils/StorageSlot.sol":{"content":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/StorageSlot.sol)\n// This file was procedurally generated from scripts/generate/templates/StorageSlot.js.\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Library for reading and writing primitive types to specific storage slots.\n *\n * Storage slots are often used to avoid storage conflict when dealing with upgradeable contracts.\n * This library helps with reading and writing to such slots without the need for inline assembly.\n *\n * The functions in this library return Slot structs that contain a `value` member that can be used to read or write.\n *\n * Example usage to set ERC1967 implementation slot:\n * ```solidity\n * contract ERC1967 {\n *     bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\n *\n *     function _getImplementation() internal view returns (address) {\n *         return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value;\n *     }\n *\n *     function _setImplementation(address newImplementation) internal {\n *         require(Address.isContract(newImplementation), \"ERC1967: new implementation is not a contract\");\n *         StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation;\n *     }\n * }\n * ```\n *\n * _Available since v4.1 for `address`, `bool`, `bytes32`, `uint256`._\n * _Available since v4.9 for `string`, `bytes`._\n */\nlibrary StorageSlot {\n    struct AddressSlot {\n        address value;\n    }\n\n    struct BooleanSlot {\n        bool value;\n    }\n\n    struct Bytes32Slot {\n        bytes32 value;\n    }\n\n    struct Uint256Slot {\n        uint256 value;\n    }\n\n    struct StringSlot {\n        string value;\n    }\n\n    struct BytesSlot {\n        bytes value;\n    }\n\n    /**\n     * @dev Returns an `AddressSlot` with member `value` located at `slot`.\n     */\n    function getAddressSlot(bytes32 slot) internal pure returns (AddressSlot storage r) {\n        /// @solidity memory-safe-assembly\n        assembly {\n            r.slot := slot\n        }\n    }\n\n    /**\n     * @dev Returns an `BooleanSlot` with member `value` located at `slot`.\n     */\n    function getBooleanSlot(bytes32 slot) internal pure returns (BooleanSlot storage r) {\n        /// @solidity memory-safe-assembly\n        assembly {\n            r.slot := slot\n        }\n    }\n\n    /**\n     * @dev Returns an `Bytes32Slot` with member `value` located at `slot`.\n     */\n    function getBytes32Slot(bytes32 slot) internal pure returns (Bytes32Slot storage r) {\n        /// @solidity memory-safe-assembly\n        assembly {\n            r.slot := slot\n        }\n    }\n\n    /**\n     * @dev Returns an `Uint256Slot` with member `value` located at `slot`.\n     */\n    function getUint256Slot(bytes32 slot) internal pure returns (Uint256Slot storage r) {\n        /// @solidity memory-safe-assembly\n        assembly {\n            r.slot := slot\n        }\n    }\n\n    /**\n     * @dev Returns an `StringSlot` with member `value` located at `slot`.\n     */\n    function getStringSlot(bytes32 slot) internal pure returns (StringSlot storage r) {\n        /// @solidity memory-safe-assembly\n        assembly {\n            r.slot := slot\n        }\n    }\n\n    /**\n     * @dev Returns an `StringSlot` representation of the string storage pointer `store`.\n     */\n    function getStringSlot(string storage store) internal pure returns (StringSlot storage r) {\n        /// @solidity memory-safe-assembly\n        assembly {\n            r.slot := store.slot\n        }\n    }\n\n    /**\n     * @dev Returns an `BytesSlot` with member `value` located at `slot`.\n     */\n    function getBytesSlot(bytes32 slot) internal pure returns (BytesSlot storage r) {\n        /// @solidity memory-safe-assembly\n        assembly {\n            r.slot := slot\n        }\n    }\n\n    /**\n     * @dev Returns an `BytesSlot` representation of the bytes storage pointer `store`.\n     */\n    function getBytesSlot(bytes storage store) internal pure returns (BytesSlot storage r) {\n        /// @solidity memory-safe-assembly\n        assembly {\n            r.slot := store.slot\n        }\n    }\n}\n"},"@openzeppelin/contracts/utils/Strings.sol":{"content":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/Strings.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./math/Math.sol\";\nimport \"./math/SignedMath.sol\";\n\n/**\n * @dev String operations.\n */\nlibrary Strings {\n    bytes16 private constant _SYMBOLS = \"0123456789abcdef\";\n    uint8 private constant _ADDRESS_LENGTH = 20;\n\n    /**\n     * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n     */\n    function toString(uint256 value) internal pure returns (string memory) {\n        unchecked {\n            uint256 length = Math.log10(value) + 1;\n            string memory buffer = new string(length);\n            uint256 ptr;\n            /// @solidity memory-safe-assembly\n            assembly {\n                ptr := add(buffer, add(32, length))\n            }\n            while (true) {\n                ptr--;\n                /// @solidity memory-safe-assembly\n                assembly {\n                    mstore8(ptr, byte(mod(value, 10), _SYMBOLS))\n                }\n                value /= 10;\n                if (value == 0) break;\n            }\n            return buffer;\n        }\n    }\n\n    /**\n     * @dev Converts a `int256` to its ASCII `string` decimal representation.\n     */\n    function toString(int256 value) internal pure returns (string memory) {\n        return string(abi.encodePacked(value < 0 ? \"-\" : \"\", toString(SignedMath.abs(value))));\n    }\n\n    /**\n     * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n     */\n    function toHexString(uint256 value) internal pure returns (string memory) {\n        unchecked {\n            return toHexString(value, Math.log256(value) + 1);\n        }\n    }\n\n    /**\n     * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n     */\n    function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n        bytes memory buffer = new bytes(2 * length + 2);\n        buffer[0] = \"0\";\n        buffer[1] = \"x\";\n        for (uint256 i = 2 * length + 1; i > 1; --i) {\n            buffer[i] = _SYMBOLS[value & 0xf];\n            value >>= 4;\n        }\n        require(value == 0, \"Strings: hex length insufficient\");\n        return string(buffer);\n    }\n\n    /**\n     * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation.\n     */\n    function toHexString(address addr) internal pure returns (string memory) {\n        return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);\n    }\n\n    /**\n     * @dev Returns true if the two strings are equal.\n     */\n    function equal(string memory a, string memory b) internal pure returns (bool) {\n        return keccak256(bytes(a)) == keccak256(bytes(b));\n    }\n}\n"},"@openzeppelin/contracts/utils/structs/EnumerableMap.sol":{"content":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/structs/EnumerableMap.sol)\n// This file was procedurally generated from scripts/generate/templates/EnumerableMap.js.\n\npragma solidity ^0.8.0;\n\nimport \"./EnumerableSet.sol\";\n\n/**\n * @dev Library for managing an enumerable variant of Solidity's\n * https://solidity.readthedocs.io/en/latest/types.html#mapping-types[`mapping`]\n * type.\n *\n * Maps have the following properties:\n *\n * - Entries are added, removed, and checked for existence in constant time\n * (O(1)).\n * - Entries are enumerated in O(n). No guarantees are made on the ordering.\n *\n * ```solidity\n * contract Example {\n *     // Add the library methods\n *     using EnumerableMap for EnumerableMap.UintToAddressMap;\n *\n *     // Declare a set state variable\n *     EnumerableMap.UintToAddressMap private myMap;\n * }\n * ```\n *\n * The following map types are supported:\n *\n * - `uint256 -> address` (`UintToAddressMap`) since v3.0.0\n * - `address -> uint256` (`AddressToUintMap`) since v4.6.0\n * - `bytes32 -> bytes32` (`Bytes32ToBytes32Map`) since v4.6.0\n * - `uint256 -> uint256` (`UintToUintMap`) since v4.7.0\n * - `bytes32 -> uint256` (`Bytes32ToUintMap`) since v4.7.0\n *\n * [WARNING]\n * ====\n * Trying to delete such a structure from storage will likely result in data corruption, rendering the structure\n * unusable.\n * See https://github.com/ethereum/solidity/pull/11843[ethereum/solidity#11843] for more info.\n *\n * In order to clean an EnumerableMap, you can either remove all elements one by one or create a fresh instance using an\n * array of EnumerableMap.\n * ====\n */\nlibrary EnumerableMap {\n    using EnumerableSet for EnumerableSet.Bytes32Set;\n\n    // To implement this library for multiple types with as little code\n    // repetition as possible, we write it in terms of a generic Map type with\n    // bytes32 keys and values.\n    // The Map implementation uses private functions, and user-facing\n    // implementations (such as Uint256ToAddressMap) are just wrappers around\n    // the underlying Map.\n    // This means that we can only create new EnumerableMaps for types that fit\n    // in bytes32.\n\n    struct Bytes32ToBytes32Map {\n        // Storage of keys\n        EnumerableSet.Bytes32Set _keys;\n        mapping(bytes32 => bytes32) _values;\n    }\n\n    /**\n     * @dev Adds a key-value pair to a map, or updates the value for an existing\n     * key. O(1).\n     *\n     * Returns true if the key was added to the map, that is if it was not\n     * already present.\n     */\n    function set(Bytes32ToBytes32Map storage map, bytes32 key, bytes32 value) internal returns (bool) {\n        map._values[key] = value;\n        return map._keys.add(key);\n    }\n\n    /**\n     * @dev Removes a key-value pair from a map. O(1).\n     *\n     * Returns true if the key was removed from the map, that is if it was present.\n     */\n    function remove(Bytes32ToBytes32Map storage map, bytes32 key) internal returns (bool) {\n        delete map._values[key];\n        return map._keys.remove(key);\n    }\n\n    /**\n     * @dev Returns true if the key is in the map. O(1).\n     */\n    function contains(Bytes32ToBytes32Map storage map, bytes32 key) internal view returns (bool) {\n        return map._keys.contains(key);\n    }\n\n    /**\n     * @dev Returns the number of key-value pairs in the map. O(1).\n     */\n    function length(Bytes32ToBytes32Map storage map) internal view returns (uint256) {\n        return map._keys.length();\n    }\n\n    /**\n     * @dev Returns the key-value pair stored at position `index` in the map. O(1).\n     *\n     * Note that there are no guarantees on the ordering of entries inside the\n     * array, and it may change when more entries are added or removed.\n     *\n     * Requirements:\n     *\n     * - `index` must be strictly less than {length}.\n     */\n    function at(Bytes32ToBytes32Map storage map, uint256 index) internal view returns (bytes32, bytes32) {\n        bytes32 key = map._keys.at(index);\n        return (key, map._values[key]);\n    }\n\n    /**\n     * @dev Tries to returns the value associated with `key`. O(1).\n     * Does not revert if `key` is not in the map.\n     */\n    function tryGet(Bytes32ToBytes32Map storage map, bytes32 key) internal view returns (bool, bytes32) {\n        bytes32 value = map._values[key];\n        if (value == bytes32(0)) {\n            return (contains(map, key), bytes32(0));\n        } else {\n            return (true, value);\n        }\n    }\n\n    /**\n     * @dev Returns the value associated with `key`. O(1).\n     *\n     * Requirements:\n     *\n     * - `key` must be in the map.\n     */\n    function get(Bytes32ToBytes32Map storage map, bytes32 key) internal view returns (bytes32) {\n        bytes32 value = map._values[key];\n        require(value != 0 || contains(map, key), \"EnumerableMap: nonexistent key\");\n        return value;\n    }\n\n    /**\n     * @dev Same as {get}, with a custom error message when `key` is not in the map.\n     *\n     * CAUTION: This function is deprecated because it requires allocating memory for the error\n     * message unnecessarily. For custom revert reasons use {tryGet}.\n     */\n    function get(\n        Bytes32ToBytes32Map storage map,\n        bytes32 key,\n        string memory errorMessage\n    ) internal view returns (bytes32) {\n        bytes32 value = map._values[key];\n        require(value != 0 || contains(map, key), errorMessage);\n        return value;\n    }\n\n    /**\n     * @dev Return the an array containing all the keys\n     *\n     * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n     * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n     * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n     * uncallable if the map grows to a point where copying to memory consumes too much gas to fit in a block.\n     */\n    function keys(Bytes32ToBytes32Map storage map) internal view returns (bytes32[] memory) {\n        return map._keys.values();\n    }\n\n    // UintToUintMap\n\n    struct UintToUintMap {\n        Bytes32ToBytes32Map _inner;\n    }\n\n    /**\n     * @dev Adds a key-value pair to a map, or updates the value for an existing\n     * key. O(1).\n     *\n     * Returns true if the key was added to the map, that is if it was not\n     * already present.\n     */\n    function set(UintToUintMap storage map, uint256 key, uint256 value) internal returns (bool) {\n        return set(map._inner, bytes32(key), bytes32(value));\n    }\n\n    /**\n     * @dev Removes a value from a map. O(1).\n     *\n     * Returns true if the key was removed from the map, that is if it was present.\n     */\n    function remove(UintToUintMap storage map, uint256 key) internal returns (bool) {\n        return remove(map._inner, bytes32(key));\n    }\n\n    /**\n     * @dev Returns true if the key is in the map. O(1).\n     */\n    function contains(UintToUintMap storage map, uint256 key) internal view returns (bool) {\n        return contains(map._inner, bytes32(key));\n    }\n\n    /**\n     * @dev Returns the number of elements in the map. O(1).\n     */\n    function length(UintToUintMap storage map) internal view returns (uint256) {\n        return length(map._inner);\n    }\n\n    /**\n     * @dev Returns the element stored at position `index` in the map. O(1).\n     * Note that there are no guarantees on the ordering of values inside the\n     * array, and it may change when more values are added or removed.\n     *\n     * Requirements:\n     *\n     * - `index` must be strictly less than {length}.\n     */\n    function at(UintToUintMap storage map, uint256 index) internal view returns (uint256, uint256) {\n        (bytes32 key, bytes32 value) = at(map._inner, index);\n        return (uint256(key), uint256(value));\n    }\n\n    /**\n     * @dev Tries to returns the value associated with `key`. O(1).\n     * Does not revert if `key` is not in the map.\n     */\n    function tryGet(UintToUintMap storage map, uint256 key) internal view returns (bool, uint256) {\n        (bool success, bytes32 value) = tryGet(map._inner, bytes32(key));\n        return (success, uint256(value));\n    }\n\n    /**\n     * @dev Returns the value associated with `key`. O(1).\n     *\n     * Requirements:\n     *\n     * - `key` must be in the map.\n     */\n    function get(UintToUintMap storage map, uint256 key) internal view returns (uint256) {\n        return uint256(get(map._inner, bytes32(key)));\n    }\n\n    /**\n     * @dev Same as {get}, with a custom error message when `key` is not in the map.\n     *\n     * CAUTION: This function is deprecated because it requires allocating memory for the error\n     * message unnecessarily. For custom revert reasons use {tryGet}.\n     */\n    function get(UintToUintMap storage map, uint256 key, string memory errorMessage) internal view returns (uint256) {\n        return uint256(get(map._inner, bytes32(key), errorMessage));\n    }\n\n    /**\n     * @dev Return the an array containing all the keys\n     *\n     * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n     * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n     * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n     * uncallable if the map grows to a point where copying to memory consumes too much gas to fit in a block.\n     */\n    function keys(UintToUintMap storage map) internal view returns (uint256[] memory) {\n        bytes32[] memory store = keys(map._inner);\n        uint256[] memory result;\n\n        /// @solidity memory-safe-assembly\n        assembly {\n            result := store\n        }\n\n        return result;\n    }\n\n    // UintToAddressMap\n\n    struct UintToAddressMap {\n        Bytes32ToBytes32Map _inner;\n    }\n\n    /**\n     * @dev Adds a key-value pair to a map, or updates the value for an existing\n     * key. O(1).\n     *\n     * Returns true if the key was added to the map, that is if it was not\n     * already present.\n     */\n    function set(UintToAddressMap storage map, uint256 key, address value) internal returns (bool) {\n        return set(map._inner, bytes32(key), bytes32(uint256(uint160(value))));\n    }\n\n    /**\n     * @dev Removes a value from a map. O(1).\n     *\n     * Returns true if the key was removed from the map, that is if it was present.\n     */\n    function remove(UintToAddressMap storage map, uint256 key) internal returns (bool) {\n        return remove(map._inner, bytes32(key));\n    }\n\n    /**\n     * @dev Returns true if the key is in the map. O(1).\n     */\n    function contains(UintToAddressMap storage map, uint256 key) internal view returns (bool) {\n        return contains(map._inner, bytes32(key));\n    }\n\n    /**\n     * @dev Returns the number of elements in the map. O(1).\n     */\n    function length(UintToAddressMap storage map) internal view returns (uint256) {\n        return length(map._inner);\n    }\n\n    /**\n     * @dev Returns the element stored at position `index` in the map. O(1).\n     * Note that there are no guarantees on the ordering of values inside the\n     * array, and it may change when more values are added or removed.\n     *\n     * Requirements:\n     *\n     * - `index` must be strictly less than {length}.\n     */\n    function at(UintToAddressMap storage map, uint256 index) internal view returns (uint256, address) {\n        (bytes32 key, bytes32 value) = at(map._inner, index);\n        return (uint256(key), address(uint160(uint256(value))));\n    }\n\n    /**\n     * @dev Tries to returns the value associated with `key`. O(1).\n     * Does not revert if `key` is not in the map.\n     */\n    function tryGet(UintToAddressMap storage map, uint256 key) internal view returns (bool, address) {\n        (bool success, bytes32 value) = tryGet(map._inner, bytes32(key));\n        return (success, address(uint160(uint256(value))));\n    }\n\n    /**\n     * @dev Returns the value associated with `key`. O(1).\n     *\n     * Requirements:\n     *\n     * - `key` must be in the map.\n     */\n    function get(UintToAddressMap storage map, uint256 key) internal view returns (address) {\n        return address(uint160(uint256(get(map._inner, bytes32(key)))));\n    }\n\n    /**\n     * @dev Same as {get}, with a custom error message when `key` is not in the map.\n     *\n     * CAUTION: This function is deprecated because it requires allocating memory for the error\n     * message unnecessarily. For custom revert reasons use {tryGet}.\n     */\n    function get(\n        UintToAddressMap storage map,\n        uint256 key,\n        string memory errorMessage\n    ) internal view returns (address) {\n        return address(uint160(uint256(get(map._inner, bytes32(key), errorMessage))));\n    }\n\n    /**\n     * @dev Return the an array containing all the keys\n     *\n     * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n     * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n     * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n     * uncallable if the map grows to a point where copying to memory consumes too much gas to fit in a block.\n     */\n    function keys(UintToAddressMap storage map) internal view returns (uint256[] memory) {\n        bytes32[] memory store = keys(map._inner);\n        uint256[] memory result;\n\n        /// @solidity memory-safe-assembly\n        assembly {\n            result := store\n        }\n\n        return result;\n    }\n\n    // AddressToUintMap\n\n    struct AddressToUintMap {\n        Bytes32ToBytes32Map _inner;\n    }\n\n    /**\n     * @dev Adds a key-value pair to a map, or updates the value for an existing\n     * key. O(1).\n     *\n     * Returns true if the key was added to the map, that is if it was not\n     * already present.\n     */\n    function set(AddressToUintMap storage map, address key, uint256 value) internal returns (bool) {\n        return set(map._inner, bytes32(uint256(uint160(key))), bytes32(value));\n    }\n\n    /**\n     * @dev Removes a value from a map. O(1).\n     *\n     * Returns true if the key was removed from the map, that is if it was present.\n     */\n    function remove(AddressToUintMap storage map, address key) internal returns (bool) {\n        return remove(map._inner, bytes32(uint256(uint160(key))));\n    }\n\n    /**\n     * @dev Returns true if the key is in the map. O(1).\n     */\n    function contains(AddressToUintMap storage map, address key) internal view returns (bool) {\n        return contains(map._inner, bytes32(uint256(uint160(key))));\n    }\n\n    /**\n     * @dev Returns the number of elements in the map. O(1).\n     */\n    function length(AddressToUintMap storage map) internal view returns (uint256) {\n        return length(map._inner);\n    }\n\n    /**\n     * @dev Returns the element stored at position `index` in the map. O(1).\n     * Note that there are no guarantees on the ordering of values inside the\n     * array, and it may change when more values are added or removed.\n     *\n     * Requirements:\n     *\n     * - `index` must be strictly less than {length}.\n     */\n    function at(AddressToUintMap storage map, uint256 index) internal view returns (address, uint256) {\n        (bytes32 key, bytes32 value) = at(map._inner, index);\n        return (address(uint160(uint256(key))), uint256(value));\n    }\n\n    /**\n     * @dev Tries to returns the value associated with `key`. O(1).\n     * Does not revert if `key` is not in the map.\n     */\n    function tryGet(AddressToUintMap storage map, address key) internal view returns (bool, uint256) {\n        (bool success, bytes32 value) = tryGet(map._inner, bytes32(uint256(uint160(key))));\n        return (success, uint256(value));\n    }\n\n    /**\n     * @dev Returns the value associated with `key`. O(1).\n     *\n     * Requirements:\n     *\n     * - `key` must be in the map.\n     */\n    function get(AddressToUintMap storage map, address key) internal view returns (uint256) {\n        return uint256(get(map._inner, bytes32(uint256(uint160(key)))));\n    }\n\n    /**\n     * @dev Same as {get}, with a custom error message when `key` is not in the map.\n     *\n     * CAUTION: This function is deprecated because it requires allocating memory for the error\n     * message unnecessarily. For custom revert reasons use {tryGet}.\n     */\n    function get(\n        AddressToUintMap storage map,\n        address key,\n        string memory errorMessage\n    ) internal view returns (uint256) {\n        return uint256(get(map._inner, bytes32(uint256(uint160(key))), errorMessage));\n    }\n\n    /**\n     * @dev Return the an array containing all the keys\n     *\n     * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n     * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n     * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n     * uncallable if the map grows to a point where copying to memory consumes too much gas to fit in a block.\n     */\n    function keys(AddressToUintMap storage map) internal view returns (address[] memory) {\n        bytes32[] memory store = keys(map._inner);\n        address[] memory result;\n\n        /// @solidity memory-safe-assembly\n        assembly {\n            result := store\n        }\n\n        return result;\n    }\n\n    // Bytes32ToUintMap\n\n    struct Bytes32ToUintMap {\n        Bytes32ToBytes32Map _inner;\n    }\n\n    /**\n     * @dev Adds a key-value pair to a map, or updates the value for an existing\n     * key. O(1).\n     *\n     * Returns true if the key was added to the map, that is if it was not\n     * already present.\n     */\n    function set(Bytes32ToUintMap storage map, bytes32 key, uint256 value) internal returns (bool) {\n        return set(map._inner, key, bytes32(value));\n    }\n\n    /**\n     * @dev Removes a value from a map. O(1).\n     *\n     * Returns true if the key was removed from the map, that is if it was present.\n     */\n    function remove(Bytes32ToUintMap storage map, bytes32 key) internal returns (bool) {\n        return remove(map._inner, key);\n    }\n\n    /**\n     * @dev Returns true if the key is in the map. O(1).\n     */\n    function contains(Bytes32ToUintMap storage map, bytes32 key) internal view returns (bool) {\n        return contains(map._inner, key);\n    }\n\n    /**\n     * @dev Returns the number of elements in the map. O(1).\n     */\n    function length(Bytes32ToUintMap storage map) internal view returns (uint256) {\n        return length(map._inner);\n    }\n\n    /**\n     * @dev Returns the element stored at position `index` in the map. O(1).\n     * Note that there are no guarantees on the ordering of values inside the\n     * array, and it may change when more values are added or removed.\n     *\n     * Requirements:\n     *\n     * - `index` must be strictly less than {length}.\n     */\n    function at(Bytes32ToUintMap storage map, uint256 index) internal view returns (bytes32, uint256) {\n        (bytes32 key, bytes32 value) = at(map._inner, index);\n        return (key, uint256(value));\n    }\n\n    /**\n     * @dev Tries to returns the value associated with `key`. O(1).\n     * Does not revert if `key` is not in the map.\n     */\n    function tryGet(Bytes32ToUintMap storage map, bytes32 key) internal view returns (bool, uint256) {\n        (bool success, bytes32 value) = tryGet(map._inner, key);\n        return (success, uint256(value));\n    }\n\n    /**\n     * @dev Returns the value associated with `key`. O(1).\n     *\n     * Requirements:\n     *\n     * - `key` must be in the map.\n     */\n    function get(Bytes32ToUintMap storage map, bytes32 key) internal view returns (uint256) {\n        return uint256(get(map._inner, key));\n    }\n\n    /**\n     * @dev Same as {get}, with a custom error message when `key` is not in the map.\n     *\n     * CAUTION: This function is deprecated because it requires allocating memory for the error\n     * message unnecessarily. For custom revert reasons use {tryGet}.\n     */\n    function get(\n        Bytes32ToUintMap storage map,\n        bytes32 key,\n        string memory errorMessage\n    ) internal view returns (uint256) {\n        return uint256(get(map._inner, key, errorMessage));\n    }\n\n    /**\n     * @dev Return the an array containing all the keys\n     *\n     * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n     * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n     * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n     * uncallable if the map grows to a point where copying to memory consumes too much gas to fit in a block.\n     */\n    function keys(Bytes32ToUintMap storage map) internal view returns (bytes32[] memory) {\n        bytes32[] memory store = keys(map._inner);\n        bytes32[] memory result;\n\n        /// @solidity memory-safe-assembly\n        assembly {\n            result := store\n        }\n\n        return result;\n    }\n}\n"},"@openzeppelin/contracts/utils/structs/EnumerableSet.sol":{"content":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/structs/EnumerableSet.sol)\n// This file was procedurally generated from scripts/generate/templates/EnumerableSet.js.\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Library for managing\n * https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive\n * types.\n *\n * Sets have the following properties:\n *\n * - Elements are added, removed, and checked for existence in constant time\n * (O(1)).\n * - Elements are enumerated in O(n). No guarantees are made on the ordering.\n *\n * ```solidity\n * contract Example {\n *     // Add the library methods\n *     using EnumerableSet for EnumerableSet.AddressSet;\n *\n *     // Declare a set state variable\n *     EnumerableSet.AddressSet private mySet;\n * }\n * ```\n *\n * As of v3.3.0, sets of type `bytes32` (`Bytes32Set`), `address` (`AddressSet`)\n * and `uint256` (`UintSet`) are supported.\n *\n * [WARNING]\n * ====\n * Trying to delete such a structure from storage will likely result in data corruption, rendering the structure\n * unusable.\n * See https://github.com/ethereum/solidity/pull/11843[ethereum/solidity#11843] for more info.\n *\n * In order to clean an EnumerableSet, you can either remove all elements one by one or create a fresh instance using an\n * array of EnumerableSet.\n * ====\n */\nlibrary EnumerableSet {\n    // To implement this library for multiple types with as little code\n    // repetition as possible, we write it in terms of a generic Set type with\n    // bytes32 values.\n    // The Set implementation uses private functions, and user-facing\n    // implementations (such as AddressSet) are just wrappers around the\n    // underlying Set.\n    // This means that we can only create new EnumerableSets for types that fit\n    // in bytes32.\n\n    struct Set {\n        // Storage of set values\n        bytes32[] _values;\n        // Position of the value in the `values` array, plus 1 because index 0\n        // means a value is not in the set.\n        mapping(bytes32 => uint256) _indexes;\n    }\n\n    /**\n     * @dev Add a value to a set. O(1).\n     *\n     * Returns true if the value was added to the set, that is if it was not\n     * already present.\n     */\n    function _add(Set storage set, bytes32 value) private returns (bool) {\n        if (!_contains(set, value)) {\n            set._values.push(value);\n            // The value is stored at length-1, but we add 1 to all indexes\n            // and use 0 as a sentinel value\n            set._indexes[value] = set._values.length;\n            return true;\n        } else {\n            return false;\n        }\n    }\n\n    /**\n     * @dev Removes a value from a set. O(1).\n     *\n     * Returns true if the value was removed from the set, that is if it was\n     * present.\n     */\n    function _remove(Set storage set, bytes32 value) private returns (bool) {\n        // We read and store the value's index to prevent multiple reads from the same storage slot\n        uint256 valueIndex = set._indexes[value];\n\n        if (valueIndex != 0) {\n            // Equivalent to contains(set, value)\n            // To delete an element from the _values array in O(1), we swap the element to delete with the last one in\n            // the array, and then remove the last element (sometimes called as 'swap and pop').\n            // This modifies the order of the array, as noted in {at}.\n\n            uint256 toDeleteIndex = valueIndex - 1;\n            uint256 lastIndex = set._values.length - 1;\n\n            if (lastIndex != toDeleteIndex) {\n                bytes32 lastValue = set._values[lastIndex];\n\n                // Move the last value to the index where the value to delete is\n                set._values[toDeleteIndex] = lastValue;\n                // Update the index for the moved value\n                set._indexes[lastValue] = valueIndex; // Replace lastValue's index to valueIndex\n            }\n\n            // Delete the slot where the moved value was stored\n            set._values.pop();\n\n            // Delete the index for the deleted slot\n            delete set._indexes[value];\n\n            return true;\n        } else {\n            return false;\n        }\n    }\n\n    /**\n     * @dev Returns true if the value is in the set. O(1).\n     */\n    function _contains(Set storage set, bytes32 value) private view returns (bool) {\n        return set._indexes[value] != 0;\n    }\n\n    /**\n     * @dev Returns the number of values on the set. O(1).\n     */\n    function _length(Set storage set) private view returns (uint256) {\n        return set._values.length;\n    }\n\n    /**\n     * @dev Returns the value stored at position `index` in the set. O(1).\n     *\n     * Note that there are no guarantees on the ordering of values inside the\n     * array, and it may change when more values are added or removed.\n     *\n     * Requirements:\n     *\n     * - `index` must be strictly less than {length}.\n     */\n    function _at(Set storage set, uint256 index) private view returns (bytes32) {\n        return set._values[index];\n    }\n\n    /**\n     * @dev Return the entire set in an array\n     *\n     * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n     * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n     * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n     * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n     */\n    function _values(Set storage set) private view returns (bytes32[] memory) {\n        return set._values;\n    }\n\n    // Bytes32Set\n\n    struct Bytes32Set {\n        Set _inner;\n    }\n\n    /**\n     * @dev Add a value to a set. O(1).\n     *\n     * Returns true if the value was added to the set, that is if it was not\n     * already present.\n     */\n    function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n        return _add(set._inner, value);\n    }\n\n    /**\n     * @dev Removes a value from a set. O(1).\n     *\n     * Returns true if the value was removed from the set, that is if it was\n     * present.\n     */\n    function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n        return _remove(set._inner, value);\n    }\n\n    /**\n     * @dev Returns true if the value is in the set. O(1).\n     */\n    function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {\n        return _contains(set._inner, value);\n    }\n\n    /**\n     * @dev Returns the number of values in the set. O(1).\n     */\n    function length(Bytes32Set storage set) internal view returns (uint256) {\n        return _length(set._inner);\n    }\n\n    /**\n     * @dev Returns the value stored at position `index` in the set. O(1).\n     *\n     * Note that there are no guarantees on the ordering of values inside the\n     * array, and it may change when more values are added or removed.\n     *\n     * Requirements:\n     *\n     * - `index` must be strictly less than {length}.\n     */\n    function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {\n        return _at(set._inner, index);\n    }\n\n    /**\n     * @dev Return the entire set in an array\n     *\n     * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n     * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n     * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n     * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n     */\n    function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {\n        bytes32[] memory store = _values(set._inner);\n        bytes32[] memory result;\n\n        /// @solidity memory-safe-assembly\n        assembly {\n            result := store\n        }\n\n        return result;\n    }\n\n    // AddressSet\n\n    struct AddressSet {\n        Set _inner;\n    }\n\n    /**\n     * @dev Add a value to a set. O(1).\n     *\n     * Returns true if the value was added to the set, that is if it was not\n     * already present.\n     */\n    function add(AddressSet storage set, address value) internal returns (bool) {\n        return _add(set._inner, bytes32(uint256(uint160(value))));\n    }\n\n    /**\n     * @dev Removes a value from a set. O(1).\n     *\n     * Returns true if the value was removed from the set, that is if it was\n     * present.\n     */\n    function remove(AddressSet storage set, address value) internal returns (bool) {\n        return _remove(set._inner, bytes32(uint256(uint160(value))));\n    }\n\n    /**\n     * @dev Returns true if the value is in the set. O(1).\n     */\n    function contains(AddressSet storage set, address value) internal view returns (bool) {\n        return _contains(set._inner, bytes32(uint256(uint160(value))));\n    }\n\n    /**\n     * @dev Returns the number of values in the set. O(1).\n     */\n    function length(AddressSet storage set) internal view returns (uint256) {\n        return _length(set._inner);\n    }\n\n    /**\n     * @dev Returns the value stored at position `index` in the set. O(1).\n     *\n     * Note that there are no guarantees on the ordering of values inside the\n     * array, and it may change when more values are added or removed.\n     *\n     * Requirements:\n     *\n     * - `index` must be strictly less than {length}.\n     */\n    function at(AddressSet storage set, uint256 index) internal view returns (address) {\n        return address(uint160(uint256(_at(set._inner, index))));\n    }\n\n    /**\n     * @dev Return the entire set in an array\n     *\n     * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n     * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n     * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n     * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n     */\n    function values(AddressSet storage set) internal view returns (address[] memory) {\n        bytes32[] memory store = _values(set._inner);\n        address[] memory result;\n\n        /// @solidity memory-safe-assembly\n        assembly {\n            result := store\n        }\n\n        return result;\n    }\n\n    // UintSet\n\n    struct UintSet {\n        Set _inner;\n    }\n\n    /**\n     * @dev Add a value to a set. O(1).\n     *\n     * Returns true if the value was added to the set, that is if it was not\n     * already present.\n     */\n    function add(UintSet storage set, uint256 value) internal returns (bool) {\n        return _add(set._inner, bytes32(value));\n    }\n\n    /**\n     * @dev Removes a value from a set. O(1).\n     *\n     * Returns true if the value was removed from the set, that is if it was\n     * present.\n     */\n    function remove(UintSet storage set, uint256 value) internal returns (bool) {\n        return _remove(set._inner, bytes32(value));\n    }\n\n    /**\n     * @dev Returns true if the value is in the set. O(1).\n     */\n    function contains(UintSet storage set, uint256 value) internal view returns (bool) {\n        return _contains(set._inner, bytes32(value));\n    }\n\n    /**\n     * @dev Returns the number of values in the set. O(1).\n     */\n    function length(UintSet storage set) internal view returns (uint256) {\n        return _length(set._inner);\n    }\n\n    /**\n     * @dev Returns the value stored at position `index` in the set. O(1).\n     *\n     * Note that there are no guarantees on the ordering of values inside the\n     * array, and it may change when more values are added or removed.\n     *\n     * Requirements:\n     *\n     * - `index` must be strictly less than {length}.\n     */\n    function at(UintSet storage set, uint256 index) internal view returns (uint256) {\n        return uint256(_at(set._inner, index));\n    }\n\n    /**\n     * @dev Return the entire set in an array\n     *\n     * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n     * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n     * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n     * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n     */\n    function values(UintSet storage set) internal view returns (uint256[] memory) {\n        bytes32[] memory store = _values(set._inner);\n        uint256[] memory result;\n\n        /// @solidity memory-safe-assembly\n        assembly {\n            result := store\n        }\n\n        return result;\n    }\n}\n"},"@openzeppelin/contracts/vendor/arbitrum/IBridge.sol":{"content":"// Copyright 2021-2022, Offchain Labs, Inc.\n// For license information, see https://github.com/nitro/blob/master/LICENSE\n// SPDX-License-Identifier: BUSL-1.1\n// OpenZeppelin Contracts (last updated v4.9.0) (vendor/arbitrum/IBridge.sol)\n\n// solhint-disable-next-line compiler-version\npragma solidity >=0.6.9 <0.9.0;\n\ninterface IBridge {\n    event MessageDelivered(\n        uint256 indexed messageIndex,\n        bytes32 indexed beforeInboxAcc,\n        address inbox,\n        uint8 kind,\n        address sender,\n        bytes32 messageDataHash,\n        uint256 baseFeeL1,\n        uint64 timestamp\n    );\n\n    event BridgeCallTriggered(address indexed outbox, address indexed to, uint256 value, bytes data);\n\n    event InboxToggle(address indexed inbox, bool enabled);\n\n    event OutboxToggle(address indexed outbox, bool enabled);\n\n    event SequencerInboxUpdated(address newSequencerInbox);\n\n    function allowedDelayedInboxList(uint256) external returns (address);\n\n    function allowedOutboxList(uint256) external returns (address);\n\n    /// @dev Accumulator for delayed inbox messages; tail represents hash of the current state; each element represents the inclusion of a new message.\n    function delayedInboxAccs(uint256) external view returns (bytes32);\n\n    /// @dev Accumulator for sequencer inbox messages; tail represents hash of the current state; each element represents the inclusion of a new message.\n    function sequencerInboxAccs(uint256) external view returns (bytes32);\n\n    // OpenZeppelin: changed return type from IOwnable\n    function rollup() external view returns (address);\n\n    function sequencerInbox() external view returns (address);\n\n    function activeOutbox() external view returns (address);\n\n    function allowedDelayedInboxes(address inbox) external view returns (bool);\n\n    function allowedOutboxes(address outbox) external view returns (bool);\n\n    function sequencerReportedSubMessageCount() external view returns (uint256);\n\n    /**\n     * @dev Enqueue a message in the delayed inbox accumulator.\n     *      These messages are later sequenced in the SequencerInbox, either\n     *      by the sequencer as part of a normal batch, or by force inclusion.\n     */\n    function enqueueDelayedMessage(\n        uint8 kind,\n        address sender,\n        bytes32 messageDataHash\n    ) external payable returns (uint256);\n\n    function executeCall(\n        address to,\n        uint256 value,\n        bytes calldata data\n    ) external returns (bool success, bytes memory returnData);\n\n    function delayedMessageCount() external view returns (uint256);\n\n    function sequencerMessageCount() external view returns (uint256);\n\n    // ---------- onlySequencerInbox functions ----------\n\n    function enqueueSequencerMessage(\n        bytes32 dataHash,\n        uint256 afterDelayedMessagesRead,\n        uint256 prevMessageCount,\n        uint256 newMessageCount\n    ) external returns (uint256 seqMessageIndex, bytes32 beforeAcc, bytes32 delayedAcc, bytes32 acc);\n\n    /**\n     * @dev Allows the sequencer inbox to submit a delayed message of the batchPostingReport type\n     *      This is done through a separate function entrypoint instead of allowing the sequencer inbox\n     *      to call `enqueueDelayedMessage` to avoid the gas overhead of an extra SLOAD in either\n     *      every delayed inbox or every sequencer inbox call.\n     */\n    function submitBatchSpendingReport(address batchPoster, bytes32 dataHash) external returns (uint256 msgNum);\n\n    // ---------- onlyRollupOrOwner functions ----------\n\n    function setSequencerInbox(address _sequencerInbox) external;\n\n    function setDelayedInbox(address inbox, bool enabled) external;\n\n    function setOutbox(address inbox, bool enabled) external;\n\n    // ---------- initializer ----------\n\n    // OpenZeppelin: changed rollup_ type from IOwnable\n    function initialize(address rollup_) external;\n}\n"},"@openzeppelin/contracts/vendor/arbitrum/IOutbox.sol":{"content":"// Copyright 2021-2022, Offchain Labs, Inc.\n// For license information, see https://github.com/nitro/blob/master/LICENSE\n// SPDX-License-Identifier: BUSL-1.1\n// OpenZeppelin Contracts (last updated v4.9.0) (vendor/arbitrum/IOutbox.sol)\n\n// solhint-disable-next-line compiler-version\npragma solidity >=0.6.9 <0.9.0;\n\nimport \"./IBridge.sol\";\n\ninterface IOutbox {\n    event SendRootUpdated(bytes32 indexed blockHash, bytes32 indexed outputRoot);\n    event OutBoxTransactionExecuted(\n        address indexed to,\n        address indexed l2Sender,\n        uint256 indexed zero,\n        uint256 transactionIndex\n    );\n\n    function rollup() external view returns (address); // the rollup contract\n\n    function bridge() external view returns (IBridge); // the bridge contract\n\n    function spent(uint256) external view returns (bytes32); // packed spent bitmap\n\n    function roots(bytes32) external view returns (bytes32); // maps root hashes => L2 block hash\n\n    // solhint-disable-next-line func-name-mixedcase\n    function OUTBOX_VERSION() external view returns (uint128); // the outbox version\n\n    function updateSendRoot(bytes32 sendRoot, bytes32 l2BlockHash) external;\n\n    /// @notice When l2ToL1Sender returns a nonzero address, the message was originated by an L2 account\n    ///         When the return value is zero, that means this is a system message\n    /// @dev the l2ToL1Sender behaves as the tx.origin, the msg.sender should be validated to protect against reentrancies\n    function l2ToL1Sender() external view returns (address);\n\n    /// @return l2Block return L2 block when the L2 tx was initiated or 0 if no L2 to L1 transaction is active\n    function l2ToL1Block() external view returns (uint256);\n\n    /// @return l1Block return L1 block when the L2 tx was initiated or 0 if no L2 to L1 transaction is active\n    function l2ToL1EthBlock() external view returns (uint256);\n\n    /// @return timestamp return L2 timestamp when the L2 tx was initiated or 0 if no L2 to L1 transaction is active\n    function l2ToL1Timestamp() external view returns (uint256);\n\n    /// @return outputId returns the unique output identifier of the L2 to L1 tx or 0 if no L2 to L1 transaction is active\n    function l2ToL1OutputId() external view returns (bytes32);\n\n    /**\n     * @notice Executes a messages in an Outbox entry.\n     * @dev Reverts if dispute period hasn't expired, since the outbox entry\n     *      is only created once the rollup confirms the respective assertion.\n     * @dev it is not possible to execute any L2-to-L1 transaction which contains data\n     *      to a contract address without any code (as enforced by the Bridge contract).\n     * @param proof Merkle proof of message inclusion in send root\n     * @param index Merkle path to message\n     * @param l2Sender sender if original message (i.e., caller of ArbSys.sendTxToL1)\n     * @param to destination address for L1 contract call\n     * @param l2Block l2 block number at which sendTxToL1 call was made\n     * @param l1Block l1 block number at which sendTxToL1 call was made\n     * @param l2Timestamp l2 Timestamp at which sendTxToL1 call was made\n     * @param value wei in L1 message\n     * @param data abi-encoded L1 message data\n     */\n    function executeTransaction(\n        bytes32[] calldata proof,\n        uint256 index,\n        address l2Sender,\n        address to,\n        uint256 l2Block,\n        uint256 l1Block,\n        uint256 l2Timestamp,\n        uint256 value,\n        bytes calldata data\n    ) external;\n\n    /**\n     *  @dev function used to simulate the result of a particular function call from the outbox\n     *       it is useful for things such as gas estimates. This function includes all costs except for\n     *       proof validation (which can be considered offchain as a somewhat of a fixed cost - it's\n     *       not really a fixed cost, but can be treated as so with a fixed overhead for gas estimation).\n     *       We can't include the cost of proof validation since this is intended to be used to simulate txs\n     *       that are included in yet-to-be confirmed merkle roots. The simulation entrypoint could instead pretend\n     *       to confirm a pending merkle root, but that would be less practical for integrating with tooling.\n     *       It is only possible to trigger it when the msg sender is address zero, which should be impossible\n     *       unless under simulation in an eth_call or eth_estimateGas\n     */\n    function executeTransactionSimulation(\n        uint256 index,\n        address l2Sender,\n        address to,\n        uint256 l2Block,\n        uint256 l1Block,\n        uint256 l2Timestamp,\n        uint256 value,\n        bytes calldata data\n    ) external;\n\n    /**\n     * @param index Merkle path to message\n     * @return true if the message has been spent\n     */\n    function isSpent(uint256 index) external view returns (bool);\n\n    function calculateItemHash(\n        address l2Sender,\n        address to,\n        uint256 l2Block,\n        uint256 l1Block,\n        uint256 l2Timestamp,\n        uint256 value,\n        bytes calldata data\n    ) external pure returns (bytes32);\n\n    function calculateMerkleRoot(bytes32[] memory proof, uint256 path, bytes32 item) external pure returns (bytes32);\n}\n"},"@openzeppelin/contracts/vendor/optimism/ICrossDomainMessenger.sol":{"content":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (vendor/optimism/ICrossDomainMessenger.sol)\npragma solidity >0.5.0 <0.9.0;\n\n/**\n * @title ICrossDomainMessenger\n */\ninterface ICrossDomainMessenger {\n    /**********\n     * Events *\n     **********/\n\n    event SentMessage(address indexed target, address sender, bytes message, uint256 messageNonce, uint256 gasLimit);\n    event RelayedMessage(bytes32 indexed msgHash);\n    event FailedRelayedMessage(bytes32 indexed msgHash);\n\n    /*************\n     * Variables *\n     *************/\n\n    function xDomainMessageSender() external view returns (address);\n\n    /********************\n     * Public Functions *\n     ********************/\n\n    /**\n     * Sends a cross domain message to the target messenger.\n     * @param _target Target contract address.\n     * @param _message Message to send to the target.\n     * @param _gasLimit Gas limit for the provided message.\n     */\n    function sendMessage(address _target, bytes calldata _message, uint32 _gasLimit) external;\n}\n"},"contracts/AttributeCheckpointFraud.sol":{"content":"// SPDX-License-Identifier: MIT OR Apache-2.0\npragma solidity >=0.8.0;\n\nimport {ECDSA} from \"@openzeppelin/contracts/utils/cryptography/ECDSA.sol\";\nimport {Address} from \"@openzeppelin/contracts/utils/Address.sol\";\nimport {Ownable} from \"@openzeppelin/contracts/access/Ownable.sol\";\n\nimport {PackageVersioned} from \"./PackageVersioned.sol\";\nimport {TREE_DEPTH} from \"./libs/Merkle.sol\";\nimport {CheckpointLib, Checkpoint} from \"./libs/CheckpointLib.sol\";\nimport {CheckpointFraudProofs} from \"./CheckpointFraudProofs.sol\";\n\nenum FraudType {\n    Whitelist,\n    Premature,\n    MessageId,\n    Root\n}\n\nstruct Attribution {\n    FraudType fraudType;\n    // for comparison with staking epoch\n    uint48 timestamp;\n}\n\n/**\n * @title AttributeCheckpointFraud\n * @dev The AttributeCheckpointFraud contract is used to attribute fraud to a specific ECDSA checkpoint signer.\n */\n\ncontract AttributeCheckpointFraud is Ownable, PackageVersioned {\n    using CheckpointLib for Checkpoint;\n    using Address for address;\n\n    CheckpointFraudProofs public immutable checkpointFraudProofs =\n        new CheckpointFraudProofs();\n\n    mapping(address merkleTree => bool isWhitelisted)\n        public merkleTreeWhitelist;\n\n    mapping(address signer => mapping(bytes32 digest => Attribution))\n        internal _attributions;\n\n    function _recover(\n        Checkpoint calldata checkpoint,\n        bytes calldata signature\n    ) internal pure returns (address signer, bytes32 digest) {\n        digest = checkpoint.digest();\n        signer = ECDSA.recover(digest, signature);\n    }\n\n    function _attribute(\n        bytes calldata signature,\n        Checkpoint calldata checkpoint,\n        FraudType fraudType\n    ) internal {\n        (address signer, bytes32 digest) = _recover(checkpoint, signature);\n        require(\n            _attributions[signer][digest].timestamp == 0,\n            \"fraud already attributed to signer for digest\"\n        );\n        _attributions[signer][digest] = Attribution({\n            fraudType: fraudType,\n            timestamp: uint48(block.timestamp)\n        });\n    }\n\n    function attributions(\n        Checkpoint calldata checkpoint,\n        bytes calldata signature\n    ) external view returns (Attribution memory) {\n        (address signer, bytes32 digest) = _recover(checkpoint, signature);\n        return _attributions[signer][digest];\n    }\n\n    function whitelist(address merkleTree) external onlyOwner {\n        require(\n            merkleTree.isContract(),\n            \"merkle tree must be a valid contract\"\n        );\n        merkleTreeWhitelist[merkleTree] = true;\n    }\n\n    function attributeWhitelist(\n        Checkpoint calldata checkpoint,\n        bytes calldata signature\n    ) external {\n        require(\n            checkpointFraudProofs.isLocal(checkpoint),\n            \"checkpoint must be local\"\n        );\n\n        require(\n            !merkleTreeWhitelist[checkpoint.merkleTreeAddress()],\n            \"merkle tree is whitelisted\"\n        );\n\n        _attribute(signature, checkpoint, FraudType.Whitelist);\n    }\n\n    function attributePremature(\n        Checkpoint calldata checkpoint,\n        bytes calldata signature\n    ) external {\n        require(\n            checkpointFraudProofs.isPremature(checkpoint),\n            \"checkpoint must be premature\"\n        );\n\n        _attribute(signature, checkpoint, FraudType.Premature);\n    }\n\n    function attributeMessageId(\n        Checkpoint calldata checkpoint,\n        bytes32[TREE_DEPTH] calldata proof,\n        bytes32 actualMessageId,\n        bytes calldata signature\n    ) external {\n        require(\n            checkpointFraudProofs.isFraudulentMessageId(\n                checkpoint,\n                proof,\n                actualMessageId\n            ),\n            \"checkpoint must have fraudulent message ID\"\n        );\n\n        _attribute(signature, checkpoint, FraudType.MessageId);\n    }\n\n    function attributeRoot(\n        Checkpoint calldata checkpoint,\n        bytes32[TREE_DEPTH] calldata proof,\n        bytes calldata signature\n    ) external {\n        require(\n            checkpointFraudProofs.isFraudulentRoot(checkpoint, proof),\n            \"checkpoint must have fraudulent root\"\n        );\n\n        _attribute(signature, checkpoint, FraudType.Root);\n    }\n}\n"},"contracts/avs/ECDSAServiceManagerBase.sol":{"content":"// SPDX-License-Identifier: BUSL-1.1\npragma solidity >=0.8.0;\n\nimport {ISignatureUtils} from \"../interfaces/avs/vendored/ISignatureUtils.sol\";\nimport {IAVSDirectory} from \"../interfaces/avs/vendored/IAVSDirectory.sol\";\n\nimport {IServiceManager} from \"../interfaces/avs/vendored/IServiceManager.sol\";\nimport {IServiceManagerUI} from \"../interfaces/avs/vendored/IServiceManagerUI.sol\";\nimport {IDelegationManager} from \"../interfaces/avs/vendored/IDelegationManager.sol\";\nimport {IStrategy} from \"../interfaces/avs/vendored/IStrategy.sol\";\nimport {IPaymentCoordinator} from \"../interfaces/avs/vendored/IPaymentCoordinator.sol\";\nimport {Quorum} from \"../interfaces/avs/vendored/IECDSAStakeRegistryEventsAndErrors.sol\";\nimport {ECDSAStakeRegistry} from \"./ECDSAStakeRegistry.sol\";\n\nimport {OwnableUpgradeable} from \"@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol\";\n\n/// @author Layr Labs, Inc.\nabstract contract ECDSAServiceManagerBase is\n    IServiceManager,\n    OwnableUpgradeable\n{\n    /// @notice Address of the stake registry contract, which manages registration and stake recording.\n    address public immutable stakeRegistry;\n\n    /// @notice Address of the AVS directory contract, which manages AVS-related data for registered operators.\n    address public immutable avsDirectory;\n\n    /// @notice Address of the delegation manager contract, which manages staker delegations to operators.\n    address internal immutable delegationManager;\n\n    // ============ Public Storage ============\n\n    /// @notice Address of the payment coordinator contract, which handles payment distributions. Will be set once live on Eigenlayer.\n    address internal paymentCoordinator;\n\n    // ============ Modifiers ============\n\n    /**\n     * @dev Ensures that the function is only callable by the `stakeRegistry` contract.\n     * This is used to restrict certain registration and deregistration functionality to the `stakeRegistry`\n     */\n    modifier onlyStakeRegistry() {\n        require(\n            msg.sender == stakeRegistry,\n            \"ECDSAServiceManagerBase.onlyStakeRegistry: caller is not the stakeRegistry\"\n        );\n        _;\n    }\n\n    // ============ Events ============\n\n    /**\n     * @notice Emitted when an operator is registered to the AVS\n     * @param operator The address of the operator\n     */\n    event OperatorRegisteredToAVS(address indexed operator);\n\n    /**\n     * @notice Emitted when an operator is deregistered from the AVS\n     * @param operator The address of the operator\n     */\n    event OperatorDeregisteredFromAVS(address indexed operator);\n\n    // ============ Constructor ============\n\n    /**\n     * @dev Constructor for ECDSAServiceManagerBase, initializing immutable contract addresses and disabling initializers.\n     * @param _avsDirectory The address of the AVS directory contract, managing AVS-related data for registered operators.\n     * @param _stakeRegistry The address of the stake registry contract, managing registration and stake recording.\n     * @param _paymentCoordinator The address of the payment coordinator contract, handling payment distributions.\n     * @param _delegationManager The address of the delegation manager contract, managing staker delegations to operators.\n     */\n    constructor(\n        address _avsDirectory,\n        address _stakeRegistry,\n        address _paymentCoordinator,\n        address _delegationManager\n    ) {\n        avsDirectory = _avsDirectory;\n        stakeRegistry = _stakeRegistry;\n        paymentCoordinator = _paymentCoordinator;\n        delegationManager = _delegationManager;\n    }\n\n    /**\n     * @dev Initializes the base service manager by transferring ownership to the initial owner.\n     * @param initialOwner The address to which the ownership of the contract will be transferred.\n     */\n    function __ServiceManagerBase_init(\n        address initialOwner\n    ) internal virtual onlyInitializing {\n        _transferOwnership(initialOwner);\n    }\n\n    /// @inheritdoc IServiceManagerUI\n    function updateAVSMetadataURI(\n        string memory _metadataURI\n    ) external virtual onlyOwner {\n        _updateAVSMetadataURI(_metadataURI);\n    }\n\n    /// @inheritdoc IServiceManager\n    function payForRange(\n        IPaymentCoordinator.RangePayment[] calldata rangePayments\n    ) external virtual onlyOwner {\n        _payForRange(rangePayments);\n    }\n\n    /// @inheritdoc IServiceManagerUI\n    function registerOperatorToAVS(\n        address operator,\n        ISignatureUtils.SignatureWithSaltAndExpiry memory operatorSignature\n    ) external virtual onlyStakeRegistry {\n        _registerOperatorToAVS(operator, operatorSignature);\n    }\n\n    /// @inheritdoc IServiceManagerUI\n    function deregisterOperatorFromAVS(\n        address operator\n    ) external virtual onlyStakeRegistry {\n        _deregisterOperatorFromAVS(operator);\n    }\n\n    /// @inheritdoc IServiceManagerUI\n    function getRestakeableStrategies()\n        external\n        view\n        virtual\n        returns (address[] memory)\n    {\n        return _getRestakeableStrategies();\n    }\n\n    /// @inheritdoc IServiceManagerUI\n    function getOperatorRestakedStrategies(\n        address _operator\n    ) external view virtual returns (address[] memory) {\n        return _getOperatorRestakedStrategies(_operator);\n    }\n\n    /**\n     * @notice Sets the address of the payment coordinator contract.\n     * @dev This function is only callable by the contract owner.\n     * @param _paymentCoordinator The address of the payment coordinator contract.\n     */\n    function setPaymentCoordinator(\n        address _paymentCoordinator\n    ) external virtual onlyOwner {\n        paymentCoordinator = _paymentCoordinator;\n    }\n\n    /**\n     * @notice Forwards the call to update AVS metadata URI in the AVSDirectory contract.\n     * @dev This internal function is a proxy to the `updateAVSMetadataURI` function of the AVSDirectory contract.\n     * @param _metadataURI The new metadata URI to be set.\n     */\n    function _updateAVSMetadataURI(\n        string memory _metadataURI\n    ) internal virtual {\n        IAVSDirectory(avsDirectory).updateAVSMetadataURI(_metadataURI);\n    }\n\n    /**\n     * @notice Forwards the call to register an operator in the AVSDirectory contract.\n     * @dev This internal function is a proxy to the `registerOperatorToAVS` function of the AVSDirectory contract.\n     * @param operator The address of the operator to register.\n     * @param operatorSignature The signature, salt, and expiry details of the operator's registration.\n     */\n    function _registerOperatorToAVS(\n        address operator,\n        ISignatureUtils.SignatureWithSaltAndExpiry memory operatorSignature\n    ) internal virtual {\n        IAVSDirectory(avsDirectory).registerOperatorToAVS(\n            operator,\n            operatorSignature\n        );\n        emit OperatorRegisteredToAVS(operator);\n    }\n\n    /**\n     * @notice Forwards the call to deregister an operator from the AVSDirectory contract.\n     * @dev This internal function is a proxy to the `deregisterOperatorFromAVS` function of the AVSDirectory contract.\n     * @param operator The address of the operator to deregister.\n     */\n    function _deregisterOperatorFromAVS(address operator) internal virtual {\n        IAVSDirectory(avsDirectory).deregisterOperatorFromAVS(operator);\n        emit OperatorDeregisteredFromAVS(operator);\n    }\n\n    /**\n     * @notice Processes a batch of range payments by transferring the specified amounts from the sender to this contract and then approving the PaymentCoordinator to use these amounts.\n     * @dev This function handles the transfer and approval of tokens necessary for range payments. It then delegates the actual payment logic to the PaymentCoordinator contract.\n     * @param rangePayments An array of `RangePayment` structs, each representing a payment for a specific range.\n     */\n    function _payForRange(\n        IPaymentCoordinator.RangePayment[] calldata rangePayments\n    ) internal virtual {\n        for (uint256 i = 0; i < rangePayments.length; ++i) {\n            rangePayments[i].token.transferFrom(\n                msg.sender,\n                address(this),\n                rangePayments[i].amount\n            );\n            rangePayments[i].token.approve(\n                paymentCoordinator,\n                rangePayments[i].amount\n            );\n        }\n\n        IPaymentCoordinator(paymentCoordinator).payForRange(rangePayments);\n    }\n\n    /**\n     * @notice Retrieves the addresses of all strategies that are part of the current quorum.\n     * @dev Fetches the quorum configuration from the ECDSAStakeRegistry and extracts the strategy addresses.\n     * @return strategies An array of addresses representing the strategies in the current quorum.\n     */\n    function _getRestakeableStrategies()\n        internal\n        view\n        virtual\n        returns (address[] memory)\n    {\n        Quorum memory quorum = ECDSAStakeRegistry(stakeRegistry).quorum();\n        address[] memory strategies = new address[](quorum.strategies.length);\n        for (uint256 i = 0; i < quorum.strategies.length; i++) {\n            strategies[i] = address(quorum.strategies[i].strategy);\n        }\n        return strategies;\n    }\n\n    /**\n     * @notice Retrieves the addresses of strategies where the operator has restaked.\n     * @dev This function fetches the quorum details from the ECDSAStakeRegistry, retrieves the operator's shares for each strategy,\n     * and filters out strategies with non-zero shares indicating active restaking by the operator.\n     * @param _operator The address of the operator whose restaked strategies are to be retrieved.\n     * @return restakedStrategies An array of addresses of strategies where the operator has active restakes.\n     */\n    function _getOperatorRestakedStrategies(\n        address _operator\n    ) internal view virtual returns (address[] memory) {\n        Quorum memory quorum = ECDSAStakeRegistry(stakeRegistry).quorum();\n        uint256 count = quorum.strategies.length;\n        IStrategy[] memory strategies = new IStrategy[](count);\n        for (uint256 i; i < count; i++) {\n            strategies[i] = quorum.strategies[i].strategy;\n        }\n        uint256[] memory shares = IDelegationManager(delegationManager)\n            .getOperatorShares(_operator, strategies);\n\n        uint256 activeCount;\n        for (uint256 i; i < count; i++) {\n            if (shares[i] > 0) {\n                activeCount++;\n            }\n        }\n\n        // Resize the array to fit only the active strategies\n        address[] memory restakedStrategies = new address[](activeCount);\n        uint256 index;\n        for (uint256 j = 0; j < count; j++) {\n            if (shares[j] > 0) {\n                restakedStrategies[index] = address(strategies[j]);\n                index++;\n            }\n        }\n\n        return restakedStrategies;\n    }\n\n    // storage gap for upgradeability\n    // slither-disable-next-line shadowing-state\n    uint256[50] private __GAP;\n}\n"},"contracts/avs/ECDSAStakeRegistry.sol":{"content":"// SPDX-License-Identifier: MIT\npragma solidity ^0.8.12;\n\nimport {ECDSAStakeRegistryStorage, Quorum} from \"./ECDSAStakeRegistryStorage.sol\";\nimport {StrategyParams} from \"../interfaces/avs/vendored/IECDSAStakeRegistryEventsAndErrors.sol\";\n\nimport {IStrategy} from \"../interfaces/avs/vendored/IStrategy.sol\";\nimport {IDelegationManager} from \"../interfaces/avs/vendored/IDelegationManager.sol\";\nimport {ISignatureUtils} from \"../interfaces/avs/vendored/ISignatureUtils.sol\";\nimport {IServiceManager} from \"../interfaces/avs/vendored/IServiceManager.sol\";\n\nimport {PackageVersioned} from \"../PackageVersioned.sol\";\n\nimport {OwnableUpgradeable} from \"@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol\";\nimport {CheckpointsUpgradeable} from \"@openzeppelin/contracts-upgradeable/utils/CheckpointsUpgradeable.sol\";\nimport {SignatureCheckerUpgradeable} from \"@openzeppelin/contracts-upgradeable/utils/cryptography/SignatureCheckerUpgradeable.sol\";\nimport {IERC1271Upgradeable} from \"@openzeppelin/contracts-upgradeable/interfaces/IERC1271Upgradeable.sol\";\n\n/// @title ECDSA Stake Registry\n/// @author Layr Labs, Inc.\n/// @dev THIS CONTRACT IS NOT AUDITED\n/// @notice Manages operator registration and quorum updates for an AVS using ECDSA signatures.\ncontract ECDSAStakeRegistry is\n    IERC1271Upgradeable,\n    OwnableUpgradeable,\n    ECDSAStakeRegistryStorage,\n    PackageVersioned\n{\n    using SignatureCheckerUpgradeable for address;\n    using CheckpointsUpgradeable for CheckpointsUpgradeable.History;\n\n    /// @dev Constructor to create ECDSAStakeRegistry.\n    /// @param _delegationManager Address of the DelegationManager contract that this registry interacts with.\n    constructor(\n        IDelegationManager _delegationManager\n    ) ECDSAStakeRegistryStorage(_delegationManager) {\n        // _disableInitializers();\n    }\n\n    /// @notice Initializes the contract with the given parameters.\n    /// @param _serviceManager The address of the service manager.\n    /// @param _thresholdWeight The threshold weight in basis points.\n    /// @param _quorum The quorum struct containing the details of the quorum thresholds.\n    function initialize(\n        address _serviceManager,\n        uint256 _thresholdWeight,\n        Quorum memory _quorum\n    ) external initializer {\n        __ECDSAStakeRegistry_init(_serviceManager, _thresholdWeight, _quorum);\n    }\n\n    /// @notice Registers a new operator using a provided signature and signing key\n    /// @param _operatorSignature Contains the operator's signature, salt, and expiry\n    /// @param _signingKey The signing key to add to the operator's history\n    function registerOperatorWithSignature(\n        ISignatureUtils.SignatureWithSaltAndExpiry memory _operatorSignature,\n        address _signingKey\n    ) external {\n        _registerOperatorWithSig(msg.sender, _operatorSignature, _signingKey);\n    }\n\n    /// @notice Deregisters an existing operator\n    function deregisterOperator() external {\n        _deregisterOperator(msg.sender);\n    }\n\n    /**\n     * @notice Updates the signing key for an operator\n     * @dev Only callable by the operator themselves\n     * @param _newSigningKey The new signing key to set for the operator\n     */\n    function updateOperatorSigningKey(address _newSigningKey) external {\n        if (!_operatorRegistered[msg.sender]) {\n            revert OperatorNotRegistered();\n        }\n        _updateOperatorSigningKey(msg.sender, _newSigningKey);\n    }\n\n    /**\n     * @notice Updates the StakeRegistry's view of one or more operators' stakes adding a new entry in their history of stake checkpoints,\n     * @dev Queries stakes from the Eigenlayer core DelegationManager contract\n     * @param _operators A list of operator addresses to update\n     */\n    function updateOperators(address[] memory _operators) external {\n        _updateOperators(_operators);\n    }\n\n    /**\n     * @notice Updates the quorum configuration and the set of operators\n     * @dev Only callable by the contract owner.\n     * It first updates the quorum configuration and then updates the list of operators.\n     * @param _quorum The new quorum configuration, including strategies and their new weights\n     * @param _operators The list of operator addresses to update stakes for\n     */\n    function updateQuorumConfig(\n        Quorum memory _quorum,\n        address[] memory _operators\n    ) external onlyOwner {\n        _updateQuorumConfig(_quorum);\n        _updateOperators(_operators);\n    }\n\n    /// @notice Updates the weight an operator must have to join the operator set\n    /// @dev Access controlled to the contract owner\n    /// @param _newMinimumWeight The new weight an operator must have to join the operator set\n    function updateMinimumWeight(\n        uint256 _newMinimumWeight,\n        address[] memory _operators\n    ) external onlyOwner {\n        _updateMinimumWeight(_newMinimumWeight);\n        _updateOperators(_operators);\n    }\n\n    /**\n     * @notice Sets a new cumulative threshold weight for message validation by operator set signatures.\n     * @dev This function can only be invoked by the owner of the contract. It delegates the update to\n     * an internal function `_updateStakeThreshold`.\n     * @param _thresholdWeight The updated threshold weight required to validate a message. This is the\n     * cumulative weight that must be met or exceeded by the sum of the stakes of the signatories for\n     * a message to be deemed valid.\n     */\n    function updateStakeThreshold(uint256 _thresholdWeight) external onlyOwner {\n        _updateStakeThreshold(_thresholdWeight);\n    }\n\n    /// @notice Verifies if the provided signature data is valid for the given data hash.\n    /// @param _dataHash The hash of the data that was signed.\n    /// @param _signatureData Encoded signature data consisting of an array of operators, an array of signatures, and a reference block number.\n    /// @return The function selector that indicates the signature is valid according to ERC1271 standard.\n    function isValidSignature(\n        bytes32 _dataHash,\n        bytes memory _signatureData\n    ) external view returns (bytes4) {\n        (\n            address[] memory operators,\n            bytes[] memory signatures,\n            uint32 referenceBlock\n        ) = abi.decode(_signatureData, (address[], bytes[], uint32));\n        _checkSignatures(_dataHash, operators, signatures, referenceBlock);\n        return IERC1271Upgradeable.isValidSignature.selector;\n    }\n\n    /// @notice Retrieves the current stake quorum details.\n    /// @return Quorum - The current quorum of strategies and weights\n    function quorum() external view returns (Quorum memory) {\n        return _quorum;\n    }\n\n    /**\n     * @notice Retrieves the latest signing key for a given operator.\n     * @param _operator The address of the operator.\n     * @return The latest signing key of the operator.\n     */\n    function getLastestOperatorSigningKey(\n        address _operator\n    ) external view returns (address) {\n        return address(uint160(_operatorSigningKeyHistory[_operator].latest()));\n    }\n\n    /**\n     * @notice Retrieves the latest signing key for a given operator at a specific block number.\n     * @param _operator The address of the operator.\n     * @param _blockNumber The block number to get the operator's signing key.\n     * @return The signing key of the operator at the given block.\n     */\n    function getOperatorSigningKeyAtBlock(\n        address _operator,\n        uint256 _blockNumber\n    ) external view returns (address) {\n        return\n            address(\n                uint160(\n                    _operatorSigningKeyHistory[_operator].getAtBlock(\n                        _blockNumber\n                    )\n                )\n            );\n    }\n\n    /// @notice Retrieves the last recorded weight for a given operator.\n    /// @param _operator The address of the operator.\n    /// @return uint256 - The latest weight of the operator.\n    function getLastCheckpointOperatorWeight(\n        address _operator\n    ) external view returns (uint256) {\n        return _operatorWeightHistory[_operator].latest();\n    }\n\n    /// @notice Retrieves the last recorded total weight across all operators.\n    /// @return uint256 - The latest total weight.\n    function getLastCheckpointTotalWeight() external view returns (uint256) {\n        return _totalWeightHistory.latest();\n    }\n\n    /// @notice Retrieves the last recorded threshold weight\n    /// @return uint256 - The latest threshold weight.\n    function getLastCheckpointThresholdWeight()\n        external\n        view\n        returns (uint256)\n    {\n        return _thresholdWeightHistory.latest();\n    }\n\n    /// @notice Retrieves the operator's weight at a specific block number.\n    /// @param _operator The address of the operator.\n    /// @param _blockNumber The block number to get the operator weight for the quorum\n    /// @return uint256 - The weight of the operator at the given block.\n    function getOperatorWeightAtBlock(\n        address _operator,\n        uint32 _blockNumber\n    ) external view returns (uint256) {\n        return _operatorWeightHistory[_operator].getAtBlock(_blockNumber);\n    }\n\n    /// @notice Retrieves the total weight at a specific block number.\n    /// @param _blockNumber The block number to get the total weight for the quorum\n    /// @return uint256 - The total weight at the given block.\n    function getLastCheckpointTotalWeightAtBlock(\n        uint32 _blockNumber\n    ) external view returns (uint256) {\n        return _totalWeightHistory.getAtBlock(_blockNumber);\n    }\n\n    /// @notice Retrieves the threshold weight at a specific block number.\n    /// @param _blockNumber The block number to get the threshold weight for the quorum\n    /// @return uint256 - The threshold weight the given block.\n    function getLastCheckpointThresholdWeightAtBlock(\n        uint32 _blockNumber\n    ) external view returns (uint256) {\n        return _thresholdWeightHistory.getAtBlock(_blockNumber);\n    }\n\n    function operatorRegistered(\n        address _operator\n    ) external view returns (bool) {\n        return _operatorRegistered[_operator];\n    }\n\n    /// @notice Returns the weight an operator must have to contribute to validating an AVS\n    function minimumWeight() external view returns (uint256) {\n        return _minimumWeight;\n    }\n\n    /// @notice Calculates the current weight of an operator based on their delegated stake in the strategies considered in the quorum\n    /// @param _operator The address of the operator.\n    /// @return uint256 - The current weight of the operator; returns 0 if below the threshold.\n    function getOperatorWeight(\n        address _operator\n    ) public view returns (uint256) {\n        StrategyParams[] memory strategyParams = _quorum.strategies;\n        uint256 weight;\n        IStrategy[] memory strategies = new IStrategy[](strategyParams.length);\n        for (uint256 i; i < strategyParams.length; i++) {\n            strategies[i] = strategyParams[i].strategy;\n        }\n        uint256[] memory shares = DELEGATION_MANAGER.getOperatorShares(\n            _operator,\n            strategies\n        );\n        for (uint256 i; i < strategyParams.length; i++) {\n            weight += shares[i] * strategyParams[i].multiplier;\n        }\n        weight = weight / BPS;\n\n        if (weight >= _minimumWeight) {\n            return weight;\n        } else {\n            return 0;\n        }\n    }\n\n    /// @notice Initializes state for the StakeRegistry\n    /// @param _serviceManagerAddr The AVS' ServiceManager contract's address\n    function __ECDSAStakeRegistry_init(\n        address _serviceManagerAddr,\n        uint256 _thresholdWeight,\n        Quorum memory _quorum\n    ) internal onlyInitializing {\n        _serviceManager = _serviceManagerAddr;\n        _updateStakeThreshold(_thresholdWeight);\n        _updateQuorumConfig(_quorum);\n        __Ownable_init();\n    }\n\n    /// @notice Updates the set of operators for the first quorum.\n    /// @param operatorsPerQuorum An array of operator address arrays, one for each quorum.\n    /// @dev This interface maintains compatibility with avs-sync which handles multiquorums while this registry has a single quorum\n    function updateOperatorsForQuorum(\n        address[][] memory operatorsPerQuorum,\n        bytes memory\n    ) external {\n        _updateAllOperators(operatorsPerQuorum[0]);\n    }\n\n    /// @dev Updates the list of operators if the provided list has the correct number of operators.\n    /// Reverts if the provided list of operators does not match the expected total count of operators.\n    /// @param _operators The list of operator addresses to update.\n    function _updateAllOperators(address[] memory _operators) internal {\n        if (_operators.length != _totalOperators) {\n            revert MustUpdateAllOperators();\n        }\n        _updateOperators(_operators);\n    }\n\n    /// @dev Updates the weights for a given list of operator addresses.\n    /// When passing an operator that isn't registered, then 0 is added to their history\n    /// @param _operators An array of addresses for which to update the weights.\n    function _updateOperators(address[] memory _operators) internal {\n        int256 delta;\n        for (uint256 i; i < _operators.length; i++) {\n            delta += _updateOperatorWeight(_operators[i]);\n        }\n        _updateTotalWeight(delta);\n    }\n\n    /// @dev Updates the stake threshold weight and records the history.\n    /// @param _thresholdWeight The new threshold weight to set and record in the history.\n    function _updateStakeThreshold(uint256 _thresholdWeight) internal {\n        _thresholdWeightHistory.push(_thresholdWeight);\n        emit ThresholdWeightUpdated(_thresholdWeight);\n    }\n\n    /// @dev Updates the weight an operator must have to join the operator set\n    /// @param _newMinimumWeight The new weight an operator must have to join the operator set\n    function _updateMinimumWeight(uint256 _newMinimumWeight) internal {\n        uint256 oldMinimumWeight = _minimumWeight;\n        _minimumWeight = _newMinimumWeight;\n        emit MinimumWeightUpdated(oldMinimumWeight, _newMinimumWeight);\n    }\n\n    /// @notice Updates the quorum configuration\n    /// @dev Replaces the current quorum configuration with `_newQuorum` if valid.\n    /// Reverts with `InvalidQuorum` if the new quorum configuration is not valid.\n    /// Emits `QuorumUpdated` event with the old and new quorum configurations.\n    /// @param _newQuorum The new quorum configuration to set.\n    function _updateQuorumConfig(Quorum memory _newQuorum) internal {\n        if (!_isValidQuorum(_newQuorum)) {\n            revert InvalidQuorum();\n        }\n        Quorum memory oldQuorum = _quorum;\n        delete _quorum;\n        for (uint256 i; i < _newQuorum.strategies.length; i++) {\n            _quorum.strategies.push(_newQuorum.strategies[i]);\n        }\n        emit QuorumUpdated(oldQuorum, _newQuorum);\n    }\n\n    /// @dev Internal function to deregister an operator\n    /// @param _operator The operator's address to deregister\n    function _deregisterOperator(address _operator) internal {\n        if (!_operatorRegistered[_operator]) {\n            revert OperatorNotRegistered();\n        }\n        _totalOperators--;\n        delete _operatorRegistered[_operator];\n        int256 delta = _updateOperatorWeight(_operator);\n        _updateTotalWeight(delta);\n        IServiceManager(_serviceManager).deregisterOperatorFromAVS(_operator);\n        emit OperatorDeregistered(_operator, address(_serviceManager));\n    }\n\n    /// @dev registers an operator through a provided signature\n    /// @param _operatorSignature Contains the operator's signature, salt, and expiry\n    /// @param _signingKey The signing key to add to the operator's history\n    function _registerOperatorWithSig(\n        address _operator,\n        ISignatureUtils.SignatureWithSaltAndExpiry memory _operatorSignature,\n        address _signingKey\n    ) internal virtual {\n        if (_operatorRegistered[_operator]) {\n            revert OperatorAlreadyRegistered();\n        }\n        _totalOperators++;\n        _operatorRegistered[_operator] = true;\n        int256 delta = _updateOperatorWeight(_operator);\n        _updateTotalWeight(delta);\n        _updateOperatorSigningKey(_operator, _signingKey);\n        IServiceManager(_serviceManager).registerOperatorToAVS(\n            _operator,\n            _operatorSignature\n        );\n        emit OperatorRegistered(_operator, _serviceManager);\n    }\n\n    /// @dev Internal function to update an operator's signing key\n    /// @param _operator The address of the operator to update the signing key for\n    /// @param _newSigningKey The new signing key to set for the operator\n    function _updateOperatorSigningKey(\n        address _operator,\n        address _newSigningKey\n    ) internal {\n        address oldSigningKey = address(\n            uint160(_operatorSigningKeyHistory[_operator].latest())\n        );\n        if (_newSigningKey == oldSigningKey) {\n            return;\n        }\n        _operatorSigningKeyHistory[_operator].push(uint160(_newSigningKey));\n        emit SigningKeyUpdate(\n            _operator,\n            block.number,\n            _newSigningKey,\n            oldSigningKey\n        );\n    }\n\n    /// @notice Updates the weight of an operator and returns the previous and current weights.\n    /// @param _operator The address of the operator to update the weight of.\n    function _updateOperatorWeight(\n        address _operator\n    ) internal virtual returns (int256) {\n        int256 delta;\n        uint256 newWeight;\n        uint256 oldWeight = _operatorWeightHistory[_operator].latest();\n        if (!_operatorRegistered[_operator]) {\n            delta -= int256(oldWeight);\n            if (delta == 0) {\n                return delta;\n            }\n            _operatorWeightHistory[_operator].push(0);\n        } else {\n            newWeight = getOperatorWeight(_operator);\n            delta = int256(newWeight) - int256(oldWeight);\n            if (delta == 0) {\n                return delta;\n            }\n            _operatorWeightHistory[_operator].push(newWeight);\n        }\n        emit OperatorWeightUpdated(_operator, oldWeight, newWeight);\n        return delta;\n    }\n\n    /// @dev Internal function to update the total weight of the stake\n    /// @param delta The change in stake applied last total weight\n    /// @return oldTotalWeight The weight before the update\n    /// @return newTotalWeight The updated weight after applying the delta\n    function _updateTotalWeight(\n        int256 delta\n    ) internal returns (uint256 oldTotalWeight, uint256 newTotalWeight) {\n        oldTotalWeight = _totalWeightHistory.latest();\n        int256 newWeight = int256(oldTotalWeight) + delta;\n        newTotalWeight = uint256(newWeight);\n        _totalWeightHistory.push(newTotalWeight);\n        emit TotalWeightUpdated(oldTotalWeight, newTotalWeight);\n    }\n\n    /**\n     * @dev Verifies that a specified quorum configuration is valid. A valid quorum has:\n     *      1. Weights that sum to exactly 10,000 basis points, ensuring proportional representation.\n     *      2. Unique strategies without duplicates to maintain quorum integrity.\n     * @param _quorum The quorum configuration to be validated.\n     * @return bool True if the quorum configuration is valid, otherwise false.\n     */\n    function _isValidQuorum(\n        Quorum memory _quorum\n    ) internal pure returns (bool) {\n        StrategyParams[] memory strategies = _quorum.strategies;\n        address lastStrategy;\n        address currentStrategy;\n        uint256 totalMultiplier;\n        for (uint256 i; i < strategies.length; i++) {\n            currentStrategy = address(strategies[i].strategy);\n            if (lastStrategy >= currentStrategy) revert NotSorted();\n            lastStrategy = currentStrategy;\n            totalMultiplier += strategies[i].multiplier;\n        }\n        if (totalMultiplier != BPS) {\n            return false;\n        } else {\n            return true;\n        }\n    }\n\n    /**\n     * @notice Common logic to verify a batch of ECDSA signatures against a hash, using either last stake weight or at a specific block.\n     * @param _dataHash The hash of the data the signers endorsed.\n     * @param _operators A collection of addresses that endorsed the data hash.\n     * @param _signatures A collection of signatures matching the signers.\n     * @param _referenceBlock The block number for evaluating stake weight; use max uint32 for latest weight.\n     */\n    function _checkSignatures(\n        bytes32 _dataHash,\n        address[] memory _operators,\n        bytes[] memory _signatures,\n        uint32 _referenceBlock\n    ) internal view {\n        uint256 signersLength = _operators.length;\n        address currentOperator;\n        address lastOperator;\n        address signer;\n        uint256 signedWeight;\n\n        _validateSignaturesLength(signersLength, _signatures.length);\n        for (uint256 i; i < signersLength; i++) {\n            currentOperator = _operators[i];\n            signer = _getOperatorSigningKey(currentOperator, _referenceBlock);\n\n            _validateSortedSigners(lastOperator, currentOperator);\n            _validateSignature(signer, _dataHash, _signatures[i]);\n\n            lastOperator = currentOperator;\n            uint256 operatorWeight = _getOperatorWeight(\n                currentOperator,\n                _referenceBlock\n            );\n            signedWeight += operatorWeight;\n        }\n\n        _validateThresholdStake(signedWeight, _referenceBlock);\n    }\n\n    /// @notice Validates that the number of signers equals the number of signatures, and neither is zero.\n    /// @param _signersLength The number of signers.\n    /// @param _signaturesLength The number of signatures.\n    function _validateSignaturesLength(\n        uint256 _signersLength,\n        uint256 _signaturesLength\n    ) internal pure {\n        if (_signersLength != _signaturesLength) {\n            revert LengthMismatch();\n        }\n        if (_signersLength == 0) {\n            revert InvalidLength();\n        }\n    }\n\n    /// @notice Ensures that signers are sorted in ascending order by address.\n    /// @param _lastSigner The address of the last signer.\n    /// @param _currentSigner The address of the current signer.\n    function _validateSortedSigners(\n        address _lastSigner,\n        address _currentSigner\n    ) internal pure {\n        if (_lastSigner >= _currentSigner) {\n            revert NotSorted();\n        }\n    }\n\n    /// @notice Validates a given signature against the signer's address and data hash.\n    /// @param _signer The address of the signer to validate.\n    /// @param _dataHash The hash of the data that is signed.\n    /// @param _signature The signature to validate.\n    function _validateSignature(\n        address _signer,\n        bytes32 _dataHash,\n        bytes memory _signature\n    ) internal view {\n        if (!_signer.isValidSignatureNow(_dataHash, _signature)) {\n            revert InvalidSignature();\n        }\n    }\n\n    /// @notice Retrieves the operator weight for a signer, either at the last checkpoint or a specified block.\n    /// @param _operator The operator to query their signing key history for\n    /// @param _referenceBlock The block number to query the operator's weight at, or the maximum uint32 value for the last checkpoint.\n    /// @return The weight of the operator.\n    function _getOperatorSigningKey(\n        address _operator,\n        uint32 _referenceBlock\n    ) internal view returns (address) {\n        if (_referenceBlock >= block.number) {\n            revert InvalidReferenceBlock();\n        }\n        return\n            address(\n                uint160(\n                    _operatorSigningKeyHistory[_operator].getAtBlock(\n                        _referenceBlock\n                    )\n                )\n            );\n    }\n\n    /// @notice Retrieves the operator weight for a signer, either at the last checkpoint or a specified block.\n    /// @param _signer The address of the signer whose weight is returned.\n    /// @param _referenceBlock The block number to query the operator's weight at, or the maximum uint32 value for the last checkpoint.\n    /// @return The weight of the operator.\n    function _getOperatorWeight(\n        address _signer,\n        uint32 _referenceBlock\n    ) internal view returns (uint256) {\n        if (_referenceBlock >= block.number) {\n            revert InvalidReferenceBlock();\n        }\n        return _operatorWeightHistory[_signer].getAtBlock(_referenceBlock);\n    }\n\n    /// @notice Retrieve the total stake weight at a specific block or the latest if not specified.\n    /// @dev If the `_referenceBlock` is the maximum value for uint32, the latest total weight is returned.\n    /// @param _referenceBlock The block number to retrieve the total stake weight from.\n    /// @return The total stake weight at the given block or the latest if the given block is the max uint32 value.\n    function _getTotalWeight(\n        uint32 _referenceBlock\n    ) internal view returns (uint256) {\n        if (_referenceBlock >= block.number) {\n            revert InvalidReferenceBlock();\n        }\n        return _totalWeightHistory.getAtBlock(_referenceBlock);\n    }\n\n    /// @notice Retrieves the threshold stake for a given reference block.\n    /// @param _referenceBlock The block number to query the threshold stake for.\n    /// If set to the maximum uint32 value, it retrieves the latest threshold stake.\n    /// @return The threshold stake in basis points for the reference block.\n    function _getThresholdStake(\n        uint32 _referenceBlock\n    ) internal view returns (uint256) {\n        if (_referenceBlock >= block.number) {\n            revert InvalidReferenceBlock();\n        }\n        return _thresholdWeightHistory.getAtBlock(_referenceBlock);\n    }\n\n    /// @notice Validates that the cumulative stake of signed messages meets or exceeds the required threshold.\n    /// @param _signedWeight The cumulative weight of the signers that have signed the message.\n    /// @param _referenceBlock The block number to verify the stake threshold for\n    function _validateThresholdStake(\n        uint256 _signedWeight,\n        uint32 _referenceBlock\n    ) internal view {\n        uint256 totalWeight = _getTotalWeight(_referenceBlock);\n        if (_signedWeight > totalWeight) {\n            revert InvalidSignedWeight();\n        }\n        uint256 thresholdStake = _getThresholdStake(_referenceBlock);\n        if (thresholdStake > _signedWeight) {\n            revert InsufficientSignedStake();\n        }\n    }\n}\n"},"contracts/avs/ECDSAStakeRegistryStorage.sol":{"content":"// SPDX-License-Identifier: MIT\npragma solidity ^0.8.12;\n\nimport {IDelegationManager} from \"../interfaces/avs/vendored/IDelegationManager.sol\";\nimport {CheckpointsUpgradeable} from \"@openzeppelin/contracts-upgradeable/utils/CheckpointsUpgradeable.sol\";\nimport {IECDSAStakeRegistryEventsAndErrors, Quorum} from \"../interfaces/avs/vendored/IECDSAStakeRegistryEventsAndErrors.sol\";\n\n/// @author Layr Labs, Inc.\nabstract contract ECDSAStakeRegistryStorage is\n    IECDSAStakeRegistryEventsAndErrors\n{\n    /// @notice Manages staking delegations through the DelegationManager interface\n    IDelegationManager internal immutable DELEGATION_MANAGER;\n\n    /// @dev The total amount of multipliers to weigh stakes\n    uint256 internal constant BPS = 10_000;\n\n    /// @notice The size of the current operator set\n    uint256 internal _totalOperators;\n\n    /// @notice Stores the current quorum configuration\n    Quorum internal _quorum;\n\n    /// @notice Specifies the weight required to become an operator\n    uint256 internal _minimumWeight;\n\n    /// @notice Holds the address of the service manager\n    address internal _serviceManager;\n\n    /// @notice Defines the duration after which the stake's weight expires.\n    uint256 internal _stakeExpiry;\n\n    /// @notice Maps an operator to their signing key history using checkpoints\n    mapping(address operator => CheckpointsUpgradeable.History signingKeyHistory)\n        internal _operatorSigningKeyHistory;\n\n    /// @notice Tracks the total stake history over time using checkpoints\n    CheckpointsUpgradeable.History internal _totalWeightHistory;\n\n    /// @notice Tracks the threshold bps history using checkpoints\n    CheckpointsUpgradeable.History internal _thresholdWeightHistory;\n\n    /// @notice Maps operator addresses to their respective stake histories using checkpoints\n    mapping(address operator => CheckpointsUpgradeable.History operatorWeightHistory)\n        internal _operatorWeightHistory;\n\n    /// @notice Maps an operator to their registration status\n    mapping(address operator => bool isRegistered) internal _operatorRegistered;\n\n    /// @param _delegationManager Connects this registry with the DelegationManager\n    constructor(IDelegationManager _delegationManager) {\n        DELEGATION_MANAGER = _delegationManager;\n    }\n\n    // slither-disable-next-line shadowing-state\n    /// @dev Reserves storage slots for future upgrades\n    // solhint-disable-next-line\n    uint256[40] private __gap;\n}\n"},"contracts/avs/HyperlaneServiceManager.sol":{"content":"// SPDX-License-Identifier: MIT OR Apache-2.0\npragma solidity >=0.8.0;\n\n/*@@@@@@@       @@@@@@@@@\n @@@@@@@@@       @@@@@@@@@\n  @@@@@@@@@       @@@@@@@@@\n   @@@@@@@@@       @@@@@@@@@\n    @@@@@@@@@@@@@@@@@@@@@@@@@\n     @@@@@  HYPERLANE  @@@@@@@\n    @@@@@@@@@@@@@@@@@@@@@@@@@\n   @@@@@@@@@       @@@@@@@@@\n  @@@@@@@@@       @@@@@@@@@\n @@@@@@@@@       @@@@@@@@@\n@@@@@@@@@       @@@@@@@@*/\n\n// ============ Internal Imports ============\nimport {Enrollment, EnrollmentStatus, EnumerableMapEnrollment} from \"../libs/EnumerableMapEnrollment.sol\";\nimport {IAVSDirectory} from \"../interfaces/avs/vendored/IAVSDirectory.sol\";\nimport {IRemoteChallenger} from \"../interfaces/avs/IRemoteChallenger.sol\";\nimport {ISlasher} from \"../interfaces/avs/vendored/ISlasher.sol\";\nimport {ECDSAServiceManagerBase} from \"./ECDSAServiceManagerBase.sol\";\nimport {PackageVersioned} from \"../PackageVersioned.sol\";\n\ncontract HyperlaneServiceManager is ECDSAServiceManagerBase, PackageVersioned {\n    // ============ Libraries ============\n\n    using EnumerableMapEnrollment for EnumerableMapEnrollment.AddressToEnrollmentMap;\n\n    // ============ Public Storage ============\n\n    // Slasher contract responsible for slashing operators\n    // @dev slasher needs to be updated once slashing is implemented\n    ISlasher internal slasher;\n\n    // ============ Events ============\n\n    /**\n     * @notice Emitted when an operator is enrolled in a challenger\n     * @param operator The address of the operator\n     * @param challenger The address of the challenger\n     */\n    event OperatorEnrolledToChallenger(\n        address operator,\n        IRemoteChallenger challenger\n    );\n\n    /**\n     * @notice Emitted when an operator is queued for unenrollment from a challenger\n     * @param operator The address of the operator\n     * @param challenger The address of the challenger\n     * @param unenrollmentStartBlock The block number at which the unenrollment was queued\n     * @param challengeDelayBlocks The number of blocks to wait before unenrollment is complete\n     */\n    event OperatorQueuedUnenrollmentFromChallenger(\n        address operator,\n        IRemoteChallenger challenger,\n        uint256 unenrollmentStartBlock,\n        uint256 challengeDelayBlocks\n    );\n\n    /**\n     * @notice Emitted when an operator is unenrolled from a challenger\n     * @param operator The address of the operator\n     * @param challenger The address of the challenger\n     * @param unenrollmentEndBlock The block number at which the unenrollment was completed\n     */\n    event OperatorUnenrolledFromChallenger(\n        address operator,\n        IRemoteChallenger challenger,\n        uint256 unenrollmentEndBlock\n    );\n\n    // ============ Internal Storage ============\n\n    // Mapping of operators to challengers they are enrolled in (enumerable required for remove-all)\n    mapping(address operator => EnumerableMapEnrollment.AddressToEnrollmentMap enrollmentMap)\n        internal enrolledChallengers;\n\n    // ============ Modifiers ============\n\n    // Only allows the challenger the operator is enrolled in to call the function\n    modifier onlyEnrolledChallenger(address operator) {\n        (bool exists, ) = enrolledChallengers[operator].tryGet(msg.sender);\n        require(\n            exists,\n            \"HyperlaneServiceManager: Operator not enrolled in challenger\"\n        );\n        _;\n    }\n\n    // ============ Constructor ============\n\n    constructor(\n        address _avsDirectory,\n        address _stakeRegistry,\n        address _paymentCoordinator,\n        address _delegationManager\n    )\n        ECDSAServiceManagerBase(\n            _avsDirectory,\n            _stakeRegistry,\n            _paymentCoordinator,\n            _delegationManager\n        )\n    {}\n\n    /**\n     * @notice Initializes the HyperlaneServiceManager contract with the owner address\n     */\n    function initialize(address _owner) public initializer {\n        __ServiceManagerBase_init(_owner);\n    }\n\n    // ============ External Functions ============\n\n    /**\n     * @notice Enrolls as an operator into a list of challengers\n     * @param _challengers The list of challengers to enroll into\n     */\n    function enrollIntoChallengers(\n        IRemoteChallenger[] memory _challengers\n    ) external {\n        for (uint256 i = 0; i < _challengers.length; i++) {\n            enrollIntoChallenger(_challengers[i]);\n        }\n    }\n\n    /**\n     * @notice starts an operator for unenrollment from a list of challengers\n     * @param _challengers The list of challengers to unenroll from\n     */\n    function startUnenrollment(\n        IRemoteChallenger[] memory _challengers\n    ) external {\n        for (uint256 i = 0; i < _challengers.length; i++) {\n            startUnenrollment(_challengers[i]);\n        }\n    }\n\n    /**\n     * @notice Completes the unenrollment of an operator from a list of challengers\n     * @param _challengers The list of challengers to unenroll from\n     */\n    function completeUnenrollment(address[] memory _challengers) external {\n        _completeUnenrollment(msg.sender, _challengers);\n    }\n\n    /**\n     * @notice Sets the slasher contract responsible for slashing operators\n     * @param _slasher The address of the slasher contract\n     */\n    function setSlasher(ISlasher _slasher) external onlyOwner {\n        slasher = _slasher;\n    }\n\n    /**\n     * @notice returns the status of a challenger an operator is enrolled in\n     * @param _operator The address of the operator\n     * @param _challenger specified IRemoteChallenger contract\n     */\n    function getChallengerEnrollment(\n        address _operator,\n        IRemoteChallenger _challenger\n    ) external view returns (Enrollment memory enrollment) {\n        return enrolledChallengers[_operator].get(address(_challenger));\n    }\n\n    /**\n     * @notice forwards a call to the Slasher contract to freeze an operator\n     * @param operator The address of the operator to freeze.\n     * @dev only the enrolled challengers can call this function\n     */\n    function freezeOperator(\n        address operator\n    ) external virtual onlyEnrolledChallenger(operator) {\n        slasher.freezeOperator(operator);\n    }\n\n    // ============ Public Functions ============\n\n    /**\n     * @notice returns the list of challengers an operator is enrolled in\n     * @param _operator The address of the operator\n     */\n    function getOperatorChallengers(\n        address _operator\n    ) public view returns (address[] memory) {\n        return enrolledChallengers[_operator].keys();\n    }\n\n    /**\n     * @notice Enrolls as an operator into a single challenger\n     * @param challenger The challenger to enroll into\n     */\n    function enrollIntoChallenger(IRemoteChallenger challenger) public {\n        require(\n            enrolledChallengers[msg.sender].set(\n                address(challenger),\n                Enrollment(EnrollmentStatus.ENROLLED, 0)\n            )\n        );\n        emit OperatorEnrolledToChallenger(msg.sender, challenger);\n    }\n\n    /**\n     * @notice starts an operator for unenrollment from a challenger\n     * @param challenger The challenger to unenroll from\n     */\n    function startUnenrollment(IRemoteChallenger challenger) public {\n        (bool exists, Enrollment memory enrollment) = enrolledChallengers[\n            msg.sender\n        ].tryGet(address(challenger));\n        require(\n            exists && enrollment.status == EnrollmentStatus.ENROLLED,\n            \"HyperlaneServiceManager: challenger isn't enrolled\"\n        );\n\n        enrolledChallengers[msg.sender].set(\n            address(challenger),\n            Enrollment(\n                EnrollmentStatus.PENDING_UNENROLLMENT,\n                uint248(block.number)\n            )\n        );\n        emit OperatorQueuedUnenrollmentFromChallenger(\n            msg.sender,\n            challenger,\n            block.number,\n            challenger.challengeDelayBlocks()\n        );\n    }\n\n    /**\n     * @notice Completes the unenrollment of an operator from a challenger\n     * @param challenger The challenger to unenroll from\n     */\n    function completeUnenrollment(address challenger) public {\n        _completeUnenrollment(msg.sender, challenger);\n    }\n\n    // ============ Internal Functions ============\n\n    /**\n     * @notice Completes the unenrollment of an operator from a list of challengers\n     * @param operator The address of the operator\n     * @param _challengers The list of challengers to unenroll from\n     */\n    function _completeUnenrollment(\n        address operator,\n        address[] memory _challengers\n    ) internal {\n        for (uint256 i = 0; i < _challengers.length; i++) {\n            _completeUnenrollment(operator, _challengers[i]);\n        }\n    }\n\n    /**\n     * @notice Completes the unenrollment of an operator from a challenger\n     * @param operator The address of the operator\n     * @param _challenger The challenger to unenroll from\n     */\n    function _completeUnenrollment(\n        address operator,\n        address _challenger\n    ) internal {\n        IRemoteChallenger challenger = IRemoteChallenger(_challenger);\n        (bool exists, Enrollment memory enrollment) = enrolledChallengers[\n            operator\n        ].tryGet(address(challenger));\n\n        require(\n            exists &&\n                enrollment.status == EnrollmentStatus.PENDING_UNENROLLMENT &&\n                block.number >=\n                enrollment.unenrollmentStartBlock +\n                    challenger.challengeDelayBlocks(),\n            \"HyperlaneServiceManager: Invalid unenrollment\"\n        );\n\n        enrolledChallengers[operator].remove(address(challenger));\n        emit OperatorUnenrolledFromChallenger(\n            operator,\n            challenger,\n            block.number\n        );\n    }\n\n    /// @inheritdoc ECDSAServiceManagerBase\n    function _deregisterOperatorFromAVS(\n        address operator\n    ) internal virtual override {\n        address[] memory challengers = getOperatorChallengers(operator);\n        _completeUnenrollment(operator, challengers);\n\n        IAVSDirectory(avsDirectory).deregisterOperatorFromAVS(operator);\n        emit OperatorDeregisteredFromAVS(operator);\n    }\n}\n"},"contracts/CheckpointFraudProofs.sol":{"content":"// SPDX-License-Identifier: MIT OR Apache-2.0\npragma solidity >=0.8.0;\n\nimport {Address} from \"@openzeppelin/contracts/utils/Address.sol\";\n\nimport {Checkpoint, CheckpointLib} from \"./libs/CheckpointLib.sol\";\nimport {MerkleLib, TREE_DEPTH} from \"./libs/Merkle.sol\";\nimport {MerkleTreeHook} from \"./hooks/MerkleTreeHook.sol\";\n\nimport {PackageVersioned} from \"./PackageVersioned.sol\";\n\nstruct StoredIndex {\n    uint32 index;\n    bool exists;\n}\n\ncontract CheckpointFraudProofs is PackageVersioned {\n    using CheckpointLib for Checkpoint;\n    using Address for address;\n\n    mapping(address merkleTree => mapping(bytes32 root => StoredIndex index))\n        public storedCheckpoints;\n\n    function storedCheckpointContainsMessage(\n        address merkleTree,\n        uint32 index,\n        bytes32 messageId,\n        bytes32[TREE_DEPTH] calldata proof\n    ) public view returns (bool) {\n        bytes32 root = MerkleLib.branchRoot(messageId, proof, index);\n        StoredIndex storage storedIndex = storedCheckpoints[merkleTree][root];\n        return storedIndex.exists && storedIndex.index >= index;\n    }\n\n    modifier onlyMessageInStoredCheckpoint(\n        Checkpoint calldata checkpoint,\n        bytes32[TREE_DEPTH] calldata proof,\n        bytes32 messageId\n    ) {\n        require(\n            storedCheckpointContainsMessage(\n                checkpoint.merkleTreeAddress(),\n                checkpoint.index,\n                messageId,\n                proof\n            ),\n            \"message must be member of stored checkpoint\"\n        );\n        _;\n    }\n\n    function isLocal(\n        Checkpoint calldata checkpoint\n    ) public view returns (bool) {\n        address merkleTree = checkpoint.merkleTreeAddress();\n        return\n            merkleTree.isContract() &&\n            MerkleTreeHook(merkleTree).localDomain() == checkpoint.origin;\n    }\n\n    modifier onlyLocal(Checkpoint calldata checkpoint) {\n        require(isLocal(checkpoint), \"must be local checkpoint\");\n        _;\n    }\n\n    /**\n     *  @notice Stores the latest checkpoint of the provided merkle tree hook\n     *  @param merkleTree Address of the merkle tree hook to store the latest checkpoint of.\n     *  @dev Must be called before proving fraud to circumvent race on message insertion and merkle proof construction.\n     */\n    function storeLatestCheckpoint(\n        address merkleTree\n    ) external returns (bytes32 root, uint32 index) {\n        (root, index) = MerkleTreeHook(merkleTree).latestCheckpoint();\n        storedCheckpoints[merkleTree][root] = StoredIndex(index, true);\n    }\n\n    /**\n     *  @notice Checks whether the provided checkpoint is premature (fraud).\n     *  @param checkpoint Checkpoint to check.\n     *  @dev Checks whether checkpoint.index is greater than or equal to mailbox count\n     *  @return Whether the provided checkpoint is premature.\n     */\n    function isPremature(\n        Checkpoint calldata checkpoint\n    ) public view onlyLocal(checkpoint) returns (bool) {\n        // count is the number of messages in the mailbox (i.e. the latest index + 1)\n        uint32 count = MerkleTreeHook(checkpoint.merkleTreeAddress()).count();\n\n        // index >= count is equivalent to index > latest index\n        return checkpoint.index >= count;\n    }\n\n    /**\n     *  @notice Checks whether the provided checkpoint has a fraudulent message ID.\n     *  @param checkpoint Checkpoint to check.\n     *  @param proof Merkle proof of the actual message ID at checkpoint.index on checkpoint.merkleTree\n     *  @param actualMessageId Actual message ID at checkpoint.index on checkpoint.merkleTree\n     *  @dev Must produce proof of inclusion for actualMessageID against some stored checkpoint.\n     *  @return Whether the provided checkpoint has a fraudulent message ID.\n     */\n    function isFraudulentMessageId(\n        Checkpoint calldata checkpoint,\n        bytes32[TREE_DEPTH] calldata proof,\n        bytes32 actualMessageId\n    )\n        public\n        view\n        onlyLocal(checkpoint)\n        onlyMessageInStoredCheckpoint(checkpoint, proof, actualMessageId)\n        returns (bool)\n    {\n        return actualMessageId != checkpoint.messageId;\n    }\n\n    /**\n     *  @notice Checks whether the provided checkpoint has a fraudulent root.\n     *  @param checkpoint Checkpoint to check.\n     *  @param proof Merkle proof of the checkpoint.messageId at checkpoint.index on checkpoint.merkleTree\n     *  @dev Must produce proof of inclusion for checkpoint.messageId against some stored checkpoint.\n     *  @return Whether the provided checkpoint has a fraudulent message ID.\n     */\n    function isFraudulentRoot(\n        Checkpoint calldata checkpoint,\n        bytes32[TREE_DEPTH] calldata proof\n    )\n        public\n        view\n        onlyLocal(checkpoint)\n        onlyMessageInStoredCheckpoint(checkpoint, proof, checkpoint.messageId)\n        returns (bool)\n    {\n        // proof of checkpoint.messageId at checkpoint.index is the list of siblings from the leaf node to some stored root\n        // once verifying the proof, we can reconstruct the specific root at checkpoint.index by replacing siblings greater\n        // than the index (right subtrees) with zeroes\n        bytes32 root = MerkleLib.reconstructRoot(\n            checkpoint.messageId,\n            proof,\n            checkpoint.index\n        );\n        return root != checkpoint.root;\n    }\n}\n"},"contracts/client/GasRouter.sol":{"content":"// SPDX-License-Identifier: MIT OR Apache-2.0\npragma solidity >=0.6.11;\n\n/*@@@@@@@       @@@@@@@@@\n @@@@@@@@@       @@@@@@@@@\n  @@@@@@@@@       @@@@@@@@@\n   @@@@@@@@@       @@@@@@@@@\n    @@@@@@@@@@@@@@@@@@@@@@@@@\n     @@@@@  HYPERLANE  @@@@@@@\n    @@@@@@@@@@@@@@@@@@@@@@@@@\n   @@@@@@@@@       @@@@@@@@@\n  @@@@@@@@@       @@@@@@@@@\n @@@@@@@@@       @@@@@@@@@\n@@@@@@@@@       @@@@@@@@*/\n\n// ============ Internal Imports ============\nimport {Router} from \"./Router.sol\";\nimport {StandardHookMetadata} from \"../hooks/libs/StandardHookMetadata.sol\";\n\nabstract contract GasRouter is Router {\n    event GasSet(uint32 domain, uint256 gas);\n\n    // ============ Mutable Storage ============\n    mapping(uint32 destinationDomain => uint256 gasLimit) public destinationGas;\n\n    struct GasRouterConfig {\n        uint32 domain;\n        uint256 gas;\n    }\n\n    constructor(address _mailbox) Router(_mailbox) {}\n\n    /**\n     * @notice Sets the gas amount dispatched for each configured domain.\n     * @param gasConfigs The array of GasRouterConfig structs\n     */\n    function setDestinationGas(\n        GasRouterConfig[] calldata gasConfigs\n    ) external onlyOwner {\n        for (uint256 i = 0; i < gasConfigs.length; i += 1) {\n            _setDestinationGas(gasConfigs[i].domain, gasConfigs[i].gas);\n        }\n    }\n\n    /**\n     * @notice Sets the gas amount dispatched for each configured domain.\n     * @param domain The destination domain ID\n     * @param gas The gas limit\n     */\n    function setDestinationGas(uint32 domain, uint256 gas) external onlyOwner {\n        _setDestinationGas(domain, gas);\n    }\n\n    /**\n     * @notice Returns the gas payment required to dispatch a message to the given domain's router.\n     * @param _destinationDomain The domain of the router.\n     * @return _gasPayment Payment computed by the registered InterchainGasPaymaster.\n     */\n    function quoteGasPayment(\n        uint32 _destinationDomain\n    ) public view virtual returns (uint256) {\n        return _GasRouter_quoteDispatch(_destinationDomain, \"\", address(hook));\n    }\n\n    function _GasRouter_hookMetadata(\n        uint32 _destination\n    ) internal view returns (bytes memory) {\n        return\n            StandardHookMetadata.overrideGasLimit(destinationGas[_destination]);\n    }\n\n    function _setDestinationGas(uint32 domain, uint256 gas) internal {\n        destinationGas[domain] = gas;\n        emit GasSet(domain, gas);\n    }\n\n    function _GasRouter_dispatch(\n        uint32 _destination,\n        uint256 _value,\n        bytes memory _messageBody,\n        address _hook\n    ) internal returns (bytes32) {\n        return\n            _Router_dispatch(\n                _destination,\n                _value,\n                _messageBody,\n                _GasRouter_hookMetadata(_destination),\n                _hook\n            );\n    }\n\n    function _GasRouter_quoteDispatch(\n        uint32 _destination,\n        bytes memory _messageBody,\n        address _hook\n    ) internal view returns (uint256) {\n        return\n            _Router_quoteDispatch(\n                _destination,\n                _messageBody,\n                _GasRouter_hookMetadata(_destination),\n                _hook\n            );\n    }\n}\n"},"contracts/client/MailboxClient.sol":{"content":"// SPDX-License-Identifier: MIT OR Apache-2.0\npragma solidity >=0.6.11;\n\n/*@@@@@@@       @@@@@@@@@\n @@@@@@@@@       @@@@@@@@@\n  @@@@@@@@@       @@@@@@@@@\n   @@@@@@@@@       @@@@@@@@@\n    @@@@@@@@@@@@@@@@@@@@@@@@@\n     @@@@@  HYPERLANE  @@@@@@@\n    @@@@@@@@@@@@@@@@@@@@@@@@@\n   @@@@@@@@@       @@@@@@@@@\n  @@@@@@@@@       @@@@@@@@@\n @@@@@@@@@       @@@@@@@@@\n@@@@@@@@@       @@@@@@@@*/\n\n// ============ Internal Imports ============\nimport {IMailbox} from \"../interfaces/IMailbox.sol\";\nimport {IPostDispatchHook} from \"../interfaces/hooks/IPostDispatchHook.sol\";\nimport {IInterchainSecurityModule} from \"../interfaces/IInterchainSecurityModule.sol\";\nimport {Message} from \"../libs/Message.sol\";\nimport {PackageVersioned} from \"../PackageVersioned.sol\";\n\n// ============ External Imports ============\nimport {Address} from \"@openzeppelin/contracts/utils/Address.sol\";\nimport {OwnableUpgradeable} from \"@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol\";\n\nabstract contract MailboxClient is OwnableUpgradeable, PackageVersioned {\n    using Message for bytes;\n\n    event HookSet(address _hook);\n    event IsmSet(address _ism);\n\n    IMailbox public immutable mailbox;\n\n    uint32 public immutable localDomain;\n\n    IPostDispatchHook public hook;\n\n    IInterchainSecurityModule internal _interchainSecurityModule;\n\n    uint256[48] private __GAP; // gap for upgrade safety\n\n    // ============ Modifiers ============\n    modifier onlyContract(address _contract) {\n        require(\n            Address.isContract(_contract),\n            \"MailboxClient: invalid mailbox\"\n        );\n        _;\n    }\n\n    modifier onlyContractOrNull(address _contract) {\n        require(\n            Address.isContract(_contract) || _contract == address(0),\n            \"MailboxClient: invalid contract setting\"\n        );\n        _;\n    }\n\n    /**\n     * @notice Only accept messages from a Hyperlane Mailbox contract\n     */\n    modifier onlyMailbox() {\n        require(\n            msg.sender == address(mailbox),\n            \"MailboxClient: sender not mailbox\"\n        );\n        _;\n    }\n\n    constructor(address _mailbox) onlyContract(_mailbox) {\n        mailbox = IMailbox(_mailbox);\n        localDomain = mailbox.localDomain();\n        _transferOwnership(msg.sender);\n    }\n\n    function interchainSecurityModule()\n        external\n        view\n        virtual\n        returns (IInterchainSecurityModule)\n    {\n        return _interchainSecurityModule;\n    }\n\n    /**\n     * @notice Sets the address of the application's custom hook.\n     * @param _hook The address of the hook contract.\n     */\n    function setHook(\n        address _hook\n    ) public virtual onlyContractOrNull(_hook) onlyOwner {\n        hook = IPostDispatchHook(_hook);\n        emit HookSet(_hook);\n    }\n\n    /**\n     * @notice Sets the address of the application's custom interchain security module.\n     * @param _module The address of the interchain security module contract.\n     */\n    function setInterchainSecurityModule(\n        address _module\n    ) public onlyContractOrNull(_module) onlyOwner {\n        _interchainSecurityModule = IInterchainSecurityModule(_module);\n        emit IsmSet(_module);\n    }\n\n    // ======== Initializer =========\n    function _MailboxClient_initialize(\n        address _hook,\n        address __interchainSecurityModule,\n        address _owner\n    ) internal onlyInitializing {\n        __Ownable_init();\n        setHook(_hook);\n        setInterchainSecurityModule(__interchainSecurityModule);\n        _transferOwnership(_owner);\n    }\n\n    function _isLatestDispatched(bytes32 id) internal view returns (bool) {\n        return mailbox.latestDispatchedId() == id;\n    }\n\n    function _isDelivered(bytes32 id) internal view returns (bool) {\n        return mailbox.delivered(id);\n    }\n}\n"},"contracts/client/Router.sol":{"content":"// SPDX-License-Identifier: MIT OR Apache-2.0\npragma solidity >=0.6.11;\n\n// ============ Internal Imports ============\nimport {IMessageRecipient} from \"../interfaces/IMessageRecipient.sol\";\nimport {IPostDispatchHook} from \"../interfaces/hooks/IPostDispatchHook.sol\";\nimport {MailboxClient} from \"./MailboxClient.sol\";\nimport {EnumerableMapExtended} from \"../libs/EnumerableMapExtended.sol\";\n\n// ============ External Imports ============\nimport {Strings} from \"@openzeppelin/contracts/utils/Strings.sol\";\n\nabstract contract Router is MailboxClient, IMessageRecipient {\n    using EnumerableMapExtended for EnumerableMapExtended.UintToBytes32Map;\n    using Strings for uint32;\n\n    // ============ Mutable Storage ============\n    /// @dev Mapping of domain => router. For a given domain we have one router we send/receive messages from.\n    EnumerableMapExtended.UintToBytes32Map internal _routers;\n\n    uint256[48] private __GAP; // gap for upgrade safety\n\n    constructor(address _mailbox) MailboxClient(_mailbox) {}\n\n    // ============ External functions ============\n    function domains() external view returns (uint32[] memory) {\n        return _routers.uint32Keys();\n    }\n\n    /**\n     * @notice Returns the address of the Router contract for the given domain\n     * @param _domain The remote domain ID.\n     * @dev Returns 0 address if no router is enrolled for the given domain\n     * @return router The address of the Router contract for the given domain\n     */\n    function routers(uint32 _domain) public view virtual returns (bytes32) {\n        (, bytes32 _router) = _routers.tryGet(_domain);\n        return _router;\n    }\n\n    /**\n     * @notice Unregister the domain\n     * @param _domain The domain of the remote Application Router\n     */\n    function unenrollRemoteRouter(uint32 _domain) external virtual onlyOwner {\n        _unenrollRemoteRouter(_domain);\n    }\n\n    /**\n     * @notice Register the address of a Router contract for the same Application on a remote chain\n     * @param _domain The domain of the remote Application Router\n     * @param _router The address of the remote Application Router\n     */\n    function enrollRemoteRouter(\n        uint32 _domain,\n        bytes32 _router\n    ) external virtual onlyOwner {\n        _enrollRemoteRouter(_domain, _router);\n    }\n\n    /**\n     * @notice Batch version of `enrollRemoteRouter`\n     * @param _domains The domains of the remote Application Routers\n     * @param _addresses The addresses of the remote Application Routers\n     */\n    function enrollRemoteRouters(\n        uint32[] calldata _domains,\n        bytes32[] calldata _addresses\n    ) external virtual onlyOwner {\n        require(_domains.length == _addresses.length, \"!length\");\n        uint256 length = _domains.length;\n        for (uint256 i = 0; i < length; i += 1) {\n            _enrollRemoteRouter(_domains[i], _addresses[i]);\n        }\n    }\n\n    /**\n     * @notice Batch version of `unenrollRemoteRouter`\n     * @param _domains The domains of the remote Application Routers\n     */\n    function unenrollRemoteRouters(\n        uint32[] calldata _domains\n    ) external virtual onlyOwner {\n        uint256 length = _domains.length;\n        for (uint256 i = 0; i < length; i += 1) {\n            _unenrollRemoteRouter(_domains[i]);\n        }\n    }\n\n    /**\n     * @notice Handles an incoming message\n     * @param _origin The origin domain\n     * @param _sender The sender address\n     * @param _message The message\n     */\n    function handle(\n        uint32 _origin,\n        bytes32 _sender,\n        bytes calldata _message\n    ) external payable virtual override onlyMailbox {\n        bytes32 _router = _mustHaveRemoteRouter(_origin);\n        require(_router == _sender, \"Enrolled router does not match sender\");\n        _handle(_origin, _sender, _message);\n    }\n\n    // ============ Virtual functions ============\n    function _handle(\n        uint32 _origin,\n        bytes32 _sender,\n        bytes calldata _message\n    ) internal virtual;\n\n    // ============ Internal functions ============\n\n    /**\n     * @notice Set the router for a given domain\n     * @param _domain The domain\n     * @param _address The new router\n     */\n    function _enrollRemoteRouter(\n        uint32 _domain,\n        bytes32 _address\n    ) internal virtual {\n        _routers.set(_domain, _address);\n    }\n\n    /**\n     * @notice Remove the router for a given domain\n     * @param _domain The domain\n     */\n    function _unenrollRemoteRouter(uint32 _domain) internal virtual {\n        require(_routers.remove(_domain), _domainNotFoundError(_domain));\n    }\n\n    /**\n     * @notice Return true if the given domain / router is the address of a remote Application Router\n     * @param _domain The domain of the potential remote Application Router\n     * @param _address The address of the potential remote Application Router\n     */\n    function _isRemoteRouter(\n        uint32 _domain,\n        bytes32 _address\n    ) internal view returns (bool) {\n        return routers(_domain) == _address;\n    }\n\n    /**\n     * @notice Assert that the given domain has an Application Router registered and return its address\n     * @param _domain The domain of the chain for which to get the Application Router\n     * @return _router The address of the remote Application Router on _domain\n     */\n    function _mustHaveRemoteRouter(\n        uint32 _domain\n    ) internal view returns (bytes32) {\n        (bool contained, bytes32 _router) = _routers.tryGet(_domain);\n        if (contained) {\n            return _router;\n        }\n        revert(_domainNotFoundError(_domain));\n    }\n\n    function _domainNotFoundError(\n        uint32 _domain\n    ) internal pure returns (string memory) {\n        return\n            string.concat(\n                \"No router enrolled for domain: \",\n                _domain.toString()\n            );\n    }\n\n    function _Router_dispatch(\n        uint32 _destinationDomain,\n        uint256 _value,\n        bytes memory _messageBody,\n        bytes memory _hookMetadata,\n        address _hook\n    ) internal returns (bytes32) {\n        bytes32 _router = _mustHaveRemoteRouter(_destinationDomain);\n        return\n            mailbox.dispatch{value: _value}(\n                _destinationDomain,\n                _router,\n                _messageBody,\n                _hookMetadata,\n                IPostDispatchHook(_hook)\n            );\n    }\n\n    /**\n     * DEPRECATED: Use `_Router_dispatch` instead\n     * @dev For backward compatibility with v2 client contracts\n     */\n    function _dispatch(\n        uint32 _destinationDomain,\n        bytes memory _messageBody\n    ) internal returns (bytes32) {\n        return\n            _Router_dispatch(\n                _destinationDomain,\n                msg.value,\n                _messageBody,\n                \"\",\n                address(hook)\n            );\n    }\n\n    function _Router_quoteDispatch(\n        uint32 _destinationDomain,\n        bytes memory _messageBody,\n        bytes memory _hookMetadata,\n        address _hook\n    ) internal view returns (uint256) {\n        bytes32 _router = _mustHaveRemoteRouter(_destinationDomain);\n        return\n            mailbox.quoteDispatch(\n                _destinationDomain,\n                _router,\n                _messageBody,\n                _hookMetadata,\n                IPostDispatchHook(_hook)\n            );\n    }\n\n    /**\n     * DEPRECATED: Use `_Router_quoteDispatch` instead\n     * @dev For backward compatibility with v2 client contracts\n     */\n    function _quoteDispatch(\n        uint32 _destinationDomain,\n        bytes memory _messageBody\n    ) internal view returns (uint256) {\n        return\n            _Router_quoteDispatch(\n                _destinationDomain,\n                _messageBody,\n                \"\",\n                address(hook)\n            );\n    }\n}\n"},"contracts/hooks/aggregation/ERC5164Hook.sol":{"content":"// SPDX-License-Identifier: MIT OR Apache-2.0\npragma solidity >=0.8.0;\n\n/*@@@@@@@       @@@@@@@@@\n @@@@@@@@@       @@@@@@@@@\n  @@@@@@@@@       @@@@@@@@@\n   @@@@@@@@@       @@@@@@@@@\n    @@@@@@@@@@@@@@@@@@@@@@@@@\n     @@@@@  HYPERLANE  @@@@@@@\n    @@@@@@@@@@@@@@@@@@@@@@@@@\n   @@@@@@@@@       @@@@@@@@@\n  @@@@@@@@@       @@@@@@@@@\n @@@@@@@@@       @@@@@@@@@\n@@@@@@@@@       @@@@@@@@*/\n\n// ============ Internal Imports ============\nimport {TypeCasts} from \"../../libs/TypeCasts.sol\";\nimport {Message} from \"../../libs/Message.sol\";\nimport {StandardHookMetadata} from \"../libs/StandardHookMetadata.sol\";\nimport {IMessageDispatcher} from \"../../interfaces/hooks/IMessageDispatcher.sol\";\nimport {AbstractMessageIdAuthHook} from \"../libs/AbstractMessageIdAuthHook.sol\";\nimport {AbstractMessageIdAuthorizedIsm} from \"../../isms/hook/AbstractMessageIdAuthorizedIsm.sol\";\n\n// ============ External Imports ============\nimport {Address} from \"@openzeppelin/contracts/utils/Address.sol\";\n\n/**\n * @title 5164MessageHook\n * @notice Message hook to inform the 5164 ISM of messages published through\n * any of the 5164 adapters.\n */\ncontract ERC5164Hook is AbstractMessageIdAuthHook {\n    using StandardHookMetadata for bytes;\n    using Message for bytes;\n\n    IMessageDispatcher public immutable dispatcher;\n\n    constructor(\n        address _mailbox,\n        uint32 _destinationDomain,\n        bytes32 _ism,\n        address _dispatcher\n    ) AbstractMessageIdAuthHook(_mailbox, _destinationDomain, _ism) {\n        require(\n            Address.isContract(_dispatcher),\n            \"ERC5164Hook: invalid dispatcher\"\n        );\n        dispatcher = IMessageDispatcher(_dispatcher);\n    }\n\n    // ============ Internal Functions ============\n\n    function _quoteDispatch(\n        bytes calldata,\n        bytes calldata\n    ) internal pure override returns (uint256) {\n        return 0; // EIP-5164 doesn't enforce a gas abstraction\n    }\n\n    function _sendMessageId(\n        bytes calldata metadata,\n        bytes calldata message\n    ) internal override {\n        require(msg.value == 0, \"ERC5164Hook: no value allowed\");\n\n        bytes memory payload = abi.encodeCall(\n            AbstractMessageIdAuthorizedIsm.preVerifyMessage,\n            (message.id(), metadata.msgValue(0))\n        );\n        dispatcher.dispatchMessage(\n            destinationDomain,\n            TypeCasts.bytes32ToAddress(ism),\n            payload\n        );\n    }\n}\n"},"contracts/hooks/aggregation/StaticAggregationHook.sol":{"content":"// SPDX-License-Identifier: MIT OR Apache-2.0\npragma solidity >=0.8.0;\n\n/*@@@@@@@       @@@@@@@@@\n @@@@@@@@@       @@@@@@@@@\n  @@@@@@@@@       @@@@@@@@@\n   @@@@@@@@@       @@@@@@@@@\n    @@@@@@@@@@@@@@@@@@@@@@@@@\n     @@@@@  HYPERLANE  @@@@@@@\n    @@@@@@@@@@@@@@@@@@@@@@@@@\n   @@@@@@@@@       @@@@@@@@@\n  @@@@@@@@@       @@@@@@@@@\n @@@@@@@@@       @@@@@@@@@\n@@@@@@@@@       @@@@@@@@*/\n\n// ============ Internal Imports ============\nimport {StandardHookMetadata} from \"../libs/StandardHookMetadata.sol\";\nimport {Message} from \"../../libs/Message.sol\";\nimport {TypeCasts} from \"../../libs/TypeCasts.sol\";\nimport {AbstractPostDispatchHook} from \"../libs/AbstractPostDispatchHook.sol\";\nimport {IPostDispatchHook} from \"../../interfaces/hooks/IPostDispatchHook.sol\";\nimport {MetaProxy} from \"../../libs/MetaProxy.sol\";\n\n// ============ External Imports ============\nimport {Address} from \"@openzeppelin/contracts/utils/Address.sol\";\n\ncontract StaticAggregationHook is AbstractPostDispatchHook {\n    using Message for bytes;\n    using TypeCasts for bytes32;\n    using StandardHookMetadata for bytes;\n    using Address for address payable;\n\n    // ============ External functions ============\n\n    /// @inheritdoc IPostDispatchHook\n    function hookType() external pure override returns (uint8) {\n        return uint8(IPostDispatchHook.Types.AGGREGATION);\n    }\n\n    /// @inheritdoc AbstractPostDispatchHook\n    function _postDispatch(\n        bytes calldata metadata,\n        bytes calldata message\n    ) internal override {\n        address[] memory _hooks = hooks(message);\n        uint256 count = _hooks.length;\n        uint256 valueRemaining = msg.value;\n        for (uint256 i = 0; i < count; i++) {\n            uint256 quote = IPostDispatchHook(_hooks[i]).quoteDispatch(\n                metadata,\n                message\n            );\n            require(\n                valueRemaining >= quote,\n                \"StaticAggregationHook: insufficient value\"\n            );\n\n            IPostDispatchHook(_hooks[i]).postDispatch{value: quote}(\n                metadata,\n                message\n            );\n\n            valueRemaining -= quote;\n        }\n\n        if (valueRemaining > 0) {\n            payable(metadata.refundAddress(message.senderAddress())).sendValue(\n                valueRemaining\n            );\n        }\n    }\n\n    /// @inheritdoc AbstractPostDispatchHook\n    function _quoteDispatch(\n        bytes calldata metadata,\n        bytes calldata message\n    ) internal view override returns (uint256) {\n        address[] memory _hooks = hooks(message);\n        uint256 count = _hooks.length;\n        uint256 total = 0;\n        for (uint256 i = 0; i < count; i++) {\n            total += IPostDispatchHook(_hooks[i]).quoteDispatch(\n                metadata,\n                message\n            );\n        }\n        return total;\n    }\n\n    function hooks(bytes calldata) public pure returns (address[] memory) {\n        return abi.decode(MetaProxy.metadata(), (address[]));\n    }\n}\n"},"contracts/hooks/aggregation/StaticAggregationHookFactory.sol":{"content":"// SPDX-License-Identifier: MIT OR Apache-2.0\npragma solidity >=0.8.0;\n\n/*@@@@@@@       @@@@@@@@@\n @@@@@@@@@       @@@@@@@@@\n  @@@@@@@@@       @@@@@@@@@\n   @@@@@@@@@       @@@@@@@@@\n    @@@@@@@@@@@@@@@@@@@@@@@@@\n     @@@@@  HYPERLANE  @@@@@@@\n    @@@@@@@@@@@@@@@@@@@@@@@@@\n   @@@@@@@@@       @@@@@@@@@\n  @@@@@@@@@       @@@@@@@@@\n @@@@@@@@@       @@@@@@@@@\n@@@@@@@@@       @@@@@@@@*/\n\n// ============ Internal Imports ============\nimport {StaticAggregationHook} from \"./StaticAggregationHook.sol\";\nimport {StaticAddressSetFactory} from \"../../libs/StaticAddressSetFactory.sol\";\n\ncontract StaticAggregationHookFactory is StaticAddressSetFactory {\n    function _deployImplementation()\n        internal\n        virtual\n        override\n        returns (address)\n    {\n        return address(new StaticAggregationHook());\n    }\n}\n"},"contracts/hooks/ArbL2ToL1Hook.sol":{"content":"// SPDX-License-Identifier: MIT OR Apache-2.0\npragma solidity >=0.8.0;\n\n/*@@@@@@@       @@@@@@@@@\n @@@@@@@@@       @@@@@@@@@\n  @@@@@@@@@       @@@@@@@@@\n   @@@@@@@@@       @@@@@@@@@\n    @@@@@@@@@@@@@@@@@@@@@@@@@\n     @@@@@  HYPERLANE  @@@@@@@\n    @@@@@@@@@@@@@@@@@@@@@@@@@\n   @@@@@@@@@       @@@@@@@@@\n  @@@@@@@@@       @@@@@@@@@\n @@@@@@@@@       @@@@@@@@@\n@@@@@@@@@       @@@@@@@@*/\n\n// ============ Internal Imports ============\nimport {Message} from \"../libs/Message.sol\";\nimport {IPostDispatchHook} from \"../interfaces/hooks/IPostDispatchHook.sol\";\nimport {AbstractPostDispatchHook} from \"./libs/AbstractMessageIdAuthHook.sol\";\nimport {AbstractMessageIdAuthHook} from \"./libs/AbstractMessageIdAuthHook.sol\";\nimport {AbstractMessageIdAuthorizedIsm} from \"../isms/hook/AbstractMessageIdAuthorizedIsm.sol\";\nimport {StandardHookMetadata} from \"./libs/StandardHookMetadata.sol\";\nimport {Message} from \"../libs/Message.sol\";\nimport {TypeCasts} from \"../libs/TypeCasts.sol\";\n\n// ============ External Imports ============\nimport {ArbSys} from \"@arbitrum/nitro-contracts/src/precompiles/ArbSys.sol\";\n\n/**\n * @title ArbL2ToL1Hook\n * @notice Message hook to inform the ArbL2ToL1iSM of messages published through\n * the native Arbitrum bridge.\n * @notice This works only for L2 -> L1 messages and has the 7 day delay as specified by the ArbSys contract.\n */\ncontract ArbL2ToL1Hook is AbstractMessageIdAuthHook {\n    using StandardHookMetadata for bytes;\n    using Message for bytes;\n\n    // ============ Constants ============\n\n    // precompile contract on L2 for sending messages to L1\n    ArbSys public immutable arbSys;\n    // child hook to call first\n    IPostDispatchHook public immutable childHook;\n\n    // ============ Constructor ============\n\n    constructor(\n        address _mailbox,\n        uint32 _destinationDomain,\n        bytes32 _ism,\n        address _arbSys,\n        address _childHook\n    ) AbstractMessageIdAuthHook(_mailbox, _destinationDomain, _ism) {\n        arbSys = ArbSys(_arbSys);\n        childHook = AbstractPostDispatchHook(_childHook);\n    }\n\n    /// @inheritdoc IPostDispatchHook\n    function hookType() external pure override returns (uint8) {\n        return uint8(IPostDispatchHook.Types.ARB_L2_TO_L1);\n    }\n\n    /// @inheritdoc AbstractPostDispatchHook\n    function _quoteDispatch(\n        bytes calldata metadata,\n        bytes calldata message\n    ) internal view override returns (uint256) {\n        return\n            metadata.msgValue(0) + childHook.quoteDispatch(metadata, message);\n    }\n\n    // ============ Internal functions ============\n\n    /// @inheritdoc AbstractMessageIdAuthHook\n    function _sendMessageId(\n        bytes calldata metadata,\n        bytes calldata message\n    ) internal override {\n        bytes memory payload = abi.encodeCall(\n            AbstractMessageIdAuthorizedIsm.preVerifyMessage,\n            (message.id(), metadata.msgValue(0))\n        );\n\n        childHook.postDispatch{\n            value: childHook.quoteDispatch(metadata, message)\n        }(metadata, message);\n        arbSys.sendTxToL1{value: metadata.msgValue(0)}(\n            TypeCasts.bytes32ToAddress(ism),\n            payload\n        );\n    }\n}\n"},"contracts/hooks/CCIPHook.sol":{"content":"// SPDX-License-Identifier: MIT OR Apache-2.0\npragma solidity >=0.8.0;\n\n/*@@@@@@@       @@@@@@@@@\n @@@@@@@@@       @@@@@@@@@\n  @@@@@@@@@       @@@@@@@@@\n   @@@@@@@@@       @@@@@@@@@\n    @@@@@@@@@@@@@@@@@@@@@@@@@\n     @@@@@  HYPERLANE  @@@@@@@\n    @@@@@@@@@@@@@@@@@@@@@@@@@\n   @@@@@@@@@       @@@@@@@@@\n  @@@@@@@@@       @@@@@@@@@\n @@@@@@@@@       @@@@@@@@@\n@@@@@@@@@       @@@@@@@@*/\n\n// ============ Internal Imports ============\nimport {AbstractMessageIdAuthHook} from \"./libs/AbstractMessageIdAuthHook.sol\";\nimport {Message} from \"../libs/Message.sol\";\nimport {TypeCasts} from \"../libs/TypeCasts.sol\";\n\n// ============ External Imports ============\nimport {IRouterClient} from \"@chainlink/contracts-ccip/src/v0.8/ccip/interfaces/IRouterClient.sol\";\nimport {Client} from \"@chainlink/contracts-ccip/src/v0.8/ccip/libraries/Client.sol\";\n\n/**\n * @title CCIPHook\n * @notice Message hook to inform the CCIP of messages published through CCIP.\n */\ncontract CCIPHook is AbstractMessageIdAuthHook {\n    using Message for bytes;\n    using TypeCasts for bytes32;\n\n    IRouterClient internal immutable ccipRouter;\n    uint64 public immutable ccipDestination;\n\n    // ============ Constructor ============\n\n    constructor(\n        address _ccipRouter,\n        uint64 _ccipDestination,\n        address _mailbox,\n        uint32 _destination,\n        bytes32 _ism\n    ) AbstractMessageIdAuthHook(_mailbox, _destination, _ism) {\n        ccipDestination = _ccipDestination;\n        ccipRouter = IRouterClient(_ccipRouter);\n    }\n\n    // ============ Internal functions ============\n\n    function _buildCCIPMessage(\n        bytes calldata message\n    ) internal view returns (Client.EVM2AnyMessage memory) {\n        // Create an EVM2AnyMessage struct in memory with necessary information for sending a cross-chain message\n        return\n            Client.EVM2AnyMessage({\n                receiver: abi.encode(ism),\n                data: abi.encode(message.id()),\n                tokenAmounts: new Client.EVMTokenAmount[](0),\n                extraArgs: Client._argsToBytes(\n                    Client.EVMExtraArgsV2({\n                        gasLimit: 60_000,\n                        allowOutOfOrderExecution: true\n                    })\n                ),\n                feeToken: address(0)\n            });\n    }\n\n    function _quoteDispatch(\n        bytes calldata /*metadata*/,\n        bytes calldata message\n    ) internal view override returns (uint256) {\n        Client.EVM2AnyMessage memory ccipMessage = _buildCCIPMessage(message);\n\n        return ccipRouter.getFee(ccipDestination, ccipMessage);\n    }\n\n    function _sendMessageId(\n        bytes calldata /*metadata*/,\n        bytes calldata message\n    ) internal override {\n        Client.EVM2AnyMessage memory ccipMessage = _buildCCIPMessage(message);\n\n        ccipRouter.ccipSend{value: msg.value}(ccipDestination, ccipMessage);\n    }\n}\n"},"contracts/hooks/DefaultHook.sol":{"content":"// SPDX-License-Identifier: MIT\npragma solidity >=0.8.0;\n\n// ============ Internal Imports ============\nimport {AbstractPostDispatchHook} from \"./libs/AbstractPostDispatchHook.sol\";\nimport {MailboxClient} from \"../client/MailboxClient.sol\";\nimport {IPostDispatchHook} from \"../interfaces/hooks/IPostDispatchHook.sol\";\n\n/**\n * @title DefaultHook\n * @notice Delegates to whatever hook behavior is defined as the default on the mailbox.\n */\ncontract DefaultHook is AbstractPostDispatchHook, MailboxClient {\n    constructor(address _mailbox) MailboxClient(_mailbox) {}\n\n    function hookType() external pure returns (uint8) {\n        return uint8(IPostDispatchHook.Types.MAILBOX_DEFAULT_HOOK);\n    }\n\n    function _hook() public view returns (IPostDispatchHook) {\n        return mailbox.defaultHook();\n    }\n\n    function _quoteDispatch(\n        bytes calldata metadata,\n        bytes calldata message\n    ) internal view virtual override returns (uint256) {\n        return _hook().quoteDispatch(metadata, message);\n    }\n\n    function _postDispatch(\n        bytes calldata metadata,\n        bytes calldata message\n    ) internal virtual override {\n        _hook().postDispatch{value: msg.value}(metadata, message);\n    }\n}\n"},"contracts/hooks/igp/InterchainGasPaymaster.sol":{"content":"// SPDX-License-Identifier: MIT OR Apache-2.0\npragma solidity >=0.8.0;\n\n/*@@@@@@@       @@@@@@@@@\n @@@@@@@@@       @@@@@@@@@\n  @@@@@@@@@       @@@@@@@@@\n   @@@@@@@@@       @@@@@@@@@\n    @@@@@@@@@@@@@@@@@@@@@@@@@\n     @@@@@  HYPERLANE  @@@@@@@\n    @@@@@@@@@@@@@@@@@@@@@@@@@\n   @@@@@@@@@       @@@@@@@@@\n  @@@@@@@@@       @@@@@@@@@\n @@@@@@@@@       @@@@@@@@@\n@@@@@@@@@       @@@@@@@@*/\n\n// ============ Internal Imports ============\nimport {Message} from \"../../libs/Message.sol\";\nimport {StandardHookMetadata} from \"../libs/StandardHookMetadata.sol\";\nimport {IGasOracle} from \"../../interfaces/IGasOracle.sol\";\nimport {IInterchainGasPaymaster} from \"../../interfaces/IInterchainGasPaymaster.sol\";\nimport {IPostDispatchHook} from \"../../interfaces/hooks/IPostDispatchHook.sol\";\nimport {AbstractPostDispatchHook} from \"../libs/AbstractPostDispatchHook.sol\";\nimport {Indexed} from \"../../libs/Indexed.sol\";\n\n// ============ External Imports ============\nimport {Strings} from \"@openzeppelin/contracts/utils/Strings.sol\";\nimport {Address} from \"@openzeppelin/contracts/utils/Address.sol\";\nimport {OwnableUpgradeable} from \"@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol\";\n\n/**\n * @title InterchainGasPaymaster\n * @notice Manages payments on a source chain to cover gas costs of relaying\n * messages to destination chains and includes the gas overhead per destination\n * @dev The intended use of this contract is to store overhead gas amounts for destination\n * domains, e.g. Mailbox and ISM gas usage, such that users of this IGP are only required\n * to specify the gas amount used by their own applications.\n */\ncontract InterchainGasPaymaster is\n    IInterchainGasPaymaster,\n    AbstractPostDispatchHook,\n    IGasOracle,\n    Indexed,\n    OwnableUpgradeable\n{\n    using Address for address payable;\n    using Message for bytes;\n    using StandardHookMetadata for bytes;\n    // ============ Constants ============\n\n    /// @notice The scale of gas oracle token exchange rates.\n    uint256 internal constant TOKEN_EXCHANGE_RATE_SCALE = 1e10;\n    /// @notice default for user call if metadata not provided\n    uint256 internal immutable DEFAULT_GAS_USAGE = 50_000;\n\n    // ============ Public Storage ============\n\n    /// @notice Destination domain => gas oracle and overhead gas amount.\n    mapping(uint32 destinationDomain => DomainGasConfig config)\n        public destinationGasConfigs;\n\n    /// @notice The benficiary that can receive native tokens paid into this contract.\n    address public beneficiary;\n\n    // ============ Events ============\n\n    /**\n     * @notice Emitted when the gas oracle for a remote domain is set.\n     * @param remoteDomain The remote domain.\n     * @param gasOracle The gas oracle.\n     * @param gasOverhead The destination gas overhead.\n     */\n    event DestinationGasConfigSet(\n        uint32 remoteDomain,\n        address gasOracle,\n        uint96 gasOverhead\n    );\n\n    /**\n     * @notice Emitted when the beneficiary is set.\n     * @param beneficiary The new beneficiary.\n     */\n    event BeneficiarySet(address beneficiary);\n\n    struct DomainGasConfig {\n        IGasOracle gasOracle;\n        uint96 gasOverhead;\n    }\n\n    struct GasParam {\n        uint32 remoteDomain;\n        DomainGasConfig config;\n    }\n\n    // ============ External Functions ============\n\n    /// @inheritdoc IPostDispatchHook\n    function hookType() external pure override returns (uint8) {\n        return uint8(IPostDispatchHook.Types.INTERCHAIN_GAS_PAYMASTER);\n    }\n\n    /**\n     * @param _owner The owner of the contract.\n     * @param _beneficiary The beneficiary.\n     */\n    function initialize(\n        address _owner,\n        address _beneficiary\n    ) public initializer {\n        __Ownable_init();\n        _transferOwnership(_owner);\n        _setBeneficiary(_beneficiary);\n    }\n\n    /**\n     * @notice Transfers the entire native token balance to the beneficiary.\n     * @dev The beneficiary must be able to receive native tokens.\n     */\n    function claim() external {\n        // Transfer the entire balance to the beneficiary.\n        (bool success, ) = beneficiary.call{value: address(this).balance}(\"\");\n        require(success, \"IGP: claim failed\");\n    }\n\n    /**\n     * @notice Sets the gas oracles for remote domains specified in the config array.\n     * @param _configs An array of configs including the remote domain and gas oracles to set.\n     */\n    function setDestinationGasConfigs(\n        GasParam[] calldata _configs\n    ) external onlyOwner {\n        uint256 _len = _configs.length;\n        for (uint256 i = 0; i < _len; i++) {\n            _setDestinationGasConfig(\n                _configs[i].remoteDomain,\n                _configs[i].config.gasOracle,\n                _configs[i].config.gasOverhead\n            );\n        }\n    }\n\n    /**\n     * @notice Sets the beneficiary.\n     * @param _beneficiary The new beneficiary.\n     */\n    function setBeneficiary(address _beneficiary) external onlyOwner {\n        _setBeneficiary(_beneficiary);\n    }\n\n    // ============ Public Functions ============\n\n    /**\n     * @notice Deposits msg.value as a payment for the relaying of a message\n     * to its destination chain.\n     * @dev Overpayment will result in a refund of native tokens to the _refundAddress.\n     * Callers should be aware that this may present reentrancy issues.\n     * @param _messageId The ID of the message to pay for.\n     * @param _destinationDomain The domain of the message's destination chain.\n     * @param _gasLimit The amount of destination gas to pay for.\n     * @param _refundAddress The address to refund any overpayment to.\n     */\n    function payForGas(\n        bytes32 _messageId,\n        uint32 _destinationDomain,\n        uint256 _gasLimit,\n        address _refundAddress\n    ) public payable override {\n        uint256 _requiredPayment = quoteGasPayment(\n            _destinationDomain,\n            _gasLimit\n        );\n        require(\n            msg.value >= _requiredPayment,\n            \"IGP: insufficient interchain gas payment\"\n        );\n        uint256 _overpayment = msg.value - _requiredPayment;\n        if (_overpayment > 0) {\n            require(_refundAddress != address(0), \"no refund address\");\n            payable(_refundAddress).sendValue(_overpayment);\n        }\n\n        emit GasPayment(\n            _messageId,\n            _destinationDomain,\n            _gasLimit,\n            _requiredPayment\n        );\n    }\n\n    /**\n     * @notice Quotes the amount of native tokens to pay for interchain gas.\n     * @param _destinationDomain The domain of the message's destination chain.\n     * @param _gasLimit The amount of destination gas to pay for.\n     * @return The amount of native tokens required to pay for interchain gas.\n     */\n    function quoteGasPayment(\n        uint32 _destinationDomain,\n        uint256 _gasLimit\n    ) public view virtual override returns (uint256) {\n        // Get the gas data for the destination domain.\n        (\n            uint128 _tokenExchangeRate,\n            uint128 _gasPrice\n        ) = getExchangeRateAndGasPrice(_destinationDomain);\n\n        // The total cost quoted in destination chain's native token.\n        uint256 _destinationGasCost = _gasLimit * uint256(_gasPrice);\n\n        // Convert to the local native token.\n        return\n            (_destinationGasCost * _tokenExchangeRate) /\n            TOKEN_EXCHANGE_RATE_SCALE;\n    }\n\n    /**\n     * @notice Gets the token exchange rate and gas price from the configured gas oracle\n     * for a given destination domain.\n     * @param _destinationDomain The destination domain.\n     * @return tokenExchangeRate The exchange rate of the remote native token quoted in the local native token.\n     * @return gasPrice The gas price on the remote chain.\n     */\n    function getExchangeRateAndGasPrice(\n        uint32 _destinationDomain\n    )\n        public\n        view\n        override\n        returns (uint128 tokenExchangeRate, uint128 gasPrice)\n    {\n        IGasOracle _gasOracle = destinationGasConfigs[_destinationDomain]\n            .gasOracle;\n\n        if (address(_gasOracle) == address(0)) {\n            revert(\n                string.concat(\n                    \"Configured IGP doesn't support domain \",\n                    Strings.toString(_destinationDomain)\n                )\n            );\n        }\n        return _gasOracle.getExchangeRateAndGasPrice(_destinationDomain);\n    }\n\n    /**\n     * @notice Returns the stored destinationGasOverhead added to the _gasLimit.\n     * @dev If there is no stored destinationGasOverhead, 0 is used. This is useful in the case\n     *      the ISM deployer wants to subsidize the overhead gas cost. Then, can specify the gas oracle\n     *      they want to use with the destination domain, but set the overhead to 0.\n     * @param _destinationDomain The domain of the message's destination chain.\n     * @param _gasLimit The amount of destination gas to pay for. This is only for application gas usage as\n     *      the gas usage for the mailbox and the ISM is already accounted in the DomainGasConfig.gasOverhead\n     */\n    function destinationGasLimit(\n        uint32 _destinationDomain,\n        uint256 _gasLimit\n    ) public view returns (uint256) {\n        return\n            uint256(destinationGasConfigs[_destinationDomain].gasOverhead) +\n            _gasLimit;\n    }\n\n    // ============ Internal Functions ============\n\n    /// @inheritdoc AbstractPostDispatchHook\n    function _postDispatch(\n        bytes calldata metadata,\n        bytes calldata message\n    ) internal override {\n        payForGas(\n            message.id(),\n            message.destination(),\n            destinationGasLimit(\n                message.destination(),\n                metadata.gasLimit(DEFAULT_GAS_USAGE)\n            ),\n            metadata.refundAddress(message.senderAddress())\n        );\n    }\n\n    /// @inheritdoc AbstractPostDispatchHook\n    function _quoteDispatch(\n        bytes calldata metadata,\n        bytes calldata message\n    ) internal view override returns (uint256) {\n        return\n            quoteGasPayment(\n                message.destination(),\n                destinationGasLimit(\n                    message.destination(),\n                    metadata.gasLimit(DEFAULT_GAS_USAGE)\n                )\n            );\n    }\n\n    /**\n     * @notice Sets the beneficiary.\n     * @param _beneficiary The new beneficiary.\n     */\n    function _setBeneficiary(address _beneficiary) internal {\n        beneficiary = _beneficiary;\n        emit BeneficiarySet(_beneficiary);\n    }\n\n    /**\n     * @notice Sets the gas oracle and destination gas overhead for a remote domain.\n     * @param _remoteDomain The remote domain.\n     * @param _gasOracle The gas oracle.\n     * @param _gasOverhead The destination gas overhead.\n     */\n    function _setDestinationGasConfig(\n        uint32 _remoteDomain,\n        IGasOracle _gasOracle,\n        uint96 _gasOverhead\n    ) internal {\n        destinationGasConfigs[_remoteDomain] = DomainGasConfig(\n            _gasOracle,\n            _gasOverhead\n        );\n        emit DestinationGasConfigSet(\n            _remoteDomain,\n            address(_gasOracle),\n            _gasOverhead\n        );\n    }\n}\n"},"contracts/hooks/igp/StorageGasOracle.sol":{"content":"// SPDX-License-Identifier: MIT OR Apache-2.0\npragma solidity >=0.8.0;\n\n// ============ Internal Imports ============\nimport {IGasOracle} from \"../../interfaces/IGasOracle.sol\";\nimport {PackageVersioned} from \"../../PackageVersioned.sol\";\n\n// ============ External Imports ============\nimport {Ownable} from \"@openzeppelin/contracts/access/Ownable.sol\";\n\n/**\n * @notice A gas oracle that uses data stored within the contract.\n * @dev This contract is intended to be owned by an address that will\n * update the stored remote gas data.\n */\ncontract StorageGasOracle is IGasOracle, Ownable, PackageVersioned {\n    // ============ Public Storage ============\n\n    /// @notice Keyed by remote domain, gas data on that remote domain.\n    mapping(uint32 remoteDomain => IGasOracle.RemoteGasData gasData)\n        public remoteGasData;\n\n    // ============ Events ============\n\n    /**\n     * @notice Emitted when an entry in `remoteGasData` is set.\n     * @param remoteDomain The remote domain in which the gas data was set for.\n     * @param tokenExchangeRate The exchange rate of the remote native token quoted in the local native token.\n     * @param gasPrice The gas price on the remote chain.\n     */\n    event RemoteGasDataSet(\n        uint32 indexed remoteDomain,\n        uint128 tokenExchangeRate,\n        uint128 gasPrice\n    );\n\n    struct RemoteGasDataConfig {\n        uint32 remoteDomain;\n        uint128 tokenExchangeRate;\n        uint128 gasPrice;\n    }\n\n    // ============ External Functions ============\n\n    /**\n     * @notice Returns the stored `remoteGasData` for the `_destinationDomain`.\n     * @param _destinationDomain The destination domain.\n     * @return tokenExchangeRate The exchange rate of the remote native token quoted in the local native token.\n     * @return gasPrice The gas price on the remote chain.\n     */\n    function getExchangeRateAndGasPrice(\n        uint32 _destinationDomain\n    )\n        external\n        view\n        override\n        returns (uint128 tokenExchangeRate, uint128 gasPrice)\n    {\n        // Intentionally allow unset / zero values\n        IGasOracle.RemoteGasData memory _data = remoteGasData[\n            _destinationDomain\n        ];\n        return (_data.tokenExchangeRate, _data.gasPrice);\n    }\n\n    /**\n     * @notice Sets the remote gas data for many remotes at a time.\n     * @param _configs The configs to use when setting the remote gas data.\n     */\n    function setRemoteGasDataConfigs(\n        RemoteGasDataConfig[] calldata _configs\n    ) external onlyOwner {\n        uint256 _len = _configs.length;\n        for (uint256 i = 0; i < _len; i++) {\n            _setRemoteGasData(_configs[i]);\n        }\n    }\n\n    /**\n     * @notice Sets the remote gas data using the values in `_config`.\n     * @param _config The config to use when setting the remote gas data.\n     */\n    function setRemoteGasData(\n        RemoteGasDataConfig calldata _config\n    ) external onlyOwner {\n        _setRemoteGasData(_config);\n    }\n\n    // ============ Internal functions ============\n\n    /**\n     * @notice Sets the remote gas data using the values in `_config`.\n     * @param _config The config to use when setting the remote gas data.\n     */\n    function _setRemoteGasData(RemoteGasDataConfig calldata _config) internal {\n        remoteGasData[_config.remoteDomain] = IGasOracle.RemoteGasData({\n            tokenExchangeRate: _config.tokenExchangeRate,\n            gasPrice: _config.gasPrice\n        });\n\n        emit RemoteGasDataSet(\n            _config.remoteDomain,\n            _config.tokenExchangeRate,\n            _config.gasPrice\n        );\n    }\n}\n"},"contracts/hooks/libs/AbstractMessageIdAuthHook.sol":{"content":"// SPDX-License-Identifier: MIT OR Apache-2.0\npragma solidity >=0.8.0;\n\n/*@@@@@@@       @@@@@@@@@\n @@@@@@@@@       @@@@@@@@@\n  @@@@@@@@@       @@@@@@@@@\n   @@@@@@@@@       @@@@@@@@@\n    @@@@@@@@@@@@@@@@@@@@@@@@@\n     @@@@@  HYPERLANE  @@@@@@@\n    @@@@@@@@@@@@@@@@@@@@@@@@@\n   @@@@@@@@@       @@@@@@@@@\n  @@@@@@@@@       @@@@@@@@@\n @@@@@@@@@       @@@@@@@@@\n@@@@@@@@@       @@@@@@@@*/\n\n// ============ Internal Imports ============\nimport {IPostDispatchHook} from \"../../interfaces/hooks/IPostDispatchHook.sol\";\nimport {AbstractPostDispatchHook} from \"./AbstractPostDispatchHook.sol\";\nimport {Message} from \"../../libs/Message.sol\";\nimport {StandardHookMetadata} from \"./StandardHookMetadata.sol\";\nimport {MailboxClient} from \"../../client/MailboxClient.sol\";\n\n// ============ External Imports ============\nimport {Address} from \"@openzeppelin/contracts/utils/Address.sol\";\n\n/**\n * @title AbstractMessageIdAuthHook\n * @notice Message hook to inform an Abstract Message ID ISM of messages published through\n * a third-party bridge.\n */\nabstract contract AbstractMessageIdAuthHook is\n    AbstractPostDispatchHook,\n    MailboxClient\n{\n    using Address for address payable;\n    using StandardHookMetadata for bytes;\n    using Message for bytes;\n\n    // ============ Constants ============\n\n    // left-padded address for ISM to verify messages\n    bytes32 public immutable ism;\n    // Domain of chain on which the ISM is deployed\n    uint32 public immutable destinationDomain;\n\n    // ============ Constructor ============\n\n    constructor(\n        address _mailbox,\n        uint32 _destinationDomain,\n        bytes32 _ism\n    ) MailboxClient(_mailbox) {\n        require(_ism != bytes32(0), \"AbstractMessageIdAuthHook: invalid ISM\");\n        require(\n            _destinationDomain != 0,\n            \"AbstractMessageIdAuthHook: invalid destination domain\"\n        );\n        ism = _ism;\n        destinationDomain = _destinationDomain;\n    }\n\n    /// @inheritdoc IPostDispatchHook\n    function hookType() external pure virtual returns (uint8) {\n        return uint8(IPostDispatchHook.Types.ID_AUTH_ISM);\n    }\n\n    // ============ Internal functions ============\n\n    /// @inheritdoc AbstractPostDispatchHook\n    function _postDispatch(\n        bytes calldata metadata,\n        bytes calldata message\n    ) internal virtual override {\n        bytes32 id = message.id();\n        require(\n            _isLatestDispatched(id),\n            \"AbstractMessageIdAuthHook: message not latest dispatched\"\n        );\n        require(\n            message.destination() == destinationDomain,\n            \"AbstractMessageIdAuthHook: invalid destination domain\"\n        );\n        require(\n            metadata.msgValue(0) < 2 ** 255,\n            \"AbstractMessageIdAuthHook: msgValue must be less than 2 ** 255\"\n        );\n\n        _sendMessageId(metadata, message);\n\n        _refund(metadata, message, address(this).balance);\n    }\n\n    /**\n     * @notice Send a message to the ISM.\n     * @param metadata The metadata for the hook caller\n     * @param message The message to send to the ISM\n     */\n    function _sendMessageId(\n        bytes calldata metadata,\n        bytes calldata message\n    ) internal virtual;\n}\n"},"contracts/hooks/libs/AbstractPostDispatchHook.sol":{"content":"// SPDX-License-Identifier: MIT OR Apache-2.0\npragma solidity >=0.8.0;\n\n/*@@@@@@@       @@@@@@@@@\n @@@@@@@@@       @@@@@@@@@\n  @@@@@@@@@       @@@@@@@@@\n   @@@@@@@@@       @@@@@@@@@\n    @@@@@@@@@@@@@@@@@@@@@@@@@\n     @@@@@  HYPERLANE  @@@@@@@\n    @@@@@@@@@@@@@@@@@@@@@@@@@\n   @@@@@@@@@       @@@@@@@@@\n  @@@@@@@@@       @@@@@@@@@\n @@@@@@@@@       @@@@@@@@@\n@@@@@@@@@       @@@@@@@@*/\n\nimport {Address} from \"@openzeppelin/contracts/utils/Address.sol\";\n\n// ============ Internal Imports ============\nimport {StandardHookMetadata} from \"./StandardHookMetadata.sol\";\nimport {IPostDispatchHook} from \"../../interfaces/hooks/IPostDispatchHook.sol\";\nimport {PackageVersioned} from \"../../PackageVersioned.sol\";\nimport {Message} from \"../../libs/Message.sol\";\n\n/**\n * @title AbstractPostDispatch\n * @notice Abstract post dispatch hook supporting the current global hook metadata variant.\n */\nabstract contract AbstractPostDispatchHook is\n    IPostDispatchHook,\n    PackageVersioned\n{\n    using StandardHookMetadata for bytes;\n    using Message for bytes;\n    using Address for address payable;\n\n    // ============ External functions ============\n\n    /// @inheritdoc IPostDispatchHook\n    function supportsMetadata(\n        bytes calldata metadata\n    ) public pure virtual override returns (bool) {\n        return\n            metadata.length == 0 ||\n            metadata.variant() == StandardHookMetadata.VARIANT;\n    }\n\n    function _refund(\n        bytes calldata metadata,\n        bytes calldata message,\n        uint256 amount\n    ) internal {\n        if (amount == 0) {\n            return;\n        }\n\n        address refundAddress = metadata.refundAddress(message.senderAddress());\n        require(\n            refundAddress != address(0),\n            \"AbstractPostDispatchHook: no refund address\"\n        );\n        payable(refundAddress).sendValue(amount);\n    }\n\n    /// @inheritdoc IPostDispatchHook\n    function postDispatch(\n        bytes calldata metadata,\n        bytes calldata message\n    ) external payable override {\n        require(\n            supportsMetadata(metadata),\n            \"AbstractPostDispatchHook: invalid metadata variant\"\n        );\n        _postDispatch(metadata, message);\n    }\n\n    /// @inheritdoc IPostDispatchHook\n    function quoteDispatch(\n        bytes calldata metadata,\n        bytes calldata message\n    ) public view override returns (uint256) {\n        require(\n            supportsMetadata(metadata),\n            \"AbstractPostDispatchHook: invalid metadata variant\"\n        );\n        return _quoteDispatch(metadata, message);\n    }\n\n    // ============ Internal functions ============\n\n    /**\n     * @notice Post dispatch hook implementation.\n     * @param metadata The metadata of the message being dispatched.\n     * @param message The message being dispatched.\n     */\n    function _postDispatch(\n        bytes calldata metadata,\n        bytes calldata message\n    ) internal virtual;\n\n    /**\n     * @notice Quote dispatch hook implementation.\n     * @param metadata The metadata of the message being dispatched.\n     * @param message The message being dispatched.\n     * @return The quote for the dispatch.\n     */\n    function _quoteDispatch(\n        bytes calldata metadata,\n        bytes calldata message\n    ) internal view virtual returns (uint256);\n}\n"},"contracts/hooks/libs/StandardHookMetadata.sol":{"content":"// SPDX-License-Identifier: MIT OR Apache-2.0\npragma solidity >=0.8.0;\n\n/*@@@@@@@       @@@@@@@@@\n @@@@@@@@@       @@@@@@@@@\n  @@@@@@@@@       @@@@@@@@@\n   @@@@@@@@@       @@@@@@@@@\n    @@@@@@@@@@@@@@@@@@@@@@@@@\n     @@@@@  HYPERLANE  @@@@@@@\n    @@@@@@@@@@@@@@@@@@@@@@@@@\n   @@@@@@@@@       @@@@@@@@@\n  @@@@@@@@@       @@@@@@@@@\n @@@@@@@@@       @@@@@@@@@\n@@@@@@@@@       @@@@@@@@*/\n\n/**\n * Format of metadata:\n *\n * [0:2] variant\n * [2:34] msg.value\n * [34:66] Gas limit for message (IGP)\n * [66:86] Refund address for message (IGP)\n * [86:] Custom metadata\n */\n\nlibrary StandardHookMetadata {\n    struct Metadata {\n        uint16 variant;\n        uint256 msgValue;\n        uint256 gasLimit;\n        address refundAddress;\n    }\n\n    uint8 private constant VARIANT_OFFSET = 0;\n    uint8 private constant MSG_VALUE_OFFSET = 2;\n    uint8 private constant GAS_LIMIT_OFFSET = 34;\n    uint8 private constant REFUND_ADDRESS_OFFSET = 66;\n    uint256 private constant MIN_METADATA_LENGTH = 86;\n\n    uint16 public constant VARIANT = 1;\n\n    /**\n     * @notice Returns the variant of the metadata.\n     * @param _metadata ABI encoded standard hook metadata.\n     * @return variant of the metadata as uint8.\n     */\n    function variant(bytes calldata _metadata) internal pure returns (uint16) {\n        if (_metadata.length < VARIANT_OFFSET + 2) return 0;\n        return uint16(bytes2(_metadata[VARIANT_OFFSET:VARIANT_OFFSET + 2]));\n    }\n\n    /**\n     * @notice Returns the specified value for the message.\n     * @param _metadata ABI encoded standard hook metadata.\n     * @param _default Default fallback value.\n     * @return Value for the message as uint256.\n     */\n    function msgValue(\n        bytes calldata _metadata,\n        uint256 _default\n    ) internal pure returns (uint256) {\n        if (_metadata.length < MSG_VALUE_OFFSET + 32) return _default;\n        return\n            uint256(bytes32(_metadata[MSG_VALUE_OFFSET:MSG_VALUE_OFFSET + 32]));\n    }\n\n    /**\n     * @notice Returns the specified gas limit for the message.\n     * @param _metadata ABI encoded standard hook metadata.\n     * @param _default Default fallback gas limit.\n     * @return Gas limit for the message as uint256.\n     */\n    function gasLimit(\n        bytes calldata _metadata,\n        uint256 _default\n    ) internal pure returns (uint256) {\n        if (_metadata.length < GAS_LIMIT_OFFSET + 32) return _default;\n        return\n            uint256(bytes32(_metadata[GAS_LIMIT_OFFSET:GAS_LIMIT_OFFSET + 32]));\n    }\n\n    function gasLimit(\n        bytes memory _metadata\n    ) internal pure returns (uint256 _gasLimit) {\n        if (_metadata.length < GAS_LIMIT_OFFSET + 32) return 50_000;\n        assembly {\n            _gasLimit := mload(add(_metadata, add(0x20, GAS_LIMIT_OFFSET)))\n        }\n    }\n\n    /**\n     * @notice Returns the specified refund address for the message.\n     * @param _metadata ABI encoded standard hook metadata.\n     * @param _default Default fallback refund address.\n     * @return Refund address for the message as address.\n     */\n    function refundAddress(\n        bytes calldata _metadata,\n        address _default\n    ) internal pure returns (address) {\n        if (_metadata.length < REFUND_ADDRESS_OFFSET + 20) return _default;\n        return\n            address(\n                bytes20(\n                    _metadata[REFUND_ADDRESS_OFFSET:REFUND_ADDRESS_OFFSET + 20]\n                )\n            );\n    }\n\n    /**\n     * @notice Returns any custom metadata.\n     * @param _metadata ABI encoded standard hook metadata.\n     * @return Custom metadata.\n     */\n    function getCustomMetadata(\n        bytes calldata _metadata\n    ) internal pure returns (bytes calldata) {\n        if (_metadata.length < MIN_METADATA_LENGTH) return _metadata[0:0];\n        return _metadata[MIN_METADATA_LENGTH:];\n    }\n\n    /**\n     * @notice Formats the specified gas limit and refund address into standard hook metadata.\n     * @param _msgValue msg.value for the message.\n     * @param _gasLimit Gas limit for the message.\n     * @param _refundAddress Refund address for the message.\n     * @return ABI encoded standard hook metadata.\n     */\n    function format(\n        uint256 _msgValue,\n        uint256 _gasLimit,\n        address _refundAddress\n    ) internal pure returns (bytes memory) {\n        return abi.encodePacked(VARIANT, _msgValue, _gasLimit, _refundAddress);\n    }\n\n    /**\n\n    /**\n     * @notice Formats the specified gas limit and refund address into standard hook metadata.\n     * @param _msgValue msg.value for the message.\n     * @param _gasLimit Gas limit for the message.\n     * @param _refundAddress Refund address for the message.\n     * @param _customMetadata Additional metadata to include in the standard hook metadata.\n     * @return ABI encoded standard hook metadata.\n     */\n    function formatMetadata(\n        uint256 _msgValue,\n        uint256 _gasLimit,\n        address _refundAddress,\n        bytes memory _customMetadata\n    ) internal pure returns (bytes memory) {\n        return\n            abi.encodePacked(\n                VARIANT,\n                _msgValue,\n                _gasLimit,\n                _refundAddress,\n                _customMetadata\n            );\n    }\n\n    /**\n     * @notice Formats the specified gas limit and refund address into standard hook metadata.\n     * @param _msgValue msg.value for the message.\n     * @return ABI encoded standard hook metadata.\n     */\n    function overrideMsgValue(\n        uint256 _msgValue\n    ) internal view returns (bytes memory) {\n        return formatMetadata(_msgValue, uint256(0), msg.sender, \"\");\n    }\n\n    /**\n     * @notice Formats the specified gas limit and refund address into standard hook metadata.\n     * @param _gasLimit Gas limit for the message.\n     * @return ABI encoded standard hook metadata.\n     */\n    function overrideGasLimit(\n        uint256 _gasLimit\n    ) internal view returns (bytes memory) {\n        return formatMetadata(uint256(0), _gasLimit, msg.sender, \"\");\n    }\n\n    /**\n     * @notice Formats the specified refund address into standard hook metadata.\n     * @param _refundAddress Refund address for the message.\n     * @return ABI encoded standard hook metadata.\n     */\n    function overrideRefundAddress(\n        address _refundAddress\n    ) internal pure returns (bytes memory) {\n        return formatMetadata(uint256(0), uint256(0), _refundAddress, \"\");\n    }\n\n    function getRefundAddress(\n        bytes memory _metadata,\n        address _default\n    ) internal pure returns (address) {\n        if (_metadata.length < REFUND_ADDRESS_OFFSET + 20) return _default;\n        address result;\n        assembly {\n            let data_start_ptr := add(_metadata, 32) // Skip length prefix of _metadata\n            let mload_ptr := add(data_start_ptr, sub(REFUND_ADDRESS_OFFSET, 12))\n            result := mload(mload_ptr) // Loads 32 bytes; address takes lower 20 bytes.\n        }\n        return result;\n    }\n}\n"},"contracts/hooks/MerkleTreeHook.sol":{"content":"// SPDX-License-Identifier: MIT\npragma solidity >=0.8.0;\n\n/*@@@@@@@       @@@@@@@@@\n @@@@@@@@@       @@@@@@@@@\n  @@@@@@@@@       @@@@@@@@@\n   @@@@@@@@@       @@@@@@@@@\n    @@@@@@@@@@@@@@@@@@@@@@@@@\n     @@@@@  HYPERLANE  @@@@@@@\n    @@@@@@@@@@@@@@@@@@@@@@@@@\n   @@@@@@@@@       @@@@@@@@@\n  @@@@@@@@@       @@@@@@@@@\n @@@@@@@@@       @@@@@@@@@\n@@@@@@@@@       @@@@@@@@*/\n\nimport {MerkleLib} from \"../libs/Merkle.sol\";\nimport {Message} from \"../libs/Message.sol\";\nimport {MailboxClient} from \"../client/MailboxClient.sol\";\nimport {Indexed} from \"../libs/Indexed.sol\";\nimport {IPostDispatchHook} from \"../interfaces/hooks/IPostDispatchHook.sol\";\nimport {AbstractPostDispatchHook} from \"./libs/AbstractPostDispatchHook.sol\";\nimport {StandardHookMetadata} from \"./libs/StandardHookMetadata.sol\";\n\ncontract MerkleTreeHook is AbstractPostDispatchHook, MailboxClient, Indexed {\n    using Message for bytes;\n    using MerkleLib for MerkleLib.Tree;\n    using StandardHookMetadata for bytes;\n\n    // An incremental merkle tree used to store outbound message IDs.\n    MerkleLib.Tree internal _tree;\n\n    event InsertedIntoTree(bytes32 messageId, uint32 index);\n\n    constructor(address _mailbox) MailboxClient(_mailbox) {}\n\n    // count cannot exceed 2**TREE_DEPTH, see MerkleLib.sol\n    function count() public view returns (uint32) {\n        return uint32(_tree.count);\n    }\n\n    function root() public view returns (bytes32) {\n        return _tree.root();\n    }\n\n    function tree() public view returns (MerkleLib.Tree memory) {\n        return _tree;\n    }\n\n    function latestCheckpoint() external view returns (bytes32, uint32) {\n        return (root(), count() - 1);\n    }\n\n    // ============ External Functions ============\n\n    /// @inheritdoc IPostDispatchHook\n    function hookType() external pure override returns (uint8) {\n        return uint8(IPostDispatchHook.Types.MERKLE_TREE);\n    }\n\n    // ============ Internal Functions ============\n\n    /// @inheritdoc AbstractPostDispatchHook\n    function _postDispatch(\n        bytes calldata,\n        /*metadata*/\n        bytes calldata message\n    ) internal override {\n        require(msg.value == 0, \"MerkleTreeHook: no value expected\");\n\n        // ensure messages which were not dispatched are not inserted into the tree\n        bytes32 id = message.id();\n        require(_isLatestDispatched(id), \"message not dispatching\");\n\n        uint32 index = count();\n        _tree.insert(id);\n        emit InsertedIntoTree(id, index);\n    }\n\n    /// @inheritdoc AbstractPostDispatchHook\n    function _quoteDispatch(\n        bytes calldata,\n        /*metadata*/\n        bytes calldata /*message*/\n    ) internal pure override returns (uint256) {\n        return 0;\n    }\n}\n"},"contracts/hooks/OPL2ToL1Hook.sol":{"content":"// SPDX-License-Identifier: MIT OR Apache-2.0\npragma solidity >=0.8.0;\n\n/*@@@@@@@       @@@@@@@@@\n @@@@@@@@@       @@@@@@@@@\n  @@@@@@@@@       @@@@@@@@@\n   @@@@@@@@@       @@@@@@@@@\n    @@@@@@@@@@@@@@@@@@@@@@@@@\n     @@@@@  HYPERLANE  @@@@@@@\n    @@@@@@@@@@@@@@@@@@@@@@@@@\n   @@@@@@@@@       @@@@@@@@@\n  @@@@@@@@@       @@@@@@@@@\n @@@@@@@@@       @@@@@@@@@\n@@@@@@@@@       @@@@@@@@*/\n\n// ============ Internal Imports ============\nimport {Message} from \"../libs/Message.sol\";\nimport {AbstractPostDispatchHook, AbstractMessageIdAuthHook} from \"./libs/AbstractMessageIdAuthHook.sol\";\nimport {AbstractMessageIdAuthorizedIsm} from \"../isms/hook/AbstractMessageIdAuthorizedIsm.sol\";\nimport {StandardHookMetadata} from \"./libs/StandardHookMetadata.sol\";\nimport {TypeCasts} from \"../libs/TypeCasts.sol\";\nimport {IPostDispatchHook} from \"../interfaces/hooks/IPostDispatchHook.sol\";\n\n// ============ External Imports ============\nimport {ICrossDomainMessenger} from \"../interfaces/optimism/ICrossDomainMessenger.sol\";\n\n/**\n * @title OPL2ToL1Hook\n * @notice Message hook to inform the OPL2ToL1Ism of messages published through\n * the native Optimism bridge.\n * @notice This works only for L2 -> L1 messages and has the 7 day delay as specified by the OptimismPortal contract.\n */\ncontract OPL2ToL1Hook is AbstractMessageIdAuthHook {\n    using StandardHookMetadata for bytes;\n    using Message for bytes;\n\n    // ============ Constants ============\n\n    // precompile contract on L2 for sending messages to L1\n    ICrossDomainMessenger public immutable l2Messenger;\n    // child hook to call first\n    IPostDispatchHook public immutable childHook;\n    // Minimum gas limit that the message can be executed with - OP specific\n    uint32 public constant MIN_GAS_LIMIT = 300_000;\n\n    // ============ Constructor ============\n\n    constructor(\n        address _mailbox,\n        uint32 _destinationDomain,\n        bytes32 _ism,\n        address _l2Messenger,\n        address _childHook\n    ) AbstractMessageIdAuthHook(_mailbox, _destinationDomain, _ism) {\n        l2Messenger = ICrossDomainMessenger(_l2Messenger);\n        childHook = AbstractPostDispatchHook(_childHook);\n    }\n\n    /// @inheritdoc IPostDispatchHook\n    function hookType() external pure override returns (uint8) {\n        return uint8(IPostDispatchHook.Types.OP_L2_TO_L1);\n    }\n\n    /// @inheritdoc AbstractPostDispatchHook\n    function _quoteDispatch(\n        bytes calldata metadata,\n        bytes calldata message\n    ) internal view override returns (uint256) {\n        return\n            metadata.msgValue(0) + childHook.quoteDispatch(metadata, message);\n    }\n\n    // ============ Internal functions ============\n\n    /// @inheritdoc AbstractMessageIdAuthHook\n    function _sendMessageId(\n        bytes calldata metadata,\n        bytes calldata message\n    ) internal override {\n        bytes memory payload = abi.encodeCall(\n            AbstractMessageIdAuthorizedIsm.preVerifyMessage,\n            (message.id(), metadata.msgValue(0))\n        );\n\n        childHook.postDispatch{\n            value: childHook.quoteDispatch(metadata, message)\n        }(metadata, message);\n        l2Messenger.sendMessage{value: metadata.msgValue(0)}(\n            TypeCasts.bytes32ToAddress(ism),\n            payload,\n            MIN_GAS_LIMIT\n        );\n    }\n}\n"},"contracts/hooks/OPStackHook.sol":{"content":"// SPDX-License-Identifier: MIT OR Apache-2.0\npragma solidity >=0.8.0;\n\n/*@@@@@@@       @@@@@@@@@\n @@@@@@@@@       @@@@@@@@@\n  @@@@@@@@@       @@@@@@@@@\n   @@@@@@@@@       @@@@@@@@@\n    @@@@@@@@@@@@@@@@@@@@@@@@@\n     @@@@@  HYPERLANE  @@@@@@@\n    @@@@@@@@@@@@@@@@@@@@@@@@@\n   @@@@@@@@@       @@@@@@@@@\n  @@@@@@@@@       @@@@@@@@@\n @@@@@@@@@       @@@@@@@@@\n@@@@@@@@@       @@@@@@@@*/\n\n// ============ Internal Imports ============\nimport {AbstractMessageIdAuthHook} from \"./libs/AbstractMessageIdAuthHook.sol\";\nimport {StandardHookMetadata} from \"./libs/StandardHookMetadata.sol\";\nimport {TypeCasts} from \"../libs/TypeCasts.sol\";\nimport {Message} from \"../libs/Message.sol\";\nimport {AbstractMessageIdAuthorizedIsm} from \"../isms/hook/AbstractMessageIdAuthorizedIsm.sol\";\n\n// ============ External Imports ============\nimport {ICrossDomainMessenger} from \"../interfaces/optimism/ICrossDomainMessenger.sol\";\nimport {Address} from \"@openzeppelin/contracts/utils/Address.sol\";\n\n/**\n * @title OPStackHook\n * @notice Message hook to inform the OPStackIsm of messages published through\n * the native OPStack bridge.\n * @notice This works only for L1 -> L2 messages.\n */\ncontract OPStackHook is AbstractMessageIdAuthHook {\n    using StandardHookMetadata for bytes;\n    using Message for bytes;\n\n    // ============ Constants ============\n\n    /// @notice messenger contract specified by the rollup\n    ICrossDomainMessenger public immutable l1Messenger;\n\n    // Gas limit for sending messages to L2\n    // First 1.92e6 gas is provided by Optimism, see more here:\n    // https://community.optimism.io/docs/developers/bridge/messaging/#for-l1-%E2%87%92-l2-transactions\n    uint32 internal constant GAS_LIMIT = 1_920_000;\n\n    // ============ Constructor ============\n\n    constructor(\n        address _mailbox,\n        uint32 _destinationDomain,\n        bytes32 _ism,\n        address _l1Messenger\n    ) AbstractMessageIdAuthHook(_mailbox, _destinationDomain, _ism) {\n        require(\n            Address.isContract(_l1Messenger),\n            \"OPStackHook: invalid messenger\"\n        );\n        l1Messenger = ICrossDomainMessenger(_l1Messenger);\n    }\n\n    // ============ Internal functions ============\n    function _quoteDispatch(\n        bytes calldata metadata,\n        bytes calldata\n    ) internal pure override returns (uint256) {\n        return metadata.msgValue(0); // gas subsidized by the L2\n    }\n\n    /// @inheritdoc AbstractMessageIdAuthHook\n    function _sendMessageId(\n        bytes calldata metadata,\n        bytes calldata message\n    ) internal override {\n        bytes memory payload = abi.encodeCall(\n            AbstractMessageIdAuthorizedIsm.preVerifyMessage,\n            (message.id(), metadata.msgValue(0))\n        );\n\n        l1Messenger.sendMessage{value: metadata.msgValue(0)}(\n            TypeCasts.bytes32ToAddress(ism),\n            payload,\n            GAS_LIMIT\n        );\n    }\n}\n"},"contracts/hooks/PausableHook.sol":{"content":"// SPDX-License-Identifier: MIT\npragma solidity >=0.8.0;\n\n/*@@@@@@@       @@@@@@@@@\n @@@@@@@@@       @@@@@@@@@\n  @@@@@@@@@       @@@@@@@@@\n   @@@@@@@@@       @@@@@@@@@\n    @@@@@@@@@@@@@@@@@@@@@@@@@\n     @@@@@  HYPERLANE  @@@@@@@\n    @@@@@@@@@@@@@@@@@@@@@@@@@\n   @@@@@@@@@       @@@@@@@@@\n  @@@@@@@@@       @@@@@@@@@\n @@@@@@@@@       @@@@@@@@@\n@@@@@@@@@       @@@@@@@@*/\n\nimport {IPostDispatchHook} from \"../interfaces/hooks/IPostDispatchHook.sol\";\nimport {AbstractPostDispatchHook} from \"./libs/AbstractPostDispatchHook.sol\";\n\nimport {Ownable} from \"@openzeppelin/contracts/access/Ownable.sol\";\nimport {Pausable} from \"@openzeppelin/contracts/security/Pausable.sol\";\n\ncontract PausableHook is AbstractPostDispatchHook, Ownable, Pausable {\n    // ============ External functions ============\n\n    function pause() external onlyOwner {\n        _pause();\n    }\n\n    function unpause() external onlyOwner {\n        _unpause();\n    }\n\n    // ============ External Functions ============\n\n    /// @inheritdoc IPostDispatchHook\n    function hookType() external pure override returns (uint8) {\n        return uint8(IPostDispatchHook.Types.PAUSABLE);\n    }\n\n    // ============ Internal functions ============\n\n    /// @inheritdoc AbstractPostDispatchHook\n    function _postDispatch(\n        bytes calldata metadata,\n        bytes calldata message\n    ) internal override whenNotPaused {}\n\n    /// @inheritdoc AbstractPostDispatchHook\n    function _quoteDispatch(\n        bytes calldata,\n        bytes calldata\n    ) internal pure override returns (uint256) {\n        return 0;\n    }\n}\n"},"contracts/hooks/ProtocolFee.sol":{"content":"// SPDX-License-Identifier: MIT OR Apache-2.0\npragma solidity >=0.8.0;\n\n/*@@@@@@@       @@@@@@@@@\n @@@@@@@@@       @@@@@@@@@\n  @@@@@@@@@       @@@@@@@@@\n   @@@@@@@@@       @@@@@@@@@\n    @@@@@@@@@@@@@@@@@@@@@@@@@\n     @@@@@  HYPERLANE  @@@@@@@\n    @@@@@@@@@@@@@@@@@@@@@@@@@\n   @@@@@@@@@       @@@@@@@@@\n  @@@@@@@@@       @@@@@@@@@\n @@@@@@@@@       @@@@@@@@@\n@@@@@@@@@       @@@@@@@@*/\n\n// ============ Internal Imports ============\nimport {Message} from \"../libs/Message.sol\";\nimport {StandardHookMetadata} from \"./libs/StandardHookMetadata.sol\";\nimport {AbstractPostDispatchHook} from \"./libs/AbstractPostDispatchHook.sol\";\nimport {IPostDispatchHook} from \"../interfaces/hooks/IPostDispatchHook.sol\";\n\n// ============ External Imports ============\nimport {Address} from \"@openzeppelin/contracts/utils/Address.sol\";\nimport {Ownable} from \"@openzeppelin/contracts/access/Ownable.sol\";\n\n/**\n * @title ProtocolFee\n * @notice Collects a static protocol fee from the sender.\n */\ncontract ProtocolFee is AbstractPostDispatchHook, Ownable {\n    using StandardHookMetadata for bytes;\n    using Address for address payable;\n    using Message for bytes;\n\n    event ProtocolFeeSet(uint256 protocolFee);\n    event BeneficiarySet(address beneficiary);\n\n    // ============ Constants ============\n\n    /// @notice The maximum protocol fee that can be set.\n    uint256 public immutable MAX_PROTOCOL_FEE;\n\n    // ============ Public Storage ============\n\n    /// @notice The current protocol fee.\n    uint256 public protocolFee;\n    /// @notice The beneficiary of protocol fees.\n    address public beneficiary;\n\n    // ============ Constructor ============\n\n    constructor(\n        uint256 _maxProtocolFee,\n        uint256 _protocolFee,\n        address _beneficiary,\n        address _owner\n    ) {\n        MAX_PROTOCOL_FEE = _maxProtocolFee;\n        _setProtocolFee(_protocolFee);\n        _setBeneficiary(_beneficiary);\n        _transferOwnership(_owner);\n    }\n\n    // ============ External Functions ============\n\n    /// @inheritdoc IPostDispatchHook\n    function hookType() external pure override returns (uint8) {\n        return uint8(IPostDispatchHook.Types.PROTOCOL_FEE);\n    }\n\n    /**\n     * @notice Sets the protocol fee.\n     * @param _protocolFee The new protocol fee.\n     */\n    function setProtocolFee(uint256 _protocolFee) external onlyOwner {\n        _setProtocolFee(_protocolFee);\n    }\n\n    /**\n     * @notice Sets the beneficiary of protocol fees.\n     * @param _beneficiary The new beneficiary.\n     */\n    function setBeneficiary(address _beneficiary) external onlyOwner {\n        _setBeneficiary(_beneficiary);\n    }\n\n    /**\n     * @notice Collects protocol fees from the contract.\n     */\n    function collectProtocolFees() external {\n        payable(beneficiary).sendValue(address(this).balance);\n    }\n\n    // ============ Internal Functions ============\n\n    /// @inheritdoc AbstractPostDispatchHook\n    function _postDispatch(\n        bytes calldata metadata,\n        bytes calldata message\n    ) internal override {\n        require(\n            msg.value >= protocolFee,\n            \"ProtocolFee: insufficient protocol fee\"\n        );\n\n        _refund(metadata, message, msg.value - protocolFee);\n    }\n\n    /// @inheritdoc AbstractPostDispatchHook\n    function _quoteDispatch(\n        bytes calldata,\n        bytes calldata\n    ) internal view override returns (uint256) {\n        return protocolFee;\n    }\n\n    /**\n     * @notice Sets the protocol fee.\n     * @param _protocolFee The new protocol fee.\n     */\n    function _setProtocolFee(uint256 _protocolFee) internal {\n        require(\n            _protocolFee <= MAX_PROTOCOL_FEE,\n            \"ProtocolFee: exceeds max protocol fee\"\n        );\n        protocolFee = _protocolFee;\n        emit ProtocolFeeSet(_protocolFee);\n    }\n\n    /**\n     * @notice Sets the beneficiary of protocol fees.\n     * @param _beneficiary The new beneficiary.\n     */\n    function _setBeneficiary(address _beneficiary) internal {\n        require(_beneficiary != address(0), \"ProtocolFee: invalid beneficiary\");\n        beneficiary = _beneficiary;\n        emit BeneficiarySet(_beneficiary);\n    }\n}\n"},"contracts/hooks/routing/AmountRoutingHook.sol":{"content":"// SPDX-License-Identifier: MIT OR Apache-2.0\npragma solidity >=0.8.0;\n\n// ============ Internal Imports ============\nimport {AbstractPostDispatchHook} from \"../libs/AbstractPostDispatchHook.sol\";\nimport {IPostDispatchHook} from \"../../interfaces/hooks/IPostDispatchHook.sol\";\nimport {AmountPartition} from \"../../token/libs/AmountPartition.sol\";\n\n/**\n * @title AmountRoutingHook\n */\ncontract AmountRoutingHook is AmountPartition, AbstractPostDispatchHook {\n    constructor(\n        address _lowerHook,\n        address _upperHook,\n        uint256 _threshold\n    ) AmountPartition(_lowerHook, _upperHook, _threshold) {}\n\n    function hookType() external pure override returns (uint8) {\n        return uint8(IPostDispatchHook.Types.AMOUNT_ROUTING);\n    }\n\n    function _postDispatch(\n        bytes calldata _metadata,\n        bytes calldata _message\n    ) internal override {\n        uint256 quote = _quoteDispatch(_metadata, _message);\n        IPostDispatchHook(_partition(_message)).postDispatch{value: quote}(\n            _metadata,\n            _message\n        );\n        return _refund(_metadata, _message, msg.value - quote);\n    }\n\n    function _quoteDispatch(\n        bytes calldata _metadata,\n        bytes calldata _message\n    ) internal view override returns (uint256) {\n        return\n            IPostDispatchHook(_partition(_message)).quoteDispatch(\n                _metadata,\n                _message\n            );\n    }\n}\n"},"contracts/hooks/routing/DestinationRecipientRoutingHook.sol":{"content":"// SPDX-License-Identifier: MIT OR Apache-2.0\npragma solidity >=0.8.0;\n\n/*@@@@@@@       @@@@@@@@@\n @@@@@@@@@       @@@@@@@@@\n  @@@@@@@@@       @@@@@@@@@\n   @@@@@@@@@       @@@@@@@@@\n    @@@@@@@@@@@@@@@@@@@@@@@@@\n     @@@@@  HYPERLANE  @@@@@@@\n    @@@@@@@@@@@@@@@@@@@@@@@@@\n   @@@@@@@@@       @@@@@@@@@\n  @@@@@@@@@       @@@@@@@@@\n @@@@@@@@@       @@@@@@@@@\n@@@@@@@@@       @@@@@@@@*/\n\nimport {Message} from \"../../libs/Message.sol\";\nimport {IPostDispatchHook} from \"../../interfaces/hooks/IPostDispatchHook.sol\";\nimport {DomainRoutingHook} from \"./DomainRoutingHook.sol\";\n\ncontract DestinationRecipientRoutingHook is DomainRoutingHook {\n    using Message for bytes;\n\n    /// @notice destination => recipient => custom hook\n    mapping(uint32 destinationDomain => mapping(bytes32 recipient => address hook))\n        public customHooks;\n\n    constructor(\n        address mailbox,\n        address owner\n    ) DomainRoutingHook(mailbox, owner) {}\n\n    function _postDispatch(\n        bytes calldata metadata,\n        bytes calldata message\n    ) internal override {\n        address customHookPreset = customHooks[message.destination()][\n            message.recipient()\n        ];\n        if (customHookPreset != address(0)) {\n            IPostDispatchHook(customHookPreset).postDispatch{value: msg.value}(\n                metadata,\n                message\n            );\n        } else {\n            super._postDispatch(metadata, message);\n        }\n    }\n\n    function configCustomHook(\n        uint32 destinationDomain,\n        bytes32 recipient,\n        address hook\n    ) external onlyOwner {\n        customHooks[destinationDomain][recipient] = hook;\n    }\n}\n"},"contracts/hooks/routing/DomainRoutingHook.sol":{"content":"// SPDX-License-Identifier: MIT\npragma solidity >=0.8.0;\n\n/*@@@@@@@       @@@@@@@@@\n @@@@@@@@@       @@@@@@@@@\n  @@@@@@@@@       @@@@@@@@@\n   @@@@@@@@@       @@@@@@@@@\n    @@@@@@@@@@@@@@@@@@@@@@@@@\n     @@@@@  HYPERLANE  @@@@@@@\n    @@@@@@@@@@@@@@@@@@@@@@@@@\n   @@@@@@@@@       @@@@@@@@@\n  @@@@@@@@@       @@@@@@@@@\n @@@@@@@@@       @@@@@@@@@\n@@@@@@@@@       @@@@@@@@*/\n\n// ============ Internal Imports ============\nimport {AbstractPostDispatchHook} from \"../libs/AbstractPostDispatchHook.sol\";\nimport {MailboxClient} from \"../../client/MailboxClient.sol\";\nimport {Message} from \"../../libs/Message.sol\";\nimport {IPostDispatchHook} from \"../../interfaces/hooks/IPostDispatchHook.sol\";\n\n// ============ External Imports ============\nimport {Strings} from \"@openzeppelin/contracts/utils/Strings.sol\";\n\n/**\n * @title DomainRoutingHook\n * @notice Delegates to a hook based on the destination domain of the message.\n */\ncontract DomainRoutingHook is AbstractPostDispatchHook, MailboxClient {\n    using Strings for uint32;\n    using Message for bytes;\n\n    struct HookConfig {\n        uint32 destination;\n        address hook;\n    }\n\n    mapping(uint32 destinationDomain => IPostDispatchHook hook) public hooks;\n\n    constructor(address _mailbox, address _owner) MailboxClient(_mailbox) {\n        _transferOwnership(_owner);\n    }\n\n    // ============ External Functions ============\n\n    /// @inheritdoc IPostDispatchHook\n    function hookType() external pure virtual override returns (uint8) {\n        return uint8(IPostDispatchHook.Types.ROUTING);\n    }\n\n    function setHook(uint32 _destination, address _hook) public onlyOwner {\n        hooks[_destination] = IPostDispatchHook(_hook);\n    }\n\n    function setHooks(HookConfig[] calldata configs) external onlyOwner {\n        for (uint256 i = 0; i < configs.length; i++) {\n            setHook(configs[i].destination, configs[i].hook);\n        }\n    }\n\n    function supportsMetadata(\n        bytes calldata\n    ) public pure virtual override returns (bool) {\n        // routing hook does not care about metadata shape\n        return true;\n    }\n\n    // ============ Internal Functions ============\n\n    /// @inheritdoc AbstractPostDispatchHook\n    function _postDispatch(\n        bytes calldata metadata,\n        bytes calldata message\n    ) internal virtual override {\n        _getConfiguredHook(message).postDispatch{value: msg.value}(\n            metadata,\n            message\n        );\n    }\n\n    /// @inheritdoc AbstractPostDispatchHook\n    function _quoteDispatch(\n        bytes calldata metadata,\n        bytes calldata message\n    ) internal view virtual override returns (uint256) {\n        return _getConfiguredHook(message).quoteDispatch(metadata, message);\n    }\n\n    function _getConfiguredHook(\n        bytes calldata message\n    ) internal view virtual returns (IPostDispatchHook hook) {\n        hook = hooks[message.destination()];\n        if (address(hook) == address(0)) {\n            revert(\n                string.concat(\n                    \"No hook configured for destination: \",\n                    message.destination().toString()\n                )\n            );\n        }\n    }\n}\n"},"contracts/hooks/routing/FallbackDomainRoutingHook.sol":{"content":"// SPDX-License-Identifier: MIT OR Apache-2.0\npragma solidity >=0.8.0;\n\n/*@@@@@@@       @@@@@@@@@\n @@@@@@@@@       @@@@@@@@@\n  @@@@@@@@@       @@@@@@@@@\n   @@@@@@@@@       @@@@@@@@@\n    @@@@@@@@@@@@@@@@@@@@@@@@@\n     @@@@@  HYPERLANE  @@@@@@@\n    @@@@@@@@@@@@@@@@@@@@@@@@@\n   @@@@@@@@@       @@@@@@@@@\n  @@@@@@@@@       @@@@@@@@@\n @@@@@@@@@       @@@@@@@@@\n@@@@@@@@@       @@@@@@@@*/\n\nimport {IPostDispatchHook} from \"../../interfaces/hooks/IPostDispatchHook.sol\";\nimport {DomainRoutingHook} from \"./DomainRoutingHook.sol\";\nimport {Message} from \"../../libs/Message.sol\";\n\n/**\n * @title FallbackDomainRoutingHook\n * @notice Delegates to a hook based on the destination domain of the message.\n * If no hook is configured for the destination domain, delegates to a fallback hook.\n */\ncontract FallbackDomainRoutingHook is DomainRoutingHook {\n    using Message for bytes;\n\n    IPostDispatchHook public immutable fallbackHook;\n\n    constructor(\n        address _mailbox,\n        address _owner,\n        address _fallback\n    ) DomainRoutingHook(_mailbox, _owner) {\n        fallbackHook = IPostDispatchHook(_fallback);\n    }\n\n    // ============ External Functions ============\n\n    /// @inheritdoc IPostDispatchHook\n    function hookType() external pure override returns (uint8) {\n        return uint8(IPostDispatchHook.Types.FALLBACK_ROUTING);\n    }\n\n    // ============ Internal Functions ============\n\n    function _getConfiguredHook(\n        bytes calldata message\n    ) internal view override returns (IPostDispatchHook) {\n        IPostDispatchHook _hook = hooks[message.destination()];\n        if (address(_hook) == address(0)) {\n            _hook = fallbackHook;\n        }\n        return _hook;\n    }\n}\n"},"contracts/hooks/warp-route/RateLimitedHook.sol":{"content":"// SPDX-License-Identifier: MIT OR Apache-2.0\npragma solidity >=0.8.0;\n\n/*@@@@@@@       @@@@@@@@@\n @@@@@@@@@       @@@@@@@@@\n  @@@@@@@@@       @@@@@@@@@\n   @@@@@@@@@       @@@@@@@@@\n    @@@@@@@@@@@@@@@@@@@@@@@@@\n     @@@@@  HYPERLANE  @@@@@@@\n    @@@@@@@@@@@@@@@@@@@@@@@@@\n   @@@@@@@@@       @@@@@@@@@\n  @@@@@@@@@       @@@@@@@@@\n @@@@@@@@@       @@@@@@@@@\n@@@@@@@@@       @@@@@@@@*/\n\n// ============ Internal Imports ============\nimport {MailboxClient} from \"../../client/MailboxClient.sol\";\nimport {IPostDispatchHook} from \"../../interfaces/hooks/IPostDispatchHook.sol\";\nimport {Message} from \"../../libs/Message.sol\";\nimport {TokenMessage} from \"../../token/libs/TokenMessage.sol\";\nimport {RateLimited} from \"../../libs/RateLimited.sol\";\nimport {AbstractPostDispatchHook} from \"../../hooks/libs/AbstractPostDispatchHook.sol\";\n\n/*\n * @title RateLimitedHook\n * @author Abacus Works\n * @notice A hook that rate limits the volume of token transfers to a destination using a bucket fill algorithm\n */\ncontract RateLimitedHook is\n    AbstractPostDispatchHook,\n    MailboxClient,\n    RateLimited\n{\n    using Message for bytes;\n    using TokenMessage for bytes;\n\n    /// @notice The address that is authorized to call this hook\n    address public immutable sender;\n    /// @notice A mapping of message IDs to whether they have been validated\n    mapping(bytes32 messageId => bool validated) public messageValidated;\n\n    // ============ Modifiers ============\n\n    /// @notice Ensures that the message has not been validated yet\n    modifier validateMessageOnce(bytes calldata _message) {\n        bytes32 messageId = _message.id();\n        require(!messageValidated[messageId], \"MessageAlreadyValidated\");\n        _;\n        messageValidated[messageId] = true;\n    }\n\n    /// @notice Ensures that the message was sent by the authorized sender\n    modifier onlySender(bytes calldata _message) {\n        require(_message.senderAddress() == sender, \"InvalidSender\");\n        _;\n    }\n\n    // ============ Constructor ============\n\n    constructor(\n        address _mailbox,\n        uint256 _maxCapacity,\n        address _sender\n    ) MailboxClient(_mailbox) RateLimited(_maxCapacity) {\n        require(_sender != address(0), \"InvalidSender\");\n        sender = _sender;\n    }\n\n    // ============ External Functions ============\n\n    /// @inheritdoc IPostDispatchHook\n    function hookType() external pure returns (uint8) {\n        return uint8(IPostDispatchHook.Types.RATE_LIMITED);\n    }\n\n    // ============ Internal Functions ============\n\n    /// @inheritdoc AbstractPostDispatchHook\n    function _postDispatch(\n        bytes calldata,\n        bytes calldata _message\n    ) internal override onlySender(_message) validateMessageOnce(_message) {\n        require(_isLatestDispatched(_message.id()), \"InvalidDispatchedMessage\");\n\n        uint256 newAmount = _message.body().amount();\n        _validateAndConsumeFilledLevel(newAmount);\n    }\n\n    /// @inheritdoc AbstractPostDispatchHook\n    function _quoteDispatch(\n        bytes calldata,\n        bytes calldata\n    ) internal pure override returns (uint256) {\n        return 0;\n    }\n}\n"},"contracts/interfaces/avs/IRemoteChallenger.sol":{"content":"// SPDX-License-Identifier: MIT OR Apache-2.0\npragma solidity >=0.8.0;\n\n/*@@@@@@@       @@@@@@@@@\n @@@@@@@@@       @@@@@@@@@\n  @@@@@@@@@       @@@@@@@@@\n   @@@@@@@@@       @@@@@@@@@\n    @@@@@@@@@@@@@@@@@@@@@@@@@\n     @@@@@  HYPERLANE  @@@@@@@\n    @@@@@@@@@@@@@@@@@@@@@@@@@\n   @@@@@@@@@       @@@@@@@@@\n  @@@@@@@@@       @@@@@@@@@\n @@@@@@@@@       @@@@@@@@@\n@@@@@@@@@       @@@@@@@@*/\n\ninterface IRemoteChallenger {\n    /// @notice Returns the number of blocks that must be mined before a challenge can be handled\n    /// @return The number of blocks that must be mined before a challenge can be handled\n    function challengeDelayBlocks() external view returns (uint256);\n\n    /// @notice Handles a challenge for an operator\n    /// @param operator The address of the operator\n    function handleChallenge(address operator) external;\n}\n"},"contracts/interfaces/avs/vendored/IAVSDirectory.sol":{"content":"// SPDX-License-Identifier: BUSL-1.1\npragma solidity >=0.8.0;\n\nimport \"./ISignatureUtils.sol\";\n\n/// part of mock interfaces for vendoring necessary Eigenlayer contracts for the hyperlane AVS\n/// @author Layr Labs, Inc.\ninterface IAVSDirectory is ISignatureUtils {\n    enum OperatorAVSRegistrationStatus {\n        UNREGISTERED,\n        REGISTERED\n    }\n\n    event AVSMetadataURIUpdated(address indexed avs, string metadataURI);\n\n    function registerOperatorToAVS(\n        address operator,\n        ISignatureUtils.SignatureWithSaltAndExpiry memory operatorSignature\n    ) external;\n\n    function deregisterOperatorFromAVS(address operator) external;\n\n    function updateAVSMetadataURI(string calldata metadataURI) external;\n}\n"},"contracts/interfaces/avs/vendored/IDelegationManager.sol":{"content":"// SPDX-License-Identifier: BUSL-1.1\npragma solidity >=0.8.0;\n\nimport {IStrategy} from \"./IStrategy.sol\";\n\n/**\n * @title DelegationManager\n * @author Layr Labs, Inc.\n * @notice Terms of Service: https://docs.eigenlayer.xyz/overview/terms-of-service\n * @notice  This is the contract for delegation in EigenLayer. The main functionalities of this contract are\n * - enabling anyone to register as an operator in EigenLayer\n * - allowing operators to specify parameters related to stakers who delegate to them\n * - enabling any staker to delegate its stake to the operator of its choice (a given staker can only delegate to a single operator at a time)\n * - enabling a staker to undelegate its assets from the operator it is delegated to (performed as part of the withdrawal process, initiated through the StrategyManager)\n */\ninterface IDelegationManager {\n    struct OperatorDetails {\n        address earningsReceiver;\n        address delegationApprover;\n        uint32 stakerOptOutWindowBlocks;\n    }\n\n    event OperatorMetadataURIUpdated(\n        address indexed operator,\n        string metadataURI\n    );\n\n    function registerAsOperator(\n        OperatorDetails calldata registeringOperatorDetails,\n        string calldata metadataURI\n    ) external;\n\n    function getOperatorShares(\n        address operator,\n        IStrategy[] memory strategies\n    ) external view returns (uint256[] memory);\n}\n"},"contracts/interfaces/avs/vendored/IECDSAStakeRegistryEventsAndErrors.sol":{"content":"// SPDX-License-Identifier: MIT\npragma solidity ^0.8.12;\n\nimport {IStrategy} from \"./IStrategy.sol\";\n\nstruct StrategyParams {\n    IStrategy strategy; // The strategy contract reference\n    uint96 multiplier; // The multiplier applied to the strategy\n}\n\nstruct Quorum {\n    StrategyParams[] strategies; // An array of strategy parameters to define the quorum\n}\n\ninterface IECDSAStakeRegistryEventsAndErrors {\n    /// @notice Emitted when the system registers an operator\n    /// @param _operator The address of the registered operator\n    /// @param _avs The address of the associated AVS\n    event OperatorRegistered(address indexed _operator, address indexed _avs);\n\n    /// @notice Emitted when the system deregisters an operator\n    /// @param _operator The address of the deregistered operator\n    /// @param _avs The address of the associated AVS\n    event OperatorDeregistered(address indexed _operator, address indexed _avs);\n\n    /// @notice Emitted when the system updates the quorum\n    /// @param _old The previous quorum configuration\n    /// @param _new The new quorum configuration\n    event QuorumUpdated(Quorum _old, Quorum _new);\n\n    /// @notice Emitted when the weight to join the operator set updates\n    /// @param _old The previous minimum weight\n    /// @param _new The new minimumWeight\n    event MinimumWeightUpdated(uint256 _old, uint256 _new);\n\n    /// @notice Emitted when the weight required to be an operator changes\n    /// @param oldMinimumWeight The previous weight\n    /// @param newMinimumWeight The updated weight\n    event UpdateMinimumWeight(\n        uint256 oldMinimumWeight,\n        uint256 newMinimumWeight\n    );\n\n    /// @notice Emitted when the system updates an operator's weight\n    /// @param _operator The address of the operator updated\n    /// @param oldWeight The operator's weight before the update\n    /// @param newWeight The operator's weight after the update\n    event OperatorWeightUpdated(\n        address indexed _operator,\n        uint256 oldWeight,\n        uint256 newWeight\n    );\n\n    /// @notice Emitted when the system updates the total weight\n    /// @param oldTotalWeight The total weight before the update\n    /// @param newTotalWeight The total weight after the update\n    event TotalWeightUpdated(uint256 oldTotalWeight, uint256 newTotalWeight);\n\n    /// @notice Emits when setting a new threshold weight.\n    event ThresholdWeightUpdated(uint256 _thresholdWeight);\n\n    /// @notice Emitted when an operator's signing key is updated\n    /// @param operator The address of the operator whose signing key was updated\n    /// @param updateBlock The block number at which the signing key was updated\n    /// @param newSigningKey The operator's signing key after the update\n    /// @param oldSigningKey The operator's signing key before the update\n    event SigningKeyUpdate(\n        address indexed operator,\n        uint256 indexed updateBlock,\n        address indexed newSigningKey,\n        address oldSigningKey\n    );\n    /// @notice Indicates when the lengths of the signers array and signatures array do not match.\n\n    error LengthMismatch();\n\n    /// @notice Indicates encountering an invalid length for the signers or signatures array.\n    error InvalidLength();\n\n    /// @notice Indicates encountering an invalid signature.\n    error InvalidSignature();\n\n    /// @notice Thrown when the threshold update is greater than BPS\n    error InvalidThreshold();\n\n    /// @notice Thrown when missing operators in an update\n    error MustUpdateAllOperators();\n\n    /// @notice Reference blocks must be for blocks that have already been confirmed\n    error InvalidReferenceBlock();\n\n    /// @notice Indicates operator weights were out of sync and the signed weight exceed the total\n    error InvalidSignedWeight();\n\n    /// @notice Indicates the total signed stake fails to meet the required threshold.\n    error InsufficientSignedStake();\n\n    /// @notice Indicates an individual signer's weight fails to meet the required threshold.\n    error InsufficientWeight();\n\n    /// @notice Indicates the quorum is invalid\n    error InvalidQuorum();\n\n    /// @notice Indicates the system finds a list of items unsorted\n    error NotSorted();\n\n    /// @notice Thrown when registering an already registered operator\n    error OperatorAlreadyRegistered();\n\n    /// @notice Thrown when de-registering or updating the stake for an unregistered operator\n    error OperatorNotRegistered();\n}\n"},"contracts/interfaces/avs/vendored/IPaymentCoordinator.sol":{"content":"// SPDX-License-Identifier: BUSL-1.1\npragma solidity >=0.8.0;\n\nimport {IERC20} from \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"./IStrategy.sol\";\n\n/**\n * @title Interface for the `IPaymentCoordinator` contract.\n * @author Layr Labs, Inc.\n * @notice Terms of Service: https://docs.eigenlayer.xyz/overview/terms-of-service\n * @notice Allows AVSs to make \"Range Payments\", which get distributed amongst the AVSs' confirmed\n * Operators and the Stakers delegated to those Operators.\n * Calculations are performed based on the completed Range Payments, with the results posted in\n * a Merkle root against which Stakers & Operators can make claims.\n */\ninterface IPaymentCoordinator {\n    /// STRUCTS ///\n    struct StrategyAndMultiplier {\n        IStrategy strategy;\n        // weight used to compare shares in multiple strategies against one another\n        uint96 multiplier;\n    }\n\n    struct RangePayment {\n        // Strategies & relative weights of shares in the strategies\n        StrategyAndMultiplier[] strategiesAndMultipliers;\n        IERC20 token;\n        uint256 amount;\n        uint64 startTimestamp;\n        uint64 duration;\n    }\n\n    /// EXTERNAL FUNCTIONS ///\n\n    /**\n     * @notice Creates a new range payment on behalf of an AVS, to be split amongst the\n     * set of stakers delegated to operators who are registered to the `avs`\n     * @param rangePayments The range payments being created\n     * @dev Expected to be called by the ServiceManager of the AVS on behalf of which the payment is being made\n     * @dev The duration of the `rangePayment` cannot exceed `MAX_PAYMENT_DURATION`\n     * @dev The tokens are sent to the `claimingManager` contract\n     * @dev This function will revert if the `rangePayment` is malformed,\n     * e.g. if the `strategies` and `weights` arrays are of non-equal lengths\n     */\n    function payForRange(RangePayment[] calldata rangePayments) external;\n}\n"},"contracts/interfaces/avs/vendored/IServiceManager.sol":{"content":"// SPDX-License-Identifier: BUSL-1.1\npragma solidity >=0.8.0;\n\nimport {IPaymentCoordinator} from \"./IPaymentCoordinator.sol\";\nimport {IServiceManagerUI} from \"./IServiceManagerUI.sol\";\n\n/**\n * @title Minimal interface for a ServiceManager-type contract that forms the single point for an AVS to push updates to EigenLayer\n * @author Layr Labs, Inc.\n */\ninterface IServiceManager is IServiceManagerUI {\n    /**\n     * @notice Creates a new range payment on behalf of an AVS, to be split amongst the\n     * set of stakers delegated to operators who are registered to the `avs`.\n     * Note that the owner calling this function must have approved the tokens to be transferred to the ServiceManager\n     * and of course has the required balances.\n     * @param rangePayments The range payments being created\n     * @dev Expected to be called by the ServiceManager of the AVS on behalf of which the payment is being made\n     * @dev The duration of the `rangePayment` cannot exceed `paymentCoordinator.MAX_PAYMENT_DURATION()`\n     * @dev The tokens are sent to the `PaymentCoordinator` contract\n     * @dev Strategies must be in ascending order of addresses to check for duplicates\n     * @dev This function will revert if the `rangePayment` is malformed,\n     * e.g. if the `strategies` and `weights` arrays are of non-equal lengths\n     */\n    function payForRange(\n        IPaymentCoordinator.RangePayment[] calldata rangePayments\n    ) external;\n}\n"},"contracts/interfaces/avs/vendored/IServiceManagerUI.sol":{"content":"// SPDX-License-Identifier: BUSL-1.1\npragma solidity >=0.8.0;\n\nimport {ISignatureUtils} from \"./ISignatureUtils.sol\";\nimport {IDelegationManager} from \"./IDelegationManager.sol\";\n\n/**\n * @title Minimal interface for a ServiceManager-type contract that AVS ServiceManager contracts must implement\n * for eigenlabs to be able to index their data on the AVS marketplace frontend.\n * @author Layr Labs, Inc.\n */\ninterface IServiceManagerUI {\n    /**\n     * Metadata should follow the format outlined by this example.\n     *     {\n     *         \"name\": \"EigenLabs AVS 1\",\n     *         \"website\": \"https://www.eigenlayer.xyz/\",\n     *         \"description\": \"This is my 1st AVS\",\n     *         \"logo\": \"https://holesky-operator-metadata.s3.amazonaws.com/eigenlayer.png\",\n     *         \"twitter\": \"https://twitter.com/eigenlayer\"\n     *     }\n     * @notice Updates the metadata URI for the AVS\n     * @param _metadataURI is the metadata URI for the AVS\n     */\n    function updateAVSMetadataURI(string memory _metadataURI) external;\n\n    /**\n     * @notice Forwards a call to EigenLayer's DelegationManager contract to confirm operator registration with the AVS\n     * @param operator The address of the operator to register.\n     * @param operatorSignature The signature, salt, and expiry of the operator's signature.\n     */\n    function registerOperatorToAVS(\n        address operator,\n        ISignatureUtils.SignatureWithSaltAndExpiry memory operatorSignature\n    ) external;\n\n    /**\n     * @notice Forwards a call to EigenLayer's DelegationManager contract to confirm operator deregistration from the AVS\n     * @param operator The address of the operator to deregister.\n     */\n    function deregisterOperatorFromAVS(address operator) external;\n\n    /**\n     * @notice Returns the list of strategies that the operator has potentially restaked on the AVS\n     * @param operator The address of the operator to get restaked strategies for\n     * @dev This function is intended to be called off-chain\n     * @dev No guarantee is made on whether the operator has shares for a strategy in a quorum or uniqueness\n     *      of each element in the returned array. The off-chain service should do that validation separately\n     */\n    function getOperatorRestakedStrategies(\n        address operator\n    ) external view returns (address[] memory);\n\n    /**\n     * @notice Returns the list of strategies that the AVS supports for restaking\n     * @dev This function is intended to be called off-chain\n     * @dev No guarantee is made on uniqueness of each element in the returned array.\n     *      The off-chain service should do that validation separately\n     */\n    function getRestakeableStrategies()\n        external\n        view\n        returns (address[] memory);\n\n    /// @notice Returns the EigenLayer AVSDirectory contract.\n    function avsDirectory() external view returns (address);\n}\n"},"contracts/interfaces/avs/vendored/ISignatureUtils.sol":{"content":"// SPDX-License-Identifier: BUSL-1.1\npragma solidity >=0.5.0;\n\n/**\n * @title The interface for common signature utilities.\n * @author Layr Labs, Inc.\n * @notice Terms of Service: https://docs.eigenlayer.xyz/overview/terms-of-service\n */\ninterface ISignatureUtils {\n    // @notice Struct that bundles together a signature and an expiration time for the signature. Used primarily for stack management.\n    struct SignatureWithExpiry {\n        // the signature itself, formatted as a single bytes object\n        bytes signature;\n        // the expiration timestamp (UTC) of the signature\n        uint256 expiry;\n    }\n\n    // @notice Struct that bundles together a signature, a salt for uniqueness, and an expiration time for the signature. Used primarily for stack management.\n    struct SignatureWithSaltAndExpiry {\n        // the signature itself, formatted as a single bytes object\n        bytes signature;\n        // the salt used to generate the signature\n        bytes32 salt;\n        // the expiration timestamp (UTC) of the signature\n        uint256 expiry;\n    }\n}\n"},"contracts/interfaces/avs/vendored/ISlasher.sol":{"content":"// SPDX-License-Identifier: BUSL-1.1\npragma solidity >=0.5.0;\n\n/**\n * @title Interface for the primary 'slashing' contract for EigenLayer.\n * @author Layr Labs, Inc.\n * @notice Terms of Service: https://docs.eigenlayer.xyz/overview/terms-of-service\n */\ninterface ISlasher {\n    function freezeOperator(address toBeFrozen) external;\n}\n"},"contracts/interfaces/avs/vendored/IStrategy.sol":{"content":"// SPDX-License-Identifier: BUSL-1.1\npragma solidity >=0.5.0;\n\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\n\n/**\n * @title Minimal interface for an `Strategy` contract.\n * @author Layr Labs, Inc.\n * @notice Terms of Service: https://docs.eigenlayer.xyz/overview/terms-of-service\n * @notice Custom `Strategy` implementations may expand extensively on this interface.\n */\ninterface IStrategy {\n    /**\n     * @notice Used to deposit tokens into this Strategy\n     * @param token is the ERC20 token being deposited\n     * @param amount is the amount of token being deposited\n     * @dev This function is only callable by the strategyManager contract. It is invoked inside of the strategyManager's\n     * `depositIntoStrategy` function, and individual share balances are recorded in the strategyManager as well.\n     * @return newShares is the number of new shares issued at the current exchange ratio.\n     */\n    function deposit(IERC20 token, uint256 amount) external returns (uint256);\n\n    /**\n     * @notice Used to withdraw tokens from this Strategy, to the `recipient`'s address\n     * @param recipient is the address to receive the withdrawn funds\n     * @param token is the ERC20 token being transferred out\n     * @param amountShares is the amount of shares being withdrawn\n     * @dev This function is only callable by the strategyManager contract. It is invoked inside of the strategyManager's\n     * other functions, and individual share balances are recorded in the strategyManager as well.\n     */\n    function withdraw(\n        address recipient,\n        IERC20 token,\n        uint256 amountShares\n    ) external;\n\n    /**\n     * @notice Used to convert a number of shares to the equivalent amount of underlying tokens for this strategy.\n     * @notice In contrast to `sharesToUnderlyingView`, this function **may** make state modifications\n     * @param amountShares is the amount of shares to calculate its conversion into the underlying token\n     * @return The amount of underlying tokens corresponding to the input `amountShares`\n     * @dev Implementation for these functions in particular may vary significantly for different strategies\n     */\n    function sharesToUnderlying(\n        uint256 amountShares\n    ) external returns (uint256);\n\n    /**\n     * @notice Used to convert an amount of underlying tokens to the equivalent amount of shares in this strategy.\n     * @notice In contrast to `underlyingToSharesView`, this function **may** make state modifications\n     * @param amountUnderlying is the amount of `underlyingToken` to calculate its conversion into strategy shares\n     * @return The amount of underlying tokens corresponding to the input `amountShares`\n     * @dev Implementation for these functions in particular may vary significantly for different strategies\n     */\n    function underlyingToShares(\n        uint256 amountUnderlying\n    ) external returns (uint256);\n\n    /**\n     * @notice convenience function for fetching the current underlying value of all of the `user`'s shares in\n     * this strategy. In contrast to `userUnderlyingView`, this function **may** make state modifications\n     */\n    function userUnderlying(address user) external returns (uint256);\n\n    /**\n     * @notice convenience function for fetching the current total shares of `user` in this strategy, by\n     * querying the `strategyManager` contract\n     */\n    function shares(address user) external view returns (uint256);\n\n    /**\n     * @notice Used to convert a number of shares to the equivalent amount of underlying tokens for this strategy.\n     * @notice In contrast to `sharesToUnderlying`, this function guarantees no state modifications\n     * @param amountShares is the amount of shares to calculate its conversion into the underlying token\n     * @return The amount of shares corresponding to the input `amountUnderlying`\n     * @dev Implementation for these functions in particular may vary significantly for different strategies\n     */\n    function sharesToUnderlyingView(\n        uint256 amountShares\n    ) external view returns (uint256);\n\n    /**\n     * @notice Used to convert an amount of underlying tokens to the equivalent amount of shares in this strategy.\n     * @notice In contrast to `underlyingToShares`, this function guarantees no state modifications\n     * @param amountUnderlying is the amount of `underlyingToken` to calculate its conversion into strategy shares\n     * @return The amount of shares corresponding to the input `amountUnderlying`\n     * @dev Implementation for these functions in particular may vary significantly for different strategies\n     */\n    function underlyingToSharesView(\n        uint256 amountUnderlying\n    ) external view returns (uint256);\n\n    /**\n     * @notice convenience function for fetching the current underlying value of all of the `user`'s shares in\n     * this strategy. In contrast to `userUnderlying`, this function guarantees no state modifications\n     */\n    function userUnderlyingView(address user) external view returns (uint256);\n\n    /// @notice The underlying token for shares in this Strategy\n    function underlyingToken() external view returns (IERC20);\n\n    /// @notice The total number of extant shares in this Strategy\n    function totalShares() external view returns (uint256);\n\n    /// @notice Returns either a brief string explaining the strategy's goal & purpose, or a link to metadata that explains in more detail.\n    function explanation() external view returns (string memory);\n}\n"},"contracts/interfaces/cctp/IMessageTransmitter.sol":{"content":"/*\n * Copyright (c) 2022, Circle Internet Financial Limited.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npragma solidity >=0.8.0;\n\n// @dev copied from https://github.com/circlefin/evm-cctp-contracts\ninterface IRelayer {\n    function sendMessage(\n        uint32 destinationDomain,\n        bytes32 recipient,\n        bytes calldata messageBody\n    ) external returns (uint64);\n\n    function sendMessageWithCaller(\n        uint32 destinationDomain,\n        bytes32 recipient,\n        bytes32 destinationCaller,\n        bytes calldata messageBody\n    ) external returns (uint64);\n\n    function replaceMessage(\n        bytes calldata originalMessage,\n        bytes calldata originalAttestation,\n        bytes calldata newMessageBody,\n        bytes32 newDestinationCaller\n    ) external;\n}\n\ninterface IReceiver {\n    function receiveMessage(\n        bytes calldata message,\n        bytes calldata signature\n    ) external returns (bool success);\n}\n\ninterface IMessageTransmitter is IRelayer, IReceiver {\n    event MessageSent(bytes message);\n\n    function usedNonces(\n        bytes32 sourceAndNonceHash\n    ) external view returns (uint256);\n\n    function version() external view returns (uint32);\n\n    function localDomain() external view returns (uint32);\n}\n"},"contracts/interfaces/cctp/ITokenMessenger.sol":{"content":"// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\ninterface ITokenMessenger {\n    event DepositForBurn(\n        uint64 indexed nonce,\n        address indexed burnToken,\n        uint256 amount,\n        address indexed depositor,\n        bytes32 mintRecipient,\n        uint32 destinationDomain,\n        bytes32 destinationTokenMessenger,\n        bytes32 destinationCaller\n    );\n\n    function depositForBurn(\n        uint256 amount,\n        uint32 destinationDomain,\n        bytes32 mintRecipient,\n        address burnToken\n    ) external returns (uint64 _nonce);\n\n    function messageBodyVersion() external returns (uint32);\n}\n"},"contracts/interfaces/cctp/ITokenMessengerV2.sol":{"content":"// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\ninterface ITokenMessengerV2 {\n    event DepositForBurn(\n        address indexed burnToken,\n        uint256 amount,\n        address indexed depositor,\n        bytes32 mintRecipient,\n        uint32 destinationDomain,\n        bytes32 destinationTokenMessenger,\n        bytes32 destinationCaller,\n        uint256 maxFee,\n        uint32 indexed minFinalityThreshold,\n        bytes hookData\n    );\n\n    function depositForBurn(\n        uint256 amount,\n        uint32 destinationDomain,\n        bytes32 mintRecipient,\n        address burnToken,\n        bytes32 destinationCaller,\n        uint256 maxFee,\n        uint32 minFinalityThreshold\n    ) external;\n\n    function messageBodyVersion() external returns (uint32);\n}\n"},"contracts/interfaces/hooks/IMessageDispatcher.sol":{"content":"// SPDX-License-Identifier: MIT OR Apache-2.0\npragma solidity >=0.8.0;\n\n/**\n * @title ERC-5164: Cross-Chain Execution Standard\n * @dev See https://eips.ethereum.org/EIPS/eip-5164\n */\ninterface IMessageDispatcher {\n    /**\n     * @notice Emitted when a message has successfully been dispatched to the executor chain.\n     * @param messageId ID uniquely identifying the message\n     * @param from Address that dispatched the message\n     * @param toChainId ID of the chain receiving the message\n     * @param to Address that will receive the message\n     * @param data Data that was dispatched\n     */\n    event MessageDispatched(\n        bytes32 indexed messageId,\n        address indexed from,\n        uint256 indexed toChainId,\n        address to,\n        bytes data\n    );\n\n    function dispatchMessage(\n        uint256 toChainId,\n        address to,\n        bytes calldata data\n    ) external returns (bytes32);\n}\n"},"contracts/interfaces/hooks/IPostDispatchHook.sol":{"content":"// SPDX-License-Identifier: MIT OR Apache-2.0\npragma solidity >=0.8.0;\n\n/*@@@@@@@       @@@@@@@@@\n @@@@@@@@@       @@@@@@@@@\n  @@@@@@@@@       @@@@@@@@@\n   @@@@@@@@@       @@@@@@@@@\n    @@@@@@@@@@@@@@@@@@@@@@@@@\n     @@@@@  HYPERLANE  @@@@@@@\n    @@@@@@@@@@@@@@@@@@@@@@@@@\n   @@@@@@@@@       @@@@@@@@@\n  @@@@@@@@@       @@@@@@@@@\n @@@@@@@@@       @@@@@@@@@\n@@@@@@@@@       @@@@@@@@*/\n\ninterface IPostDispatchHook {\n    enum Types {\n        UNUSED,\n        ROUTING,\n        AGGREGATION,\n        MERKLE_TREE,\n        INTERCHAIN_GAS_PAYMASTER,\n        FALLBACK_ROUTING,\n        ID_AUTH_ISM,\n        PAUSABLE,\n        PROTOCOL_FEE,\n        DEPRECATED,\n        RATE_LIMITED,\n        ARB_L2_TO_L1,\n        OP_L2_TO_L1,\n        MAILBOX_DEFAULT_HOOK,\n        AMOUNT_ROUTING,\n        CCTP\n    }\n\n    /**\n     * @notice Returns an enum that represents the type of hook\n     */\n    function hookType() external view returns (uint8);\n\n    /**\n     * @notice Returns whether the hook supports metadata\n     * @param metadata metadata\n     * @return Whether the hook supports metadata\n     */\n    function supportsMetadata(\n        bytes calldata metadata\n    ) external view returns (bool);\n\n    /**\n     * @notice Post action after a message is dispatched via the Mailbox\n     * @param metadata The metadata required for the hook\n     * @param message The message passed from the Mailbox.dispatch() call\n     */\n    function postDispatch(\n        bytes calldata metadata,\n        bytes calldata message\n    ) external payable;\n\n    /**\n     * @notice Compute the payment required by the postDispatch call\n     * @param metadata The metadata required for the hook\n     * @param message The message passed from the Mailbox.dispatch() call\n     * @return Quoted payment for the postDispatch call\n     */\n    function quoteDispatch(\n        bytes calldata metadata,\n        bytes calldata message\n    ) external view returns (uint256);\n}\n"},"contracts/interfaces/IGasOracle.sol":{"content":"// SPDX-License-Identifier: MIT OR Apache-2.0\npragma solidity >=0.8.0;\n\ninterface IGasOracle {\n    struct RemoteGasData {\n        // The exchange rate of the remote native token quoted in the local native token.\n        // Scaled with 10 decimals, i.e. 1e10 is \"one\".\n        uint128 tokenExchangeRate;\n        uint128 gasPrice;\n    }\n\n    function getExchangeRateAndGasPrice(\n        uint32 _destinationDomain\n    ) external view returns (uint128 tokenExchangeRate, uint128 gasPrice);\n}\n"},"contracts/interfaces/IInterchainGasPaymaster.sol":{"content":"// SPDX-License-Identifier: MIT OR Apache-2.0\npragma solidity >=0.6.11;\n\n/**\n * @title IInterchainGasPaymaster\n * @notice Manages payments on a source chain to cover gas costs of relaying\n * messages to destination chains.\n */\ninterface IInterchainGasPaymaster {\n    /**\n     * @notice Emitted when a payment is made for a message's gas costs.\n     * @param messageId The ID of the message to pay for.\n     * @param destinationDomain The domain of the destination chain.\n     * @param gasAmount The amount of destination gas paid for.\n     * @param payment The amount of native tokens paid.\n     */\n    event GasPayment(\n        bytes32 indexed messageId,\n        uint32 indexed destinationDomain,\n        uint256 gasAmount,\n        uint256 payment\n    );\n\n    function payForGas(\n        bytes32 _messageId,\n        uint32 _destinationDomain,\n        uint256 _gasAmount,\n        address _refundAddress\n    ) external payable;\n\n    function quoteGasPayment(\n        uint32 _destinationDomain,\n        uint256 _gasAmount\n    ) external view returns (uint256);\n}\n"},"contracts/interfaces/IInterchainSecurityModule.sol":{"content":"// SPDX-License-Identifier: MIT OR Apache-2.0\npragma solidity >=0.6.11;\n\ninterface IInterchainSecurityModule {\n    enum Types {\n        UNUSED,\n        ROUTING,\n        AGGREGATION,\n        LEGACY_MULTISIG,\n        MERKLE_ROOT_MULTISIG,\n        MESSAGE_ID_MULTISIG,\n        NULL, // used with relayer carrying no metadata\n        CCIP_READ,\n        ARB_L2_TO_L1,\n        WEIGHTED_MERKLE_ROOT_MULTISIG,\n        WEIGHTED_MESSAGE_ID_MULTISIG,\n        OP_L2_TO_L1\n    }\n\n    /**\n     * @notice Returns an enum that represents the type of security model\n     * encoded by this ISM.\n     * @dev Relayers infer how to fetch and format metadata.\n     */\n    function moduleType() external view returns (uint8);\n\n    /**\n     * @notice Defines a security model responsible for verifying interchain\n     * messages based on the provided metadata.\n     * @param _metadata Off-chain metadata provided by a relayer, specific to\n     * the security model encoded by the module (e.g. validator signatures)\n     * @param _message Hyperlane encoded interchain message\n     * @return True if the message was verified\n     */\n    function verify(\n        bytes calldata _metadata,\n        bytes calldata _message\n    ) external returns (bool);\n}\n\ninterface ISpecifiesInterchainSecurityModule {\n    function interchainSecurityModule()\n        external\n        view\n        returns (IInterchainSecurityModule);\n}\n"},"contracts/interfaces/IMailbox.sol":{"content":"// SPDX-License-Identifier: MIT OR Apache-2.0\npragma solidity >=0.8.0;\n\nimport {IInterchainSecurityModule} from \"./IInterchainSecurityModule.sol\";\nimport {IPostDispatchHook} from \"./hooks/IPostDispatchHook.sol\";\n\ninterface IMailbox {\n    // ============ Events ============\n    /**\n     * @notice Emitted when a new message is dispatched via Hyperlane\n     * @param sender The address that dispatched the message\n     * @param destination The destination domain of the message\n     * @param recipient The message recipient address on `destination`\n     * @param message Raw bytes of message\n     */\n    event Dispatch(\n        address indexed sender,\n        uint32 indexed destination,\n        bytes32 indexed recipient,\n        bytes message\n    );\n\n    /**\n     * @notice Emitted when a new message is dispatched via Hyperlane\n     * @param messageId The unique message identifier\n     */\n    event DispatchId(bytes32 indexed messageId);\n\n    /**\n     * @notice Emitted when a Hyperlane message is processed\n     * @param messageId The unique message identifier\n     */\n    event ProcessId(bytes32 indexed messageId);\n\n    /**\n     * @notice Emitted when a Hyperlane message is delivered\n     * @param origin The origin domain of the message\n     * @param sender The message sender address on `origin`\n     * @param recipient The address that handled the message\n     */\n    event Process(\n        uint32 indexed origin,\n        bytes32 indexed sender,\n        address indexed recipient\n    );\n\n    function localDomain() external view returns (uint32);\n\n    function delivered(bytes32 messageId) external view returns (bool);\n\n    function defaultIsm() external view returns (IInterchainSecurityModule);\n\n    function defaultHook() external view returns (IPostDispatchHook);\n\n    function requiredHook() external view returns (IPostDispatchHook);\n\n    function latestDispatchedId() external view returns (bytes32);\n\n    function dispatch(\n        uint32 destinationDomain,\n        bytes32 recipientAddress,\n        bytes calldata messageBody\n    ) external payable returns (bytes32 messageId);\n\n    function quoteDispatch(\n        uint32 destinationDomain,\n        bytes32 recipientAddress,\n        bytes calldata messageBody\n    ) external view returns (uint256 fee);\n\n    function dispatch(\n        uint32 destinationDomain,\n        bytes32 recipientAddress,\n        bytes calldata body,\n        bytes calldata defaultHookMetadata\n    ) external payable returns (bytes32 messageId);\n\n    function quoteDispatch(\n        uint32 destinationDomain,\n        bytes32 recipientAddress,\n        bytes calldata messageBody,\n        bytes calldata defaultHookMetadata\n    ) external view returns (uint256 fee);\n\n    function dispatch(\n        uint32 destinationDomain,\n        bytes32 recipientAddress,\n        bytes calldata body,\n        bytes calldata customHookMetadata,\n        IPostDispatchHook customHook\n    ) external payable returns (bytes32 messageId);\n\n    function quoteDispatch(\n        uint32 destinationDomain,\n        bytes32 recipientAddress,\n        bytes calldata messageBody,\n        bytes calldata customHookMetadata,\n        IPostDispatchHook customHook\n    ) external view returns (uint256 fee);\n\n    function process(\n        bytes calldata metadata,\n        bytes calldata message\n    ) external payable;\n\n    function recipientIsm(\n        address recipient\n    ) external view returns (IInterchainSecurityModule module);\n}\n"},"contracts/interfaces/IMessageRecipient.sol":{"content":"// SPDX-License-Identifier: MIT OR Apache-2.0\npragma solidity >=0.6.11;\n\ninterface IMessageRecipient {\n    function handle(\n        uint32 _origin,\n        bytes32 _sender,\n        bytes calldata _message\n    ) external payable;\n}\n"},"contracts/interfaces/IRouter.sol":{"content":"// SPDX-License-Identifier: MIT OR Apache-2.0\npragma solidity >=0.8.0;\n\ninterface IRouter {\n    function domains() external view returns (uint32[] memory);\n\n    function routers(uint32 _domain) external view returns (bytes32);\n\n    function enrollRemoteRouter(uint32 _domain, bytes32 _router) external;\n\n    function enrollRemoteRouters(\n        uint32[] calldata _domains,\n        bytes32[] calldata _routers\n    ) external;\n}\n"},"contracts/interfaces/ISafe.sol":{"content":"// SPDX-License-Identifier: MIT OR Apache-2.0\npragma solidity >=0.8.0;\n\n// source: https://github.com/safe-global/safe-smart-account/blob/d9fdda990c3ff5279edfea03c1fd377abcb39b38/contracts/interfaces/IOwnerManager.sol\ninterface IOwnerManager {\n    /**\n     * @notice Returns the number of required confirmations for a Safe transaction aka the threshold.\n     * @return Threshold number.\n     */\n    function getThreshold() external view returns (uint256);\n}\n\ninterface ISafe is IOwnerManager {\n    /**\n     * @notice Returns the nonce of the Safe contract.\n     * @return Nonce.\n     */\n    function nonce() external view returns (uint256);\n}\n"},"contracts/interfaces/isms/IAggregationIsm.sol":{"content":"// SPDX-License-Identifier: MIT OR Apache-2.0\npragma solidity >=0.6.11;\n\nimport {IInterchainSecurityModule} from \"../IInterchainSecurityModule.sol\";\n\ninterface IAggregationIsm is IInterchainSecurityModule {\n    /**\n     * @notice Returns the set of modules responsible for verifying _message\n     * and the number of modules that must verify\n     * @dev Can change based on the content of _message\n     * @param _message Hyperlane formatted interchain message\n     * @return modules The array of ISM addresses\n     * @return threshold The number of modules needed to verify\n     */\n    function modulesAndThreshold(\n        bytes calldata _message\n    ) external view returns (address[] memory modules, uint8 threshold);\n}\n"},"contracts/interfaces/isms/ICcipReadIsm.sol":{"content":"// SPDX-License-Identifier: MIT OR Apache-2.0\npragma solidity >=0.8.0;\n\nimport {IInterchainSecurityModule} from \"../IInterchainSecurityModule.sol\";\n\ninterface ICcipReadIsm is IInterchainSecurityModule {\n    /// @dev https://eips.ethereum.org/EIPS/eip-3668\n    /// @param sender the address of the contract making the call, usually address(this)\n    /// @param urls the URLs to query for offchain data\n    /// @param callData context needed for offchain service to service request\n    /// @param callbackFunction function selector to call with offchain information\n    /// @param extraData additional passthrough information to call callbackFunction with\n    error OffchainLookup(\n        address sender,\n        string[] urls,\n        bytes callData,\n        bytes4 callbackFunction,\n        bytes extraData\n    );\n\n    /**\n     * @notice Reverts with the data needed to query information offchain\n     * and be submitted via the origin mailbox\n     * @dev See https://eips.ethereum.org/EIPS/eip-3668 for more information\n     * @param _message data that will help construct the offchain query\n     */\n    function getOffchainVerifyInfo(bytes calldata _message) external view;\n}\n"},"contracts/interfaces/isms/IMultisigIsm.sol":{"content":"// SPDX-License-Identifier: MIT OR Apache-2.0\npragma solidity >=0.6.11;\n\nimport {IInterchainSecurityModule} from \"../IInterchainSecurityModule.sol\";\n\ninterface IMultisigIsm is IInterchainSecurityModule {\n    /**\n     * @notice Returns the set of validators responsible for verifying _message\n     * and the number of signatures required\n     * @dev Can change based on the content of _message\n     * @dev Signatures provided to `verify` must be consistent with validator ordering\n     * @param _message Hyperlane formatted interchain message\n     * @return validators The array of validator addresses\n     * @return threshold The number of validator signatures needed\n     */\n    function validatorsAndThreshold(\n        bytes calldata _message\n    ) external view returns (address[] memory validators, uint8 threshold);\n}\n"},"contracts/interfaces/isms/IRoutingIsm.sol":{"content":"// SPDX-License-Identifier: MIT OR Apache-2.0\npragma solidity >=0.8.0;\n\nimport {IInterchainSecurityModule} from \"../IInterchainSecurityModule.sol\";\n\ninterface IRoutingIsm is IInterchainSecurityModule {\n    /**\n     * @notice Returns the ISM responsible for verifying _message\n     * @dev Can change based on the content of _message\n     * @param _message Formatted Hyperlane message (see Message.sol).\n     * @return module The ISM to use to verify _message\n     */\n    function route(\n        bytes calldata _message\n    ) external view returns (IInterchainSecurityModule);\n}\n"},"contracts/interfaces/isms/IWeightedMultisigIsm.sol":{"content":"// SPDX-License-Identifier: MIT OR Apache-2.0\npragma solidity >=0.6.11;\n\n/*@@@@@@@       @@@@@@@@@\n @@@@@@@@@       @@@@@@@@@\n  @@@@@@@@@       @@@@@@@@@\n   @@@@@@@@@       @@@@@@@@@\n    @@@@@@@@@@@@@@@@@@@@@@@@@\n     @@@@@  HYPERLANE  @@@@@@@\n    @@@@@@@@@@@@@@@@@@@@@@@@@\n   @@@@@@@@@       @@@@@@@@@\n  @@@@@@@@@       @@@@@@@@@\n @@@@@@@@@       @@@@@@@@@\n@@@@@@@@@       @@@@@@@@*/\n\nimport {IInterchainSecurityModule} from \"../IInterchainSecurityModule.sol\";\n\ninterface IStaticWeightedMultisigIsm is IInterchainSecurityModule {\n    // ============ Structs ============\n\n    // ValidatorInfo contains the signing address and weight of a validator\n    struct ValidatorInfo {\n        address signingAddress;\n        uint96 weight;\n    }\n\n    /**\n     * @notice Returns the validators and threshold weight for this ISM.\n     * @param _message The message to be verified\n     * @return validators The validators and their weights\n     * @return thresholdWeight The threshold weight required to pass verification\n     */\n    function validatorsAndThresholdWeight(\n        bytes calldata _message\n    )\n        external\n        view\n        returns (ValidatorInfo[] memory validators, uint96 thresholdWeight);\n}\n"},"contracts/interfaces/IThresholdAddressFactory.sol":{"content":"// SPDX-License-Identifier: MIT OR Apache-2.0\npragma solidity >=0.8.0;\n\ninterface IThresholdAddressFactory {\n    function deploy(\n        address[] calldata _values,\n        uint8 _threshold\n    ) external returns (address);\n}\n"},"contracts/interfaces/ITokenBridge.sol":{"content":"// SPDX-License-Identifier: MIT OR Apache-2.0\npragma solidity >=0.8.0;\n\nstruct Quote {\n    address token; // address(0) for the native token\n    uint256 amount;\n}\n\ninterface ITokenBridge {\n    /**\n     * @notice Transfer value to another domain\n     * @param _destination The destination domain of the message\n     * @param _recipient The message recipient address on `destination`\n     * @param _amount The amount to send to the recipient\n     * @return messageId The identifier of the dispatched message.\n     */\n    function transferRemote(\n        uint32 _destination,\n        bytes32 _recipient,\n        uint256 _amount\n    ) external payable returns (bytes32);\n\n    /**\n     * @notice Provide the value transfer quote\n     * @param _destination The destination domain of the message\n     * @param _recipient The message recipient address on `destination`\n     * @param _amount The amount to send to the recipient\n     * @return quotes Indicate how much of each token to approve and/or send.\n     * @dev Good practice is to use the first entry of the quotes for the native currency (i.e. ETH)\n     */\n    function quoteTransferRemote(\n        uint32 _destination,\n        bytes32 _recipient,\n        uint256 _amount\n    ) external view returns (Quote[] memory quotes);\n}\n"},"contracts/interfaces/IValidatorAnnounce.sol":{"content":"// SPDX-License-Identifier: MIT OR Apache-2.0\npragma solidity >=0.6.11;\n\ninterface IValidatorAnnounce {\n    /// @notice Returns a list of validators that have made announcements\n    function getAnnouncedValidators() external view returns (address[] memory);\n\n    /**\n     * @notice Returns a list of all announced storage locations for `validators`\n     * @param _validators The list of validators to get storage locations for\n     * @return A list of announced storage locations\n     */\n    function getAnnouncedStorageLocations(\n        address[] calldata _validators\n    ) external view returns (string[][] memory);\n\n    /**\n     * @notice Announces a validator signature storage location\n     * @param _storageLocation Information encoding the location of signed\n     * checkpoints\n     * @param _signature The signed validator announcement\n     * @return True upon success\n     */\n    function announce(\n        address _validator,\n        string calldata _storageLocation,\n        bytes calldata _signature\n    ) external returns (bool);\n}\n"},"contracts/interfaces/optimism/ICrossDomainMessenger.sol":{"content":"// SPDX-License-Identifier: MIT\npragma solidity >=0.8.0;\n\n/**\n * @title ICrossDomainMessenger interface for bedrock update\n * @dev eth-optimism's version uses strict 0.8.15 which we don't want to restrict to\n */\ninterface ICrossDomainMessenger {\n    /**\n     * Sends a cross domain message to the target messenger.\n     * @param _target Target contract address.\n     * @param _message Message to send to the target.\n     * @param _gasLimit Gas limit for the provided message.\n     */\n    function sendMessage(\n        address _target,\n        bytes calldata _message,\n        uint32 _gasLimit\n    ) external payable;\n\n    function relayMessage(\n        uint256 _nonce,\n        address _sender,\n        address _target,\n        uint256 _value,\n        uint256 _minGasLimit,\n        bytes calldata _message\n    ) external payable;\n\n    function xDomainMessageSender() external view returns (address);\n\n    function OTHER_MESSENGER() external view returns (address);\n\n    function PORTAL() external view returns (address);\n\n    function baseGas(\n        bytes calldata _message,\n        uint32 _minGasLimit\n    ) external pure returns (uint64);\n\n    function messageNonce() external view returns (uint256);\n}\n\ninterface IL1CrossDomainMessenger is ICrossDomainMessenger {}\n\ninterface IL2CrossDomainMessenger is ICrossDomainMessenger {\n    function messageNonce() external view returns (uint256);\n}\n\ninterface IL2ToL1MessagePasser {\n    function messageNonce() external view returns (uint256);\n}\n"},"contracts/interfaces/optimism/IOptimismPortal.sol":{"content":"// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\n// author: OP Labs\n// copied from https://github.com/ethereum-optimism/optimism/blob/develop/packages/contracts-bedrock/interfaces/L1/IOptimismPortal.sol\ninterface IOptimismPortal {\n    struct ProvenWithdrawal {\n        bytes32 outputRoot;\n        uint128 timestamp;\n        uint128 l2OutputIndex;\n    }\n\n    struct WithdrawalTransaction {\n        uint256 nonce;\n        address sender;\n        address target;\n        uint256 value;\n        uint256 gasLimit;\n        bytes data;\n    }\n\n    struct OutputRootProof {\n        bytes32 version;\n        bytes32 stateRoot;\n        bytes32 messagePasserStorageRoot;\n        bytes32 latestBlockhash;\n    }\n\n    function proveWithdrawalTransaction(\n        WithdrawalTransaction memory _tx,\n        uint256 _disputeGameIndex,\n        OutputRootProof memory _outputRootProof,\n        bytes[] memory _withdrawalProof\n    ) external;\n\n    function finalizeWithdrawalTransaction(\n        WithdrawalTransaction memory _tx\n    ) external;\n\n    function finalizedWithdrawals(\n        bytes32 _withdrawalHash\n    ) external view returns (bool);\n\n    function provenWithdrawals(\n        bytes32 withdrawalHash\n    ) external view returns (ProvenWithdrawal memory);\n}\n"},"contracts/interfaces/optimism/IOptimismPortal2.sol":{"content":"// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\n// author: OP Labs\n// copied from https://github.com/ethereum-optimism/optimism/blob/develop/packages/contracts-bedrock/interfaces/L1/IOptimismPortal2.sol\ninterface IOptimismPortal2 {\n    struct WithdrawalTransaction {\n        uint256 nonce;\n        address sender;\n        address target;\n        uint256 value;\n        uint256 gasLimit;\n        bytes data;\n    }\n\n    struct OutputRootProof {\n        bytes32 version;\n        bytes32 stateRoot;\n        bytes32 messagePasserStorageRoot;\n        bytes32 latestBlockhash;\n    }\n\n    struct ProvenWithdrawal {\n        address disputeGameProxy;\n        uint64 timestamp;\n    }\n\n    function provenWithdrawals(\n        bytes32 withdrawalHash,\n        address msgSender\n    ) external view returns (ProvenWithdrawal memory);\n}\n"},"contracts/interfaces/optimism/IStandardBridge.sol":{"content":"// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport {ICrossDomainMessenger} from \"./ICrossDomainMessenger.sol\";\n\ninterface IStandardBridge {\n    event ERC20BridgeFinalized(\n        address indexed localToken,\n        address indexed remoteToken,\n        address indexed from,\n        address to,\n        uint256 amount,\n        bytes extraData\n    );\n    event ERC20BridgeInitiated(\n        address indexed localToken,\n        address indexed remoteToken,\n        address indexed from,\n        address to,\n        uint256 amount,\n        bytes extraData\n    );\n    event ETHBridgeFinalized(\n        address indexed from,\n        address indexed to,\n        uint256 amount,\n        bytes extraData\n    );\n    event ETHBridgeInitiated(\n        address indexed from,\n        address indexed to,\n        uint256 amount,\n        bytes extraData\n    );\n    event Initialized(uint8 version);\n\n    receive() external payable;\n\n    function MESSENGER() external view returns (ICrossDomainMessenger);\n    function OTHER_BRIDGE() external view returns (IStandardBridge);\n    function bridgeERC20(\n        address _localToken,\n        address _remoteToken,\n        uint256 _amount,\n        uint32 _minGasLimit,\n        bytes memory _extraData\n    ) external;\n    function bridgeERC20To(\n        address _localToken,\n        address _remoteToken,\n        address _to,\n        uint256 _amount,\n        uint32 _minGasLimit,\n        bytes memory _extraData\n    ) external;\n    function bridgeETH(\n        uint32 _minGasLimit,\n        bytes memory _extraData\n    ) external payable;\n    function bridgeETHTo(\n        address _to,\n        uint32 _minGasLimit,\n        bytes memory _extraData\n    ) external payable;\n    function deposits(address, address) external view returns (uint256);\n    function finalizeBridgeERC20(\n        address _localToken,\n        address _remoteToken,\n        address _from,\n        address _to,\n        uint256 _amount,\n        bytes memory _extraData\n    ) external;\n    function finalizeBridgeETH(\n        address _from,\n        address _to,\n        uint256 _amount,\n        bytes memory _extraData\n    ) external payable;\n    function messenger() external view returns (ICrossDomainMessenger);\n    function otherBridge() external view returns (IStandardBridge);\n    function paused() external view returns (bool);\n\n    function __constructor__() external;\n}\n"},"contracts/isms/aggregation/AbstractAggregationIsm.sol":{"content":"// SPDX-License-Identifier: MIT OR Apache-2.0\npragma solidity >=0.8.0;\n\n// ============ Internal Imports ============\nimport {IInterchainSecurityModule} from \"../../interfaces/IInterchainSecurityModule.sol\";\nimport {IAggregationIsm} from \"../../interfaces/isms/IAggregationIsm.sol\";\nimport {AggregationIsmMetadata} from \"../../isms/libs/AggregationIsmMetadata.sol\";\nimport {PackageVersioned} from \"../../PackageVersioned.sol\";\n\n/**\n * @title AggregationIsm\n * @notice Manages per-domain m-of-n ISM sets that are used to verify\n * interchain messages.\n */\nabstract contract AbstractAggregationIsm is IAggregationIsm, PackageVersioned {\n    // ============ Constants ============\n\n    // solhint-disable-next-line const-name-snakecase\n    uint8 public constant moduleType =\n        uint8(IInterchainSecurityModule.Types.AGGREGATION);\n\n    // ============ Virtual Functions ============\n    // ======= OVERRIDE THESE TO IMPLEMENT =======\n\n    /**\n     * @notice Returns the set of ISMs responsible for verifying _message\n     * and the number of ISMs that must verify\n     * @dev Can change based on the content of _message\n     * @param _message Hyperlane formatted interchain message\n     * @return modules The array of ISM addresses\n     * @return threshold The number of ISMs needed to verify\n     */\n    function modulesAndThreshold(\n        bytes calldata _message\n    ) public view virtual returns (address[] memory, uint8);\n\n    // ============ Public Functions ============\n\n    /**\n     * @notice Requires that m-of-n ISMs verify the provided interchain message.\n     * @param _metadata ABI encoded module metadata (see AggregationIsmMetadata.sol)\n     * @param _message Formatted Hyperlane message (see Message.sol).\n     */\n    function verify(\n        bytes calldata _metadata,\n        bytes calldata _message\n    ) public returns (bool) {\n        (address[] memory _isms, uint8 _threshold) = modulesAndThreshold(\n            _message\n        );\n        uint256 _count = _isms.length;\n        for (uint8 i = 0; i < _count; i++) {\n            if (!AggregationIsmMetadata.hasMetadata(_metadata, i)) continue;\n            IInterchainSecurityModule _ism = IInterchainSecurityModule(\n                _isms[i]\n            );\n            require(\n                _ism.verify(\n                    AggregationIsmMetadata.metadataAt(_metadata, i),\n                    _message\n                ),\n                \"!verify\"\n            );\n            _threshold -= 1;\n        }\n        require(_threshold == 0, \"!threshold\");\n        return true;\n    }\n}\n"},"contracts/isms/aggregation/StaticAggregationIsm.sol":{"content":"// SPDX-License-Identifier: MIT OR Apache-2.0\npragma solidity >=0.8.0;\n\n// ============ Internal Imports ============\nimport {AbstractAggregationIsm} from \"./AbstractAggregationIsm.sol\";\nimport {MetaProxy} from \"../../libs/MetaProxy.sol\";\n\n/**\n * @title StaticAggregationIsm\n * @notice Manages per-domain m-of-n ISM sets that are used to verify\n * interchain messages.\n */\ncontract StaticAggregationIsm is AbstractAggregationIsm {\n    // ============ Public Functions ============\n\n    /**\n     * @notice Returns the set of ISMs responsible for verifying _message\n     * and the number of ISMs that must verify\n     * @dev Can change based on the content of _message\n     * @return modules The array of ISM addresses\n     * @return threshold The number of ISMs needed to verify\n     */\n    function modulesAndThreshold(\n        bytes calldata\n    ) public view virtual override returns (address[] memory, uint8) {\n        return abi.decode(MetaProxy.metadata(), (address[], uint8));\n    }\n}\n"},"contracts/isms/aggregation/StaticAggregationIsmFactory.sol":{"content":"// SPDX-License-Identifier: MIT OR Apache-2.0\npragma solidity >=0.8.0;\n\n// ============ Internal Imports ============\nimport {StaticAggregationIsm} from \"./StaticAggregationIsm.sol\";\nimport {StaticThresholdAddressSetFactory} from \"../../libs/StaticAddressSetFactory.sol\";\n\ncontract StaticAggregationIsmFactory is StaticThresholdAddressSetFactory {\n    function _deployImplementation()\n        internal\n        virtual\n        override\n        returns (address)\n    {\n        return address(new StaticAggregationIsm());\n    }\n}\n"},"contracts/isms/aggregation/StorageAggregationIsm.sol":{"content":"// SPDX-License-Identifier: MIT OR Apache-2.0\npragma solidity >=0.8.0;\n\n// ============ Internal Imports ============\nimport {AbstractAggregationIsm} from \"./AbstractAggregationIsm.sol\";\nimport {IThresholdAddressFactory} from \"../../interfaces/IThresholdAddressFactory.sol\";\nimport {MinimalProxy} from \"../../libs/MinimalProxy.sol\";\nimport {PackageVersioned} from \"../../PackageVersioned.sol\";\n\n// ============ External Imports ============\nimport {Ownable2StepUpgradeable} from \"@openzeppelin/contracts-upgradeable/access/Ownable2StepUpgradeable.sol\";\n\ncontract StorageAggregationIsm is\n    AbstractAggregationIsm,\n    Ownable2StepUpgradeable\n{\n    address[] public modules;\n    uint8 public threshold;\n\n    event ModulesAndThresholdSet(address[] modules, uint8 threshold);\n\n    constructor(\n        address[] memory _modules,\n        uint8 _threshold\n    ) Ownable2StepUpgradeable() {\n        modules = _modules;\n        threshold = _threshold;\n        _disableInitializers();\n    }\n\n    function initialize(\n        address _owner,\n        address[] memory _modules,\n        uint8 _threshold\n    ) external initializer {\n        __Ownable2Step_init();\n        setModulesAndThreshold(_modules, _threshold);\n        _transferOwnership(_owner);\n    }\n\n    function setModulesAndThreshold(\n        address[] memory _modules,\n        uint8 _threshold\n    ) public onlyOwner {\n        require(\n            0 < _threshold && _threshold <= _modules.length,\n            \"Invalid threshold\"\n        );\n        modules = _modules;\n        threshold = _threshold;\n        emit ModulesAndThresholdSet(_modules, _threshold);\n    }\n\n    function modulesAndThreshold(\n        bytes calldata /* _message */\n    ) public view override returns (address[] memory, uint8) {\n        return (modules, threshold);\n    }\n}\n\ncontract StorageAggregationIsmFactory is\n    IThresholdAddressFactory,\n    PackageVersioned\n{\n    address public immutable implementation;\n\n    constructor() {\n        implementation = address(\n            new StorageAggregationIsm(new address[](1), 1)\n        );\n    }\n\n    /**\n     * @notice Emitted when a multisig module is deployed\n     * @param module The deployed ISM\n     */\n    event ModuleDeployed(address module);\n\n    // ============ External Functions ============\n    function deploy(\n        address[] calldata _modules,\n        uint8 _threshold\n    ) external returns (address ism) {\n        ism = MinimalProxy.create(implementation);\n        emit ModuleDeployed(ism);\n        StorageAggregationIsm(ism).initialize(msg.sender, _modules, _threshold);\n    }\n}\n"},"contracts/isms/ccip-read/AbstractCcipReadIsm.sol":{"content":"// SPDX-License-Identifier: MIT OR Apache-2.0\npragma solidity >=0.8.0;\n\n// ============ Internal Imports ============\nimport {IInterchainSecurityModule} from \"../../interfaces/IInterchainSecurityModule.sol\";\nimport {ICcipReadIsm} from \"../../interfaces/isms/ICcipReadIsm.sol\";\nimport {PackageVersioned} from \"../../PackageVersioned.sol\";\n\n// ============ External Imports ============\nimport {OwnableUpgradeable} from \"@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol\";\n\n/**\n * @title AbstractCcipReadIsm\n * @notice An ISM that allows arbitrary payloads to be submitted and verified on chain\n * @dev https://eips.ethereum.org/EIPS/eip-3668\n * @dev The AbstractCcipReadIsm provided by Hyperlane is left intentionally minimalist as\n * the range of applications that could be supported by a CcipReadIsm are so broad. However\n * there are few things to note when building a custom CcipReadIsm.\n *\n */\nabstract contract AbstractCcipReadIsm is\n    ICcipReadIsm,\n    OwnableUpgradeable,\n    PackageVersioned\n{\n    // ============ Constants ============\n\n    // solhint-disable-next-line const-name-snakecase\n    uint8 public constant moduleType =\n        uint8(IInterchainSecurityModule.Types.CCIP_READ);\n\n    string[] internal _urls;\n\n    /**\n     * @notice Emitted when new CCIP-read urls are being set\n     */\n    event UrlsChanged(string[] newUrls);\n\n    function setUrls(string[] memory __urls) public onlyOwner {\n        require(__urls.length > 0, \"AbstractCcipReadIsm: urls cannot be empty\");\n        _urls = __urls;\n        emit UrlsChanged(__urls);\n    }\n\n    function getOffchainVerifyInfo(\n        bytes calldata _message\n    ) external view override {\n        revert OffchainLookup({\n            sender: address(this),\n            urls: _urls,\n            callData: _offchainLookupCalldata(_message),\n            callbackFunction: this.verify.selector,\n            extraData: _message\n        });\n    }\n\n    function urls() external view returns (string[] memory) {\n        return _urls;\n    }\n\n    /*\n     * @dev This should return the calldata to be used for the offchain lookup.\n     **/\n    function _offchainLookupCalldata(\n        bytes calldata _message\n    ) internal view virtual returns (bytes memory);\n}\n"},"contracts/isms/ccip-read/CommitmentReadIsm.sol":{"content":"// SPDX-License-Identifier: MIT OR Apache-2.0\npragma solidity >=0.8.0;\n\n// ============ Internal Imports ============\nimport {Mailbox} from \"../../Mailbox.sol\";\nimport {AbstractCcipReadIsm} from \"./AbstractCcipReadIsm.sol\";\nimport {Ownable} from \"@openzeppelin/contracts/access/Ownable.sol\";\nimport {InterchainAccountMessageReveal} from \"../../middleware/libs/InterchainAccountMessage.sol\";\nimport {InterchainAccountRouter} from \"../../middleware/InterchainAccountRouter.sol\";\nimport {CallLib} from \"../../middleware/libs/Call.sol\";\nimport {Message} from \"../../libs/Message.sol\";\nimport {TypeCasts} from \"../../libs/TypeCasts.sol\";\nimport {OwnableMulticall} from \"../../middleware/libs/OwnableMulticall.sol\";\nimport {MailboxClient} from \"../../client/MailboxClient.sol\";\n\ninterface CommitmentReadIsmService {\n    function getCallsFromRevealMessage(\n        bytes memory _message\n    )\n        external\n        view\n        returns (address ica, bytes32 salt, CallLib.Call[] memory _calls);\n}\n\ncontract CommitmentReadIsm is AbstractCcipReadIsm {\n    using InterchainAccountMessageReveal for bytes;\n    using Message for bytes;\n    using TypeCasts for bytes32;\n\n    constructor(address _owner, string[] memory _urls) {\n        _transferOwnership(msg.sender);\n        setUrls(_urls);\n        _transferOwnership(_owner);\n    }\n\n    function _offchainLookupCalldata(\n        bytes calldata _message\n    ) internal pure override returns (bytes memory) {\n        return\n            abi.encodeCall(\n                CommitmentReadIsmService.getCallsFromRevealMessage,\n                (_message)\n            );\n    }\n\n    /**\n     * @notice Verifies the commitment by comparing the calldata hash to the commitment\n     * @param _metadata The encoded (ica, salt, calls)\n     * @param _message The reveal Hyperlane message\n     * @return true If the hash of the metadata matches the commitment.\n     */\n    function verify(\n        bytes calldata _metadata,\n        bytes calldata _message\n    ) external returns (bool) {\n        // This is hash(salt, calls). The ica address is excluded\n        bytes32 revealedHash = keccak256(_metadata[20:]);\n        bytes32 msgCommitment = _message.body().revealCommitment();\n        require(\n            revealedHash == msgCommitment,\n            \"Commitment ISM: Revealed Hash Invalid\"\n        );\n\n        // Fetch encoded ica, salt, and calls\n        address _ica = address(bytes20(_metadata[:20]));\n        OwnableMulticall ica = OwnableMulticall(payable(_ica));\n\n        bytes32 salt = bytes32(_metadata[20:52]);\n\n        CallLib.Call[] memory calls = abi.decode(\n            _metadata[52:],\n            (CallLib.Call[])\n        );\n\n        // The ica will check if the commitment is pending execution, reverting if not.\n        ica.revealAndExecute(calls, salt);\n\n        return true;\n    }\n}\n"},"contracts/isms/hook/AbstractMessageIdAuthorizedIsm.sol":{"content":"// SPDX-License-Identifier: MIT OR Apache-2.0\npragma solidity >=0.8.0;\n\n/*@@@@@@@       @@@@@@@@@\n @@@@@@@@@       @@@@@@@@@\n  @@@@@@@@@       @@@@@@@@@\n   @@@@@@@@@       @@@@@@@@@\n    @@@@@@@@@@@@@@@@@@@@@@@@@\n     @@@@@  HYPERLANE  @@@@@@@\n    @@@@@@@@@@@@@@@@@@@@@@@@@\n   @@@@@@@@@       @@@@@@@@@\n  @@@@@@@@@       @@@@@@@@@\n @@@@@@@@@       @@@@@@@@@\n@@@@@@@@@       @@@@@@@@*/\n\n// ============ Internal Imports ============\n\nimport {IInterchainSecurityModule} from \"../../interfaces/IInterchainSecurityModule.sol\";\nimport {LibBit} from \"../../libs/LibBit.sol\";\nimport {Message} from \"../../libs/Message.sol\";\nimport {PackageVersioned} from \"../../PackageVersioned.sol\";\n\n// ============ External Imports ============\nimport {Address} from \"@openzeppelin/contracts/utils/Address.sol\";\nimport {Initializable} from \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\n\n/**\n * @title AbstractMessageIdAuthorizedIsm\n * @notice Uses external verification options to verify interchain messages which need an authorized caller\n */\nabstract contract AbstractMessageIdAuthorizedIsm is\n    IInterchainSecurityModule,\n    Initializable,\n    PackageVersioned\n{\n    using Address for address payable;\n    using LibBit for uint256;\n    using Message for bytes;\n    // ============ Public Storage ============\n\n    /// @notice Maps messageId to whether or not the message has been verified\n    /// first bit is boolean for verification\n    /// rest of bits is the amount to send to the recipient\n    /// @dev bc of the bit packing, we can only send up to 2^255 wei\n    /// @dev the first bit is reserved for verification and the rest 255 bits are for the msg.value\n    mapping(bytes32 messageId => uint256 verifiedAndValue)\n        public verifiedMessages;\n    /// @notice Index of verification bit in verifiedMessages\n    uint256 public constant VERIFIED_MASK_INDEX = 255;\n    /// @notice address for the authorized hook\n    bytes32 public authorizedHook;\n\n    // ============ Events ============\n\n    /// @notice Emitted when a message is received from the external bridge\n    event ReceivedMessage(bytes32 indexed messageId, uint256 msgValue);\n\n    // ============ Initializer ============\n\n    function setAuthorizedHook(bytes32 _hook) external initializer {\n        require(\n            _hook != bytes32(0),\n            \"AbstractMessageIdAuthorizedIsm: invalid authorized hook\"\n        );\n        authorizedHook = _hook;\n    }\n\n    // ============ External Functions ============\n\n    /**\n     * @notice Verify a message was received by ISM.\n     * @param message Message to verify.\n     */\n    function verify(\n        bytes calldata,\n        /*metadata*/\n        bytes calldata message\n    ) external virtual returns (bool) {\n        bool verified = isVerified(message);\n        if (verified) {\n            _releaseValueToRecipient(message);\n        }\n        return verified;\n    }\n\n    // ============ Public Functions ============\n\n    /**\n     * @notice Check if a message is verified through preVerifyMessage first.\n     * @param message Message to check.\n     */\n    function isVerified(bytes calldata message) public view returns (bool) {\n        bytes32 messageId = message.id();\n        // check for the first bit (used for verification)\n        return verifiedMessages[messageId].isBitSet(VERIFIED_MASK_INDEX);\n    }\n\n    /**\n     * @notice Receive a message from the AbstractMessageIdAuthHook\n     * @dev Only callable by the authorized hook.\n     * @param messageId Hyperlane Id of the message.\n     */\n    function preVerifyMessage(\n        bytes32 messageId,\n        uint256 msgValue\n    ) public payable virtual {\n        require(\n            _isAuthorized(),\n            \"AbstractMessageIdAuthorizedIsm: sender is not the hook\"\n        );\n        require(\n            msg.value < 2 ** VERIFIED_MASK_INDEX && msg.value == msgValue,\n            \"AbstractMessageIdAuthorizedIsm: invalid msg.value\"\n        );\n        require(\n            verifiedMessages[messageId] == 0,\n            \"AbstractMessageIdAuthorizedIsm: message already verified\"\n        );\n\n        verifiedMessages[messageId] = msg.value.setBit(VERIFIED_MASK_INDEX);\n        emit ReceivedMessage(messageId, msgValue);\n    }\n\n    // ============ Internal Functions ============\n\n    /**\n     * @notice Release the value to the recipient if the message is verified.\n     * @param message Message to release value for.\n     */\n    function _releaseValueToRecipient(bytes calldata message) internal {\n        bytes32 messageId = message.id();\n        uint256 _msgValue = verifiedMessages[messageId].clearBit(\n            VERIFIED_MASK_INDEX\n        );\n        if (_msgValue > 0) {\n            verifiedMessages[messageId] -= _msgValue;\n            payable(message.recipientAddress()).sendValue(_msgValue);\n        }\n    }\n\n    /**\n     * @notice Check if sender is authorized to message `preVerifyMessage`.\n     */\n    function _isAuthorized() internal view virtual returns (bool);\n}\n"},"contracts/isms/hook/ArbL2ToL1Ism.sol":{"content":"// SPDX-License-Identifier: MIT OR Apache-2.0\npragma solidity >=0.8.0;\n\n/*@@@@@@@       @@@@@@@@@\n @@@@@@@@@       @@@@@@@@@\n  @@@@@@@@@       @@@@@@@@@\n   @@@@@@@@@       @@@@@@@@@\n    @@@@@@@@@@@@@@@@@@@@@@@@@\n     @@@@@  HYPERLANE  @@@@@@@\n    @@@@@@@@@@@@@@@@@@@@@@@@@\n   @@@@@@@@@       @@@@@@@@@\n  @@@@@@@@@       @@@@@@@@@\n @@@@@@@@@       @@@@@@@@@\n@@@@@@@@@       @@@@@@@@*/\n\n// ============ Internal Imports ============\n\nimport {IInterchainSecurityModule} from \"../../interfaces/IInterchainSecurityModule.sol\";\nimport {TypeCasts} from \"../../libs/TypeCasts.sol\";\nimport {Message} from \"../../libs/Message.sol\";\nimport {AbstractMessageIdAuthorizedIsm} from \"./AbstractMessageIdAuthorizedIsm.sol\";\n\n// ============ External Imports ============\n\nimport {IBridge} from \"@arbitrum/nitro-contracts/src/bridge/IBridge.sol\";\nimport {IOutbox} from \"@arbitrum/nitro-contracts/src/bridge/IOutbox.sol\";\nimport {CrossChainEnabledArbitrumL1} from \"@openzeppelin/contracts/crosschain/arbitrum/CrossChainEnabledArbitrumL1.sol\";\nimport {Address} from \"@openzeppelin/contracts/utils/Address.sol\";\n\n/**\n * @title ArbL2ToL1Ism\n * @notice Uses the native Arbitrum bridge to verify interchain messages from L2 to L1.\n */\ncontract ArbL2ToL1Ism is\n    CrossChainEnabledArbitrumL1,\n    AbstractMessageIdAuthorizedIsm\n{\n    using Message for bytes;\n    // ============ Constants ============\n\n    // module type for the ISM\n    uint8 public constant moduleType =\n        uint8(IInterchainSecurityModule.Types.ARB_L2_TO_L1);\n    // arbitrum nitro contract on L1 to forward verification\n    IOutbox public arbOutbox;\n\n    uint256 private constant DATA_LENGTH = 68;\n\n    uint256 private constant MESSAGE_ID_END = 36;\n\n    // ============ Constructor ============\n\n    constructor(address _bridge) CrossChainEnabledArbitrumL1(_bridge) {\n        require(\n            Address.isContract(_bridge),\n            \"ArbL2ToL1Ism: invalid Arbitrum Bridge\"\n        );\n        arbOutbox = IOutbox(IBridge(_bridge).activeOutbox());\n    }\n\n    // ============ External Functions ============\n\n    /// @inheritdoc IInterchainSecurityModule\n    function verify(\n        bytes calldata metadata,\n        bytes calldata message\n    ) external override returns (bool) {\n        if (!isVerified(message)) {\n            _verifyWithOutboxCall(metadata, message);\n            require(isVerified(message), \"ArbL2ToL1Ism: message not verified\");\n        }\n        _releaseValueToRecipient(message);\n        return true;\n    }\n\n    // ============ Internal function ============\n\n    /**\n     * @notice Verify message directly using the arbOutbox.executeTransaction function.\n     * @dev This is a fallback in case the message is not verified by the stateful verify function first.\n     * @dev This function doesn't support msg.value as the ism.verify call doesn't support it either.\n     */\n    function _verifyWithOutboxCall(\n        bytes calldata metadata,\n        bytes calldata message\n    ) internal {\n        (\n            bytes32[] memory proof,\n            uint256 index,\n            address l2Sender,\n            address to,\n            uint256 l2Block,\n            uint256 l1Block,\n            uint256 l2Timestamp,\n            uint256 value,\n            bytes memory data\n        ) = abi.decode(\n                metadata,\n                (\n                    bytes32[],\n                    uint256,\n                    address,\n                    address,\n                    uint256,\n                    uint256,\n                    uint256,\n                    uint256,\n                    bytes\n                )\n            );\n\n        // check if the sender of the l2 message is the authorized hook\n        require(\n            l2Sender == TypeCasts.bytes32ToAddress(authorizedHook),\n            \"ArbL2ToL1Ism: l2Sender != authorizedHook\"\n        );\n        // this data is an abi encoded call of preVerifyMessage(bytes32 messageId)\n        require(\n            data.length == DATA_LENGTH,\n            \"ArbL2ToL1Ism: invalid data length\"\n        );\n        bytes32 messageId = message.id();\n        bytes32 convertedBytes;\n        assembly {\n            // data = 0x[4 bytes function signature][32 bytes messageId]\n            convertedBytes := mload(add(data, MESSAGE_ID_END))\n        }\n        // check if the parsed message id matches the message id of the message\n        require(\n            convertedBytes == messageId,\n            \"ArbL2ToL1Ism: invalid message id\"\n        );\n        arbOutbox.executeTransaction(\n            proof,\n            index,\n            l2Sender,\n            to,\n            l2Block,\n            l1Block,\n            l2Timestamp,\n            value,\n            data\n        );\n    }\n\n    /// @inheritdoc AbstractMessageIdAuthorizedIsm\n    function _isAuthorized() internal view override returns (bool) {\n        return\n            _crossChainSender() == TypeCasts.bytes32ToAddress(authorizedHook);\n    }\n}\n"},"contracts/isms/hook/CCIPIsm.sol":{"content":"// SPDX-License-Identifier: MIT OR Apache-2.0\npragma solidity >=0.8.0;\n\n/*@@@@@@@       @@@@@@@@@\n @@@@@@@@@       @@@@@@@@@\n  @@@@@@@@@       @@@@@@@@@\n   @@@@@@@@@       @@@@@@@@@\n    @@@@@@@@@@@@@@@@@@@@@@@@@\n     @@@@@  HYPERLANE  @@@@@@@\n    @@@@@@@@@@@@@@@@@@@@@@@@@\n   @@@@@@@@@       @@@@@@@@@\n  @@@@@@@@@       @@@@@@@@@\n @@@@@@@@@       @@@@@@@@@\n@@@@@@@@@       @@@@@@@@*/\n\n// ============ Internal Imports ============\n\nimport {IInterchainSecurityModule} from \"../../interfaces/IInterchainSecurityModule.sol\";\nimport {TypeCasts} from \"../../libs/TypeCasts.sol\";\nimport {AbstractMessageIdAuthorizedIsm} from \"./AbstractMessageIdAuthorizedIsm.sol\";\n\n// ============ External Imports ============\nimport {Client} from \"@chainlink/contracts-ccip/src/v0.8/ccip/libraries/Client.sol\";\nimport {CCIPReceiver} from \"@chainlink/contracts-ccip/src/v0.8/ccip/applications/CCIPReceiver.sol\";\n\n/**\n * @title CCIPIsm\n * @notice Uses CCIP hook to verify interchain messages.\n */\ncontract CCIPIsm is AbstractMessageIdAuthorizedIsm, CCIPReceiver {\n    using TypeCasts for bytes32;\n\n    // ============ Constants ============\n\n    uint8 public constant moduleType =\n        uint8(IInterchainSecurityModule.Types.NULL);\n\n    uint64 public immutable ccipOrigin;\n\n    // ============ Storage ============\n    constructor(\n        address _ccipRouter,\n        uint64 _ccipOrigin\n    ) CCIPReceiver(_ccipRouter) {\n        ccipOrigin = _ccipOrigin;\n    }\n\n    // ============ Internal functions ============\n    function _ccipReceive(\n        Client.Any2EVMMessage memory any2EvmMessage\n    ) internal override {\n        require(\n            ccipOrigin == any2EvmMessage.sourceChainSelector,\n            \"Unauthorized origin\"\n        );\n\n        bytes32 sender = abi.decode(any2EvmMessage.sender, (bytes32));\n        require(sender == authorizedHook, \"Unauthorized hook\");\n\n        bytes32 messageId = abi.decode(any2EvmMessage.data, (bytes32));\n        preVerifyMessage(messageId, 0);\n    }\n\n    function _isAuthorized() internal view override returns (bool) {\n        return msg.sender == getRouter();\n    }\n}\n"},"contracts/isms/hook/ERC5164Ism.sol":{"content":"// SPDX-License-Identifier: MIT OR Apache-2.0\npragma solidity >=0.8.0;\n\n/*@@@@@@@       @@@@@@@@@\n @@@@@@@@@       @@@@@@@@@\n  @@@@@@@@@       @@@@@@@@@\n   @@@@@@@@@       @@@@@@@@@\n    @@@@@@@@@@@@@@@@@@@@@@@@@\n     @@@@@  HYPERLANE  @@@@@@@\n    @@@@@@@@@@@@@@@@@@@@@@@@@\n   @@@@@@@@@       @@@@@@@@@\n  @@@@@@@@@       @@@@@@@@@\n @@@@@@@@@       @@@@@@@@@\n@@@@@@@@@       @@@@@@@@*/\n\n// ============ Internal Imports ============\n\nimport {IInterchainSecurityModule} from \"../../interfaces/IInterchainSecurityModule.sol\";\nimport {AbstractMessageIdAuthorizedIsm} from \"./AbstractMessageIdAuthorizedIsm.sol\";\n\n// ============ External Imports ============\n\nimport {Address} from \"@openzeppelin/contracts/utils/Address.sol\";\n\n/**\n * @title ERC5164Ism\n * @notice Uses the generic eip-5164 standard to verify interchain messages.\n */\ncontract ERC5164Ism is AbstractMessageIdAuthorizedIsm {\n    // ============ Constants ============\n\n    uint8 public constant moduleType =\n        uint8(IInterchainSecurityModule.Types.NULL);\n    // corresponding 5164 executor address\n    address public immutable executor;\n\n    // ============ Constructor ============\n\n    constructor(address _executor) {\n        require(Address.isContract(_executor), \"ERC5164Ism: invalid executor\");\n        executor = _executor;\n    }\n\n    /**\n     * @notice Check if sender is authorized to message `preVerifyMessage`.\n     */\n    function _isAuthorized() internal view override returns (bool) {\n        return msg.sender == executor;\n    }\n}\n"},"contracts/isms/hook/OPL2ToL1CcipReadIsm.sol":{"content":"// SPDX-License-Identifier: MIT OR Apache-2.0\npragma solidity >=0.8.0;\n\nimport {Message} from \"../../libs/Message.sol\";\nimport {TypeCasts} from \"../../libs/TypeCasts.sol\";\nimport {IMailbox} from \"../../interfaces/IMailbox.sol\";\nimport {PackageVersioned} from \"../../PackageVersioned.sol\";\nimport {OPL2ToL1Withdrawal} from \"../../libs/OPL2ToL1Withdrawal.sol\";\nimport {AbstractCcipReadIsm} from \"../ccip-read/AbstractCcipReadIsm.sol\";\nimport {IMessageRecipient} from \"../../interfaces/IMessageRecipient.sol\";\nimport {IOptimismPortal} from \"../../interfaces/optimism/IOptimismPortal.sol\";\nimport {IOptimismPortal2} from \"../../interfaces/optimism/IOptimismPortal2.sol\";\nimport {IInterchainSecurityModule, ISpecifiesInterchainSecurityModule} from \"../../interfaces/IInterchainSecurityModule.sol\";\nimport {MailboxClient} from \"../../client/MailboxClient.sol\";\nimport {Address} from \"@openzeppelin/contracts/utils/Address.sol\";\n\ninterface OpL2toL1Service {\n    function getWithdrawalProof(\n        bytes calldata _message\n    )\n        external\n        view\n        returns (\n            IOptimismPortal.WithdrawalTransaction memory _tx,\n            uint256 _disputeGameIndex,\n            IOptimismPortal.OutputRootProof memory _outputRootProof,\n            bytes[] memory _withdrawalProof\n        );\n    function getFinalizeWithdrawalTx(\n        bytes calldata _message\n    ) external view returns (IOptimismPortal.WithdrawalTransaction memory _tx);\n}\n\n/**\n * @notice Prove and finalize a OP stack withdrawal on L1\n * @dev Proving and finalizing had been merged into a single\n * ISM because OP Stack expects the prover and the finalizer to\n * be the same caller\n */\nabstract contract OPL2ToL1CcipReadIsm is AbstractCcipReadIsm {\n    using Message for bytes;\n    using TypeCasts for address;\n    using TypeCasts for bytes32;\n    using OPL2ToL1Withdrawal for IOptimismPortal.WithdrawalTransaction;\n\n    // the OP Portal contract on L1\n    IOptimismPortal public immutable opPortal;\n\n    constructor(address _opPortal) {\n        require(\n            Address.isContract(_opPortal),\n            \"OPL2ToL1CcipReadIsm: invalid opPortal\"\n        );\n        opPortal = IOptimismPortal(_opPortal);\n    }\n\n    function _offchainLookupCalldata(\n        bytes calldata _message\n    ) internal view override returns (bytes memory) {\n        return\n            _isProve(_message)\n                ? abi.encodeCall(OpL2toL1Service.getWithdrawalProof, (_message))\n                : abi.encodeCall(\n                    OpL2toL1Service.getFinalizeWithdrawalTx,\n                    (_message)\n                );\n    }\n\n    function verify(\n        bytes calldata _metadata,\n        bytes calldata _message\n    ) external override returns (bool) {\n        if (_isProve(_message)) {\n            _proveWithdrawal(_message, _metadata);\n        } else {\n            _finalizeWithdrawal(_message, _metadata);\n        }\n\n        return true;\n    }\n\n    function _isProve(\n        bytes calldata _message\n    ) internal view virtual returns (bool);\n\n    function _proveWithdrawal(\n        bytes calldata _message,\n        bytes calldata _metadata\n    ) internal {\n        (\n            IOptimismPortal.WithdrawalTransaction memory _tx,\n            uint256 _disputeGameIndex,\n            IOptimismPortal.OutputRootProof memory _outputRootProof,\n            bytes[] memory _withdrawalProof\n        ) = abi.decode(\n                _metadata,\n                (\n                    IOptimismPortal.WithdrawalTransaction,\n                    uint256,\n                    IOptimismPortal.OutputRootProof,\n                    bytes[]\n                )\n            );\n\n        require(\n            _tx.sender == _message.sender().bytes32ToAddress(),\n            \"OPL2ToL1CcipReadIsm: sender mismatch\"\n        );\n\n        require(\n            _tx.proveMessageId() == _message.id(),\n            \"OPL2ToL1CcipReadIsm: prove message id mismatch\"\n        );\n\n        bytes32 withdrawalHash = _tx.hashWithdrawal();\n\n        // Proving only if the withdrawal wasn't\n        // proven already by this contract\n        if (!_isWithdrawalProvenAlready(withdrawalHash)) {\n            opPortal.proveWithdrawalTransaction(\n                _tx,\n                _disputeGameIndex,\n                _outputRootProof,\n                _withdrawalProof\n            );\n        }\n    }\n\n    function _isWithdrawalProvenAlready(\n        bytes32 _withdrawalHash\n    ) internal view virtual returns (bool);\n\n    function _finalizeWithdrawal(\n        bytes calldata _message,\n        bytes calldata _metadata\n    ) internal {\n        IOptimismPortal.WithdrawalTransaction memory _tx = abi.decode(\n            _metadata,\n            (IOptimismPortal.WithdrawalTransaction)\n        );\n\n        require(\n            _tx.sender == _message.sender().bytes32ToAddress(),\n            \"OPL2ToL1CcipReadIsm: sender mismatch\"\n        );\n\n        require(\n            _tx.finalizeMessageId() == _message.id(),\n            \"OPL2ToL1CcipReadIsm: finalize message id mismatch\"\n        );\n\n        bytes32 withdrawalHash = _tx.hashWithdrawal();\n\n        if (!opPortal.finalizedWithdrawals(withdrawalHash)) {\n            opPortal.finalizeWithdrawalTransaction(_tx);\n        }\n    }\n}\n\nabstract contract OPL2ToL1V1CcipReadIsm is OPL2ToL1CcipReadIsm {\n    function _isWithdrawalProvenAlready(\n        bytes32 _withdrawalHash\n    ) internal view override returns (bool) {\n        IOptimismPortal.ProvenWithdrawal memory provenWithdrawal = opPortal\n            .provenWithdrawals(_withdrawalHash);\n        return provenWithdrawal.timestamp > 0;\n    }\n}\n\nabstract contract OPL2ToL1V2CcipReadIsm is OPL2ToL1CcipReadIsm {\n    function _isWithdrawalProvenAlready(\n        bytes32 _withdrawalHash\n    ) internal view override returns (bool) {\n        IOptimismPortal2.ProvenWithdrawal\n            memory provenWithdrawal = IOptimismPortal2(address(opPortal))\n                .provenWithdrawals(_withdrawalHash, address(this));\n        return provenWithdrawal.timestamp > 0;\n    }\n}\n"},"contracts/isms/hook/OPStackIsm.sol":{"content":"// SPDX-License-Identifier: MIT OR Apache-2.0\npragma solidity >=0.8.0;\n\n/*@@@@@@@       @@@@@@@@@\n @@@@@@@@@       @@@@@@@@@\n  @@@@@@@@@       @@@@@@@@@\n   @@@@@@@@@       @@@@@@@@@\n    @@@@@@@@@@@@@@@@@@@@@@@@@\n     @@@@@  HYPERLANE  @@@@@@@\n    @@@@@@@@@@@@@@@@@@@@@@@@@\n   @@@@@@@@@       @@@@@@@@@\n  @@@@@@@@@       @@@@@@@@@\n @@@@@@@@@       @@@@@@@@@\n@@@@@@@@@       @@@@@@@@*/\n\n// ============ Internal Imports ============\n\nimport {IInterchainSecurityModule} from \"../../interfaces/IInterchainSecurityModule.sol\";\nimport {AbstractMessageIdAuthorizedIsm} from \"./AbstractMessageIdAuthorizedIsm.sol\";\nimport {TypeCasts} from \"../../libs/TypeCasts.sol\";\n// ============ External Imports ============\nimport {CrossChainEnabledOptimism} from \"@openzeppelin/contracts/crosschain/optimism/CrossChainEnabledOptimism.sol\";\nimport {Address} from \"@openzeppelin/contracts/utils/Address.sol\";\n\n/**\n * @title OPStackIsm\n * @notice Uses the native Optimism bridge to verify interchain messages.\n */\ncontract OPStackIsm is\n    CrossChainEnabledOptimism,\n    AbstractMessageIdAuthorizedIsm\n{\n    // ============ Constants ============\n\n    uint8 public constant moduleType =\n        uint8(IInterchainSecurityModule.Types.NULL);\n\n    // ============ Constructor ============\n\n    constructor(address _l2Messenger) CrossChainEnabledOptimism(_l2Messenger) {\n        require(\n            Address.isContract(_l2Messenger),\n            \"OPStackIsm: invalid L2Messenger\"\n        );\n    }\n\n    // ============ Internal function ============\n\n    /**\n     * @notice Check if sender is authorized to message `preVerifyMessage`.\n     */\n    function _isAuthorized() internal view override returns (bool) {\n        return\n            _crossChainSender() == TypeCasts.bytes32ToAddress(authorizedHook);\n    }\n}\n"},"contracts/isms/libs/AggregationIsmMetadata.sol":{"content":"// SPDX-License-Identifier: MIT OR Apache-2.0\npragma solidity >=0.8.0;\n\n/**\n * Format of metadata:\n *\n * [????:????] Metadata start/end uint32 ranges, packed as uint64\n * [????:????] ISM metadata, packed encoding\n */\nlibrary AggregationIsmMetadata {\n    uint256 private constant RANGE_SIZE = 4;\n\n    /**\n     * @notice Returns whether or not metadata was provided for the ISM at\n     * `_index`\n     * @dev Callers must ensure _index is less than the number of metadatas\n     * provided\n     * @param _metadata Encoded Aggregation ISM metadata\n     * @param _index The index of the ISM to check for metadata for\n     * @return Whether or not metadata was provided for the ISM at `_index`\n     */\n    function hasMetadata(\n        bytes calldata _metadata,\n        uint8 _index\n    ) internal pure returns (bool) {\n        (uint32 _start, ) = _metadataRange(_metadata, _index);\n        return _start > 0;\n    }\n\n    /**\n     * @notice Returns the metadata provided for the ISM at `_index`\n     * @dev Callers must ensure _index is less than the number of metadatas\n     * provided\n     * @dev Callers must ensure `hasMetadata(_metadata, _index)`\n     * @param _metadata Encoded Aggregation ISM metadata\n     * @param _index The index of the ISM to return metadata for\n     * @return The metadata provided for the ISM at `_index`\n     */\n    function metadataAt(\n        bytes calldata _metadata,\n        uint8 _index\n    ) internal pure returns (bytes calldata) {\n        (uint32 _start, uint32 _end) = _metadataRange(_metadata, _index);\n        return _metadata[_start:_end];\n    }\n\n    /**\n     * @notice Returns the range of the metadata provided for the ISM at\n     * `_index`, or zeroes if not provided\n     * @dev Callers must ensure _index is less than the number of metadatas\n     * provided\n     * @param _metadata Encoded Aggregation ISM metadata\n     * @param _index The index of the ISM to return metadata range for\n     * @return The range of the metadata provided for the ISM at `_index`, or\n     * zeroes if not provided\n     */\n    function _metadataRange(\n        bytes calldata _metadata,\n        uint8 _index\n    ) private pure returns (uint32, uint32) {\n        uint256 _start = (uint32(_index) * RANGE_SIZE * 2);\n        uint256 _mid = _start + RANGE_SIZE;\n        uint256 _end = _mid + RANGE_SIZE;\n        return (\n            uint32(bytes4(_metadata[_start:_mid])),\n            uint32(bytes4(_metadata[_mid:_end]))\n        );\n    }\n}\n"},"contracts/isms/libs/MerkleRootMultisigIsmMetadata.sol":{"content":"// SPDX-License-Identifier: MIT OR Apache-2.0\npragma solidity >=0.8.0;\n\n/**\n * Format of metadata:\n * [   0:  32] Origin merkle tree address\n * [  32:  36] Index of message ID in merkle tree\n * [  36:  68] Signed checkpoint message ID\n * [  68:1092] Merkle proof\n * [1092:1096] Signed checkpoint index (computed from proof and index)\n * [1096:????] Validator signatures (length := threshold * 65)\n */\nlibrary MerkleRootMultisigIsmMetadata {\n    uint8 private constant ORIGIN_MERKLE_TREE_OFFSET = 0;\n    uint8 private constant MESSAGE_INDEX_OFFSET = 32;\n    uint8 private constant MESSAGE_ID_OFFSET = 36;\n    uint8 private constant MERKLE_PROOF_OFFSET = 68;\n    uint16 private constant MERKLE_PROOF_LENGTH = 32 * 32;\n    uint16 private constant SIGNED_INDEX_OFFSET = 1092;\n    uint16 private constant SIGNATURES_OFFSET = 1096;\n    uint8 private constant SIGNATURE_LENGTH = 65;\n\n    /**\n     * @notice Returns the origin merkle tree hook of the signed checkpoint as bytes32.\n     * @param _metadata ABI encoded Multisig ISM metadata.\n     * @return Origin merkle tree hook of the signed checkpoint as bytes32\n     */\n    function originMerkleTreeHook(\n        bytes calldata _metadata\n    ) internal pure returns (bytes32) {\n        return\n            bytes32(\n                _metadata[ORIGIN_MERKLE_TREE_OFFSET:ORIGIN_MERKLE_TREE_OFFSET +\n                    32]\n            );\n    }\n\n    /**\n     * @notice Returns the index of the message being proven.\n     * @param _metadata ABI encoded Multisig ISM metadata.\n     * @return Index of the target message in the merkle tree.\n     */\n    function messageIndex(\n        bytes calldata _metadata\n    ) internal pure returns (uint32) {\n        return\n            uint32(\n                bytes4(_metadata[MESSAGE_INDEX_OFFSET:MESSAGE_INDEX_OFFSET + 4])\n            );\n    }\n\n    /**\n     * @notice Returns the index of the signed checkpoint.\n     * @param _metadata ABI encoded Multisig ISM metadata.\n     * @return Index of the signed checkpoint\n     */\n    function signedIndex(\n        bytes calldata _metadata\n    ) internal pure returns (uint32) {\n        return\n            uint32(\n                bytes4(_metadata[SIGNED_INDEX_OFFSET:SIGNED_INDEX_OFFSET + 4])\n            );\n    }\n\n    /**\n     * @notice Returns the message ID of the signed checkpoint.\n     * @param _metadata ABI encoded Multisig ISM metadata.\n     * @return Message ID of the signed checkpoint\n     */\n    function signedMessageId(\n        bytes calldata _metadata\n    ) internal pure returns (bytes32) {\n        return bytes32(_metadata[MESSAGE_ID_OFFSET:MESSAGE_ID_OFFSET + 32]);\n    }\n\n    /**\n     * @notice Returns the merkle proof branch of the message.\n     * @dev This appears to be more gas efficient than returning a calldata\n     * slice and using that.\n     * @param _metadata ABI encoded Multisig ISM metadata.\n     * @return Merkle proof branch of the message.\n     */\n    function proof(\n        bytes calldata _metadata\n    ) internal pure returns (bytes32[32] memory) {\n        return\n            abi.decode(\n                _metadata[MERKLE_PROOF_OFFSET:MERKLE_PROOF_OFFSET +\n                    MERKLE_PROOF_LENGTH],\n                (bytes32[32])\n            );\n    }\n\n    /**\n     * @notice Returns the validator ECDSA signature at `_index`.\n     * @dev Assumes signatures are sorted by validator\n     * @dev Assumes `_metadata` encodes `threshold` signatures.\n     * @dev Assumes `_index` is less than `threshold`\n     * @param _metadata ABI encoded Multisig ISM metadata.\n     * @param _index The index of the signature to return.\n     * @return The validator ECDSA signature at `_index`.\n     */\n    function signatureAt(\n        bytes calldata _metadata,\n        uint256 _index\n    ) internal pure returns (bytes calldata) {\n        uint256 _start = SIGNATURES_OFFSET + (_index * SIGNATURE_LENGTH);\n        uint256 _end = _start + SIGNATURE_LENGTH;\n        return _metadata[_start:_end];\n    }\n\n    /**\n     * @notice Returns the number of signatures in the metadata.\n     * @param _metadata ABI encoded Merkle Root Multisig ISM metadata.\n     * @return The number of signatures in the metadata.\n     */\n    function signatureCount(\n        bytes calldata _metadata\n    ) internal pure returns (uint256) {\n        uint256 signatures = _metadata.length - SIGNATURES_OFFSET;\n        require(\n            signatures % SIGNATURE_LENGTH == 0,\n            \"Invalid signatures length\"\n        );\n        return signatures / SIGNATURE_LENGTH;\n    }\n}\n"},"contracts/isms/libs/MessageIdMultisigIsmMetadata.sol":{"content":"// SPDX-License-Identifier: MIT OR Apache-2.0\npragma solidity >=0.8.0;\n\n/**\n * Format of metadata:\n * [   0:  32] Origin merkle tree address\n * [  32:  64] Signed checkpoint root\n * [  64:  68] Signed checkpoint index\n * [  68:????] Validator signatures (length := threshold * 65)\n */\nlibrary MessageIdMultisigIsmMetadata {\n    uint8 private constant ORIGIN_MERKLE_TREE_OFFSET = 0;\n    uint8 private constant MERKLE_ROOT_OFFSET = 32;\n    uint8 private constant MERKLE_INDEX_OFFSET = 64;\n    uint8 private constant SIGNATURES_OFFSET = 68;\n    uint8 private constant SIGNATURE_LENGTH = 65;\n\n    /**\n     * @notice Returns the origin merkle tree hook of the signed checkpoint as bytes32.\n     * @param _metadata ABI encoded Multisig ISM metadata.\n     * @return Origin merkle tree hook of the signed checkpoint as bytes32\n     */\n    function originMerkleTreeHook(\n        bytes calldata _metadata\n    ) internal pure returns (bytes32) {\n        return\n            bytes32(\n                _metadata[ORIGIN_MERKLE_TREE_OFFSET:ORIGIN_MERKLE_TREE_OFFSET +\n                    32]\n            );\n    }\n\n    /**\n     * @notice Returns the merkle root of the signed checkpoint.\n     * @param _metadata ABI encoded Multisig ISM metadata.\n     * @return Merkle root of the signed checkpoint\n     */\n    function root(bytes calldata _metadata) internal pure returns (bytes32) {\n        return bytes32(_metadata[MERKLE_ROOT_OFFSET:MERKLE_ROOT_OFFSET + 32]);\n    }\n\n    /**\n     * @notice Returns the merkle index of the signed checkpoint.\n     * @param _metadata ABI encoded Multisig ISM metadata.\n     * @return Merkle index of the signed checkpoint\n     */\n    function index(bytes calldata _metadata) internal pure returns (uint32) {\n        return\n            uint32(\n                bytes4(_metadata[MERKLE_INDEX_OFFSET:MERKLE_INDEX_OFFSET + 4])\n            );\n    }\n\n    /**\n     * @notice Returns the validator ECDSA signature at `_index`.\n     * @dev Assumes signatures are sorted by validator\n     * @dev Assumes `_metadata` encodes `threshold` signatures.\n     * @dev Assumes `_index` is less than `threshold`\n     * @param _metadata ABI encoded Multisig ISM metadata.\n     * @param _index The index of the signature to return.\n     * @return The validator ECDSA signature at `_index`.\n     */\n    function signatureAt(\n        bytes calldata _metadata,\n        uint256 _index\n    ) internal pure returns (bytes calldata) {\n        uint256 _start = SIGNATURES_OFFSET + (_index * SIGNATURE_LENGTH);\n        uint256 _end = _start + SIGNATURE_LENGTH;\n        return _metadata[_start:_end];\n    }\n\n    /**\n     * @notice Returns the number of signatures in the metadata.\n     * @param _metadata ABI encoded MessageId Multisig ISM metadata.\n     * @return The number of signatures in the metadata.\n     */\n    function signatureCount(\n        bytes calldata _metadata\n    ) internal pure returns (uint256) {\n        uint256 signatures = _metadata.length - SIGNATURES_OFFSET;\n        require(\n            signatures % SIGNATURE_LENGTH == 0,\n            \"Invalid signatures length\"\n        );\n        return signatures / SIGNATURE_LENGTH;\n    }\n}\n"},"contracts/isms/multisig/AbstractMerkleRootMultisigIsm.sol":{"content":"// SPDX-License-Identifier: MIT OR Apache-2.0\npragma solidity >=0.8.0;\n\n// ============ Internal Imports ============\nimport {AbstractMultisig} from \"./AbstractMultisigIsm.sol\";\nimport {MerkleRootMultisigIsmMetadata} from \"../../isms/libs/MerkleRootMultisigIsmMetadata.sol\";\nimport {Message} from \"../../libs/Message.sol\";\nimport {MerkleLib} from \"../../libs/Merkle.sol\";\nimport {CheckpointLib} from \"../../libs/CheckpointLib.sol\";\n\n/**\n * @title `AbstractMerkleRootMultisigIsm` — multi-sig ISM with the validators-censorship resistance guarantee.\n * @notice This ISM allows using a newer signed checkpoint (say #33) to prove existence of an older message (#22) in the validators' MerkleTree.\n * This guarantees censorship resistance as validators cannot hide a message\n * by refusing to sign its checkpoint but later signing a checkpoint for a newer message.\n * If validators decide to censor a message, they are left with only one option — to not produce checkpoints at all.\n * Otherwise, the very next signed checkpoint (#33) can be used by any relayer to prove the previous message inclusion using this ISM.\n * This is censorship resistance is missing in the sibling implementation `AbstractMessageIdMultisigIsm`,\n * since it can only verify messages having the corresponding checkpoints.\n * @dev Provides the default implementation of verifying signatures over a checkpoint and the message inclusion in that checkpoint.\n * This abstract contract can be overridden for customizing the `validatorsAndThreshold()` (static or dynamic).\n * @dev May be adapted in future to support batch message verification against a single root.\n */\nabstract contract AbstractMerkleRootMultisigIsm is AbstractMultisig {\n    using MerkleRootMultisigIsmMetadata for bytes;\n    using Message for bytes;\n\n    // ============ Constants ============\n\n    /**\n     * @inheritdoc AbstractMultisig\n     */\n    function digest(\n        bytes calldata _metadata,\n        bytes calldata _message\n    ) internal pure virtual override returns (bytes32) {\n        require(\n            _metadata.messageIndex() <= _metadata.signedIndex(),\n            \"Invalid merkle index metadata\"\n        );\n        // We verify a merkle proof of (messageId, index) I to compute root J\n        bytes32 _signedRoot = MerkleLib.branchRoot(\n            _message.id(),\n            _metadata.proof(),\n            _metadata.messageIndex()\n        );\n        // We provide (messageId, index) J in metadata for digest derivation\n        return\n            CheckpointLib.digest(\n                _message.origin(),\n                _metadata.originMerkleTreeHook(),\n                _signedRoot,\n                _metadata.signedIndex(),\n                _metadata.signedMessageId()\n            );\n    }\n\n    /**\n     * @inheritdoc AbstractMultisig\n     */\n    function signatureAt(\n        bytes calldata _metadata,\n        uint256 _index\n    ) internal pure virtual override returns (bytes calldata) {\n        return _metadata.signatureAt(_index);\n    }\n\n    /**\n     * @inheritdoc AbstractMultisig\n     */\n    function signatureCount(\n        bytes calldata _metadata\n    ) public pure override returns (uint256) {\n        return _metadata.signatureCount();\n    }\n}\n"},"contracts/isms/multisig/AbstractMessageIdMultisigIsm.sol":{"content":"// SPDX-License-Identifier: MIT OR Apache-2.0\npragma solidity >=0.8.0;\n\n// ============ Internal Imports ============\nimport {AbstractMultisig} from \"./AbstractMultisigIsm.sol\";\nimport {MessageIdMultisigIsmMetadata} from \"../libs/MessageIdMultisigIsmMetadata.sol\";\nimport {Message} from \"../../libs/Message.sol\";\nimport {CheckpointLib} from \"../../libs/CheckpointLib.sol\";\n\n/**\n * @title `AbstractMessageIdMultisigIsm` — multi-sig ISM for the censorship-friendly validators.\n * @notice This ISM minimizes gas/performance overhead of the checkpoints verification by compromising on the censorship resistance.\n * For censorship resistance consider using `AbstractMerkleRootMultisigIsm`.\n * If the validators (`validatorsAndThreshold`) skip messages by not sign checkpoints for them,\n * the relayers will not be able to aggregate a quorum of signatures sufficient to deliver these messages via this ISM.\n * Integrations are free to choose the trade-off between the censorship resistance and the gas/processing overhead.\n * @dev Provides the default implementation of verifying signatures over a checkpoint related to a specific message ID.\n * This abstract contract can be customized to change the `validatorsAndThreshold()` (static or dynamic).\n */\nabstract contract AbstractMessageIdMultisigIsm is AbstractMultisig {\n    using Message for bytes;\n    using MessageIdMultisigIsmMetadata for bytes;\n\n    // ============ Constants ============\n\n    /**\n     * @inheritdoc AbstractMultisig\n     */\n    function digest(\n        bytes calldata _metadata,\n        bytes calldata _message\n    ) internal pure override returns (bytes32) {\n        return\n            CheckpointLib.digest(\n                _message.origin(),\n                _metadata.originMerkleTreeHook(),\n                _metadata.root(),\n                _metadata.index(),\n                _message.id()\n            );\n    }\n\n    /**\n     * @inheritdoc AbstractMultisig\n     */\n    function signatureAt(\n        bytes calldata _metadata,\n        uint256 _index\n    ) internal pure virtual override returns (bytes calldata) {\n        return _metadata.signatureAt(_index);\n    }\n\n    /**\n     * @inheritdoc AbstractMultisig\n     */\n    function signatureCount(\n        bytes calldata _metadata\n    ) public pure override returns (uint256) {\n        return _metadata.signatureCount();\n    }\n}\n"},"contracts/isms/multisig/AbstractMultisigIsm.sol":{"content":"// SPDX-License-Identifier: MIT OR Apache-2.0\npragma solidity >=0.8.0;\n\n/*@@@@@@@       @@@@@@@@@\n @@@@@@@@@       @@@@@@@@@\n  @@@@@@@@@       @@@@@@@@@\n   @@@@@@@@@       @@@@@@@@@\n    @@@@@@@@@@@@@@@@@@@@@@@@@\n     @@@@@  HYPERLANE  @@@@@@@\n    @@@@@@@@@@@@@@@@@@@@@@@@@\n   @@@@@@@@@       @@@@@@@@@\n  @@@@@@@@@       @@@@@@@@@\n @@@@@@@@@       @@@@@@@@@\n@@@@@@@@@       @@@@@@@@*/\n\n// ============ External Imports ============\nimport {ECDSA} from \"@openzeppelin/contracts/utils/cryptography/ECDSA.sol\";\n\n// ============ Internal Imports ============\nimport {IMultisigIsm} from \"../../interfaces/isms/IMultisigIsm.sol\";\nimport {PackageVersioned} from \"../../PackageVersioned.sol\";\n\n/**\n * @title AbstractMultisig\n * @notice Manages per-domain m-of-n Validator sets\n * @dev See ./AbstractMerkleRootMultisigIsm.sol and ./AbstractMessageIdMultisigIsm.sol\n * for concrete implementations of `digest` and `signatureAt`.\n * @dev See ./StaticMultisigIsm.sol for concrete implementations.\n */\nabstract contract AbstractMultisig is PackageVersioned {\n    /**\n     * @notice Returns the digest to be used for signature verification.\n     * @param _metadata ABI encoded module metadata\n     * @param _message Formatted Hyperlane message (see Message.sol).\n     * @return digest The digest to be signed by validators\n     */\n    function digest(\n        bytes calldata _metadata,\n        bytes calldata _message\n    ) internal view virtual returns (bytes32);\n\n    /**\n     * @notice Returns the signature at a given index from the metadata.\n     * @param _metadata ABI encoded module metadata\n     * @param _index The index of the signature to return\n     * @return signature Packed encoding of signature (65 bytes)\n     */\n    function signatureAt(\n        bytes calldata _metadata,\n        uint256 _index\n    ) internal pure virtual returns (bytes calldata);\n\n    /**\n     * @notice Returns the number of signatures in the metadata.\n     * @param _metadata ABI encoded module metadata\n     * @return count The number of signatures\n     */\n    function signatureCount(\n        bytes calldata _metadata\n    ) public pure virtual returns (uint256);\n}\n\n/**\n * @title AbstractMultisigIsm\n * @notice Manages per-domain m-of-n Validator sets of AbstractMultisig that are used to verify\n * interchain messages.\n */\nabstract contract AbstractMultisigIsm is AbstractMultisig, IMultisigIsm {\n    // ============ Virtual Functions ============\n    // ======= OVERRIDE THESE TO IMPLEMENT =======\n\n    /**\n     * @notice Returns the set of validators responsible for verifying _message\n     * and the number of signatures required\n     * @dev Can change based on the content of _message\n     * @dev Signatures provided to `verify` must be consistent with validator ordering\n     * @param _message Hyperlane formatted interchain message\n     * @return validators The array of validator addresses\n     * @return threshold The number of validator signatures needed\n     */\n    function validatorsAndThreshold(\n        bytes calldata _message\n    ) public view virtual returns (address[] memory, uint8);\n\n    // ============ Public Functions ============\n\n    /**\n     * @notice Requires that m-of-n validators verify a merkle root,\n     * and verifies a merkle proof of `_message` against that root.\n     * @dev Optimization relies on the caller sorting signatures in the same order as validators.\n     * @dev Employs https://www.geeksforgeeks.org/two-pointers-technique/ to minimize gas usage.\n     * @param _metadata ABI encoded module metadata\n     * @param _message Formatted Hyperlane message (see Message.sol).\n     */\n    function verify(\n        bytes calldata _metadata,\n        bytes calldata _message\n    ) public view returns (bool) {\n        bytes32 _digest = digest(_metadata, _message);\n        (\n            address[] memory _validators,\n            uint8 _threshold\n        ) = validatorsAndThreshold(_message);\n        require(_threshold > 0, \"No MultisigISM threshold present for message\");\n\n        uint256 _validatorCount = _validators.length;\n        uint256 _validatorIndex = 0;\n        // Assumes that signatures are ordered by validator\n        for (uint256 i = 0; i < _threshold; ++i) {\n            address _signer = ECDSA.recover(_digest, signatureAt(_metadata, i));\n            // Loop through remaining validators until we find a match\n            while (\n                _validatorIndex < _validatorCount &&\n                _signer != _validators[_validatorIndex]\n            ) {\n                ++_validatorIndex;\n            }\n            // Fail if we never found a match\n            require(_validatorIndex < _validatorCount, \"!threshold\");\n            ++_validatorIndex;\n        }\n        return true;\n    }\n}\n"},"contracts/isms/multisig/AbstractWeightedMultisigIsm.sol":{"content":"// SPDX-License-Identifier: MIT OR Apache-2.0\npragma solidity >=0.8.0;\n\n/*@@@@@@@       @@@@@@@@@\n @@@@@@@@@       @@@@@@@@@\n  @@@@@@@@@       @@@@@@@@@\n   @@@@@@@@@       @@@@@@@@@\n    @@@@@@@@@@@@@@@@@@@@@@@@@\n     @@@@@  HYPERLANE  @@@@@@@\n    @@@@@@@@@@@@@@@@@@@@@@@@@\n   @@@@@@@@@       @@@@@@@@@\n  @@@@@@@@@       @@@@@@@@@\n @@@@@@@@@       @@@@@@@@@\n@@@@@@@@@       @@@@@@@@*/\n\n// ============ External Imports ============\nimport {ECDSA} from \"@openzeppelin/contracts/utils/cryptography/ECDSA.sol\";\nimport {Math} from \"@openzeppelin/contracts/utils/math/Math.sol\";\n\n// ============ Internal Imports ============\nimport {IInterchainSecurityModule} from \"../../interfaces/IInterchainSecurityModule.sol\";\nimport {IStaticWeightedMultisigIsm} from \"../../interfaces/isms/IWeightedMultisigIsm.sol\";\nimport {AbstractMultisig} from \"./AbstractMultisigIsm.sol\";\n\n/**\n * @title AbstractStaticWeightedMultisigIsm\n * @notice Manages per-domain m-of-n Validator sets with stake weights that are used to verify\n * interchain messages.\n */\nabstract contract AbstractStaticWeightedMultisigIsm is\n    AbstractMultisig,\n    IStaticWeightedMultisigIsm\n{\n    // ============ Constants ============\n\n    // total weight of all validators\n    uint96 public constant TOTAL_WEIGHT = 1e10;\n\n    /**\n     * @inheritdoc IStaticWeightedMultisigIsm\n     */\n    function validatorsAndThresholdWeight(\n        bytes calldata /* _message*/\n    ) public view virtual returns (ValidatorInfo[] memory, uint96);\n\n    /**\n     * @inheritdoc IInterchainSecurityModule\n     */\n    function verify(\n        bytes calldata _metadata,\n        bytes calldata _message\n    ) public view virtual returns (bool) {\n        bytes32 _digest = digest(_metadata, _message);\n        (\n            ValidatorInfo[] memory _validators,\n            uint96 _thresholdWeight\n        ) = validatorsAndThresholdWeight(_message);\n\n        require(\n            _thresholdWeight > 0 && _thresholdWeight <= TOTAL_WEIGHT,\n            \"Invalid threshold weight\"\n        );\n\n        uint256 _validatorCount = Math.min(\n            _validators.length,\n            signatureCount(_metadata)\n        );\n        uint256 _validatorIndex = 0;\n        uint96 _totalWeight = 0;\n\n        // assumes that signatures are ordered by validator\n        for (\n            uint256 signatureIndex = 0;\n            _totalWeight < _thresholdWeight && signatureIndex < _validatorCount;\n            ++signatureIndex\n        ) {\n            address _signer = ECDSA.recover(\n                _digest,\n                signatureAt(_metadata, signatureIndex)\n            );\n            // loop through remaining validators until we find a match\n            while (\n                _validatorIndex < _validatorCount &&\n                _signer != _validators[_validatorIndex].signingAddress\n            ) {\n                ++_validatorIndex;\n            }\n            // fail if we never found a match\n            require(_validatorIndex < _validatorCount, \"Invalid signer\");\n\n            // add the weight of the current validator\n            _totalWeight += _validators[_validatorIndex].weight;\n            ++_validatorIndex;\n        }\n        require(\n            _totalWeight >= _thresholdWeight,\n            \"Insufficient validator weight\"\n        );\n        return true;\n    }\n}\n"},"contracts/isms/multisig/StaticMultisigIsm.sol":{"content":"// SPDX-License-Identifier: MIT OR Apache-2.0\npragma solidity >=0.8.0;\n// ============ Internal Imports ============\n\nimport {IInterchainSecurityModule} from \"../../interfaces/IInterchainSecurityModule.sol\";\nimport {AbstractMultisigIsm} from \"./AbstractMultisigIsm.sol\";\nimport {AbstractMerkleRootMultisigIsm} from \"./AbstractMerkleRootMultisigIsm.sol\";\nimport {AbstractMessageIdMultisigIsm} from \"./AbstractMessageIdMultisigIsm.sol\";\nimport {MetaProxy} from \"../../libs/MetaProxy.sol\";\nimport {StaticThresholdAddressSetFactory} from \"../../libs/StaticAddressSetFactory.sol\";\n\n/**\n * @title AbstractMetaProxyMultisigIsm\n * @notice Manages per-domain m-of-n Validator set that is used\n * to verify interchain messages.\n */\nabstract contract AbstractMetaProxyMultisigIsm is AbstractMultisigIsm {\n    /**\n     * @inheritdoc AbstractMultisigIsm\n     */\n    function validatorsAndThreshold(\n        bytes calldata\n    ) public pure override returns (address[] memory, uint8) {\n        return abi.decode(MetaProxy.metadata(), (address[], uint8));\n    }\n}\n\n// solhint-disable no-empty-blocks\n\n/**\n * @title StaticMerkleRootMultisigIsm\n * @notice Manages per-domain m-of-n validator set that is used\n * to verify interchain messages using a merkle root signature quorum\n * and merkle proof of inclusion.\n */\ncontract StaticMerkleRootMultisigIsm is\n    AbstractMerkleRootMultisigIsm,\n    AbstractMetaProxyMultisigIsm\n{\n    uint8 public constant moduleType =\n        uint8(IInterchainSecurityModule.Types.MERKLE_ROOT_MULTISIG);\n}\n\n/**\n * @title StaticMessageIdMultisigIsm\n * @notice Manages per-domain m-of-n validator set that is used\n * to verify interchain messages using a message ID signature quorum.\n */\ncontract StaticMessageIdMultisigIsm is\n    AbstractMessageIdMultisigIsm,\n    AbstractMetaProxyMultisigIsm\n{\n    uint8 public constant moduleType =\n        uint8(IInterchainSecurityModule.Types.MESSAGE_ID_MULTISIG);\n}\n\n// solhint-enable no-empty-blocks\n\ncontract StaticMerkleRootMultisigIsmFactory is\n    StaticThresholdAddressSetFactory\n{\n    function _deployImplementation() internal override returns (address) {\n        return address(new StaticMerkleRootMultisigIsm());\n    }\n}\n\ncontract StaticMessageIdMultisigIsmFactory is StaticThresholdAddressSetFactory {\n    function _deployImplementation() internal override returns (address) {\n        return address(new StaticMessageIdMultisigIsm());\n    }\n}\n"},"contracts/isms/multisig/StorageMultisigIsm.sol":{"content":"// SPDX-License-Identifier: MIT OR Apache-2.0\npragma solidity >=0.8.0;\n\n// ============ Internal Imports ============\nimport {AbstractMultisigIsm} from \"./AbstractMultisigIsm.sol\";\nimport {AbstractMerkleRootMultisigIsm} from \"./AbstractMerkleRootMultisigIsm.sol\";\nimport {AbstractMessageIdMultisigIsm} from \"./AbstractMessageIdMultisigIsm.sol\";\nimport {IInterchainSecurityModule} from \"../../interfaces/IInterchainSecurityModule.sol\";\nimport {IThresholdAddressFactory} from \"../../interfaces/IThresholdAddressFactory.sol\";\nimport {MinimalProxy} from \"../../libs/MinimalProxy.sol\";\nimport {PackageVersioned} from \"../../PackageVersioned.sol\";\n\n// ============ External Imports ============\nimport {Ownable2StepUpgradeable} from \"@openzeppelin/contracts-upgradeable/access/Ownable2StepUpgradeable.sol\";\n\nabstract contract AbstractStorageMultisigIsm is\n    AbstractMultisigIsm,\n    Ownable2StepUpgradeable\n{\n    address[] public validators;\n    uint8 public threshold;\n\n    event ValidatorsAndThresholdSet(address[] validators, uint8 threshold);\n\n    constructor(\n        address[] memory _validators,\n        uint8 _threshold\n    ) Ownable2StepUpgradeable() {\n        validators = _validators;\n        threshold = _threshold;\n        _disableInitializers();\n    }\n\n    function initialize(\n        address _owner,\n        address[] memory _validators,\n        uint8 _threshold\n    ) external initializer {\n        __Ownable2Step_init();\n        setValidatorsAndThreshold(_validators, _threshold);\n        _transferOwnership(_owner);\n    }\n\n    function setValidatorsAndThreshold(\n        address[] memory _validators,\n        uint8 _threshold\n    ) public onlyOwner {\n        require(\n            0 < _threshold && _threshold <= _validators.length,\n            \"Invalid threshold\"\n        );\n        validators = _validators;\n        threshold = _threshold;\n        emit ValidatorsAndThresholdSet(_validators, _threshold);\n    }\n\n    function validatorsAndThreshold(\n        bytes calldata /* _message */\n    ) public view override returns (address[] memory, uint8) {\n        return (validators, threshold);\n    }\n}\n\ncontract StorageMerkleRootMultisigIsm is\n    AbstractMerkleRootMultisigIsm,\n    AbstractStorageMultisigIsm\n{\n    uint8 public constant moduleType =\n        uint8(IInterchainSecurityModule.Types.MERKLE_ROOT_MULTISIG);\n\n    constructor(\n        address[] memory _validators,\n        uint8 _threshold\n    ) AbstractStorageMultisigIsm(_validators, _threshold) {}\n}\n\ncontract StorageMessageIdMultisigIsm is\n    AbstractMessageIdMultisigIsm,\n    AbstractStorageMultisigIsm\n{\n    uint8 public constant moduleType =\n        uint8(IInterchainSecurityModule.Types.MESSAGE_ID_MULTISIG);\n\n    constructor(\n        address[] memory _validators,\n        uint8 _threshold\n    ) AbstractStorageMultisigIsm(_validators, _threshold) {}\n}\n\nabstract contract StorageMultisigIsmFactory is\n    IThresholdAddressFactory,\n    PackageVersioned\n{\n    /**\n     * @notice Emitted when a multisig module is deployed\n     * @param module The deployed ISM\n     */\n    event ModuleDeployed(address module);\n\n    // ============ External Functions ============\n    function deploy(\n        address[] calldata _validators,\n        uint8 _threshold\n    ) external returns (address ism) {\n        ism = MinimalProxy.create(implementation());\n        emit ModuleDeployed(ism);\n        AbstractStorageMultisigIsm(ism).initialize(\n            msg.sender,\n            _validators,\n            _threshold\n        );\n    }\n\n    function implementation() public view virtual returns (address);\n}\n\ncontract StorageMerkleRootMultisigIsmFactory is StorageMultisigIsmFactory {\n    address internal immutable _implementation;\n\n    constructor() {\n        _implementation = address(\n            new StorageMerkleRootMultisigIsm(new address[](0), 0)\n        );\n    }\n\n    function implementation() public view override returns (address) {\n        return _implementation;\n    }\n}\n\ncontract StorageMessageIdMultisigIsmFactory is StorageMultisigIsmFactory {\n    address internal immutable _implementation;\n\n    constructor() {\n        _implementation = address(\n            new StorageMessageIdMultisigIsm(new address[](0), 0)\n        );\n    }\n\n    function implementation() public view override returns (address) {\n        return _implementation;\n    }\n}\n"},"contracts/isms/multisig/ValidatorAnnounce.sol":{"content":"// SPDX-License-Identifier: MIT OR Apache-2.0\npragma solidity >=0.8.0;\n\n// ============ Internal Imports ============\nimport {IValidatorAnnounce} from \"../../interfaces/IValidatorAnnounce.sol\";\nimport {TypeCasts} from \"../../libs/TypeCasts.sol\";\nimport {MailboxClient} from \"../../client/MailboxClient.sol\";\n\n// ============ External Imports ============\nimport {EnumerableSet} from \"@openzeppelin/contracts/utils/structs/EnumerableSet.sol\";\nimport {ECDSA} from \"@openzeppelin/contracts/utils/cryptography/ECDSA.sol\";\n\n/**\n * @title ValidatorAnnounce\n * @notice Stores the location(s) of validator signed checkpoints\n */\ncontract ValidatorAnnounce is MailboxClient, IValidatorAnnounce {\n    // ============ Libraries ============\n\n    using EnumerableSet for EnumerableSet.AddressSet;\n    using TypeCasts for address;\n\n    // ============ Public Storage ============\n\n    // The set of validators that have announced\n    EnumerableSet.AddressSet private validators;\n    // Storage locations of validator signed checkpoints\n    mapping(address validator => string[] storageLocations)\n        private storageLocations;\n    // Mapping to prevent the same announcement from being registered\n    // multiple times.\n    mapping(bytes32 replayID => bool isAnnounced) private replayProtection;\n\n    // ============ Events ============\n\n    /**\n     * @notice Emitted when a new validator announcement is made\n     * @param validator The address of the announcing validator\n     * @param storageLocation The storage location being announced\n     */\n    event ValidatorAnnouncement(\n        address indexed validator,\n        string storageLocation\n    );\n\n    // ============ Constructor ============\n\n    constructor(address _mailbox) MailboxClient(_mailbox) {}\n\n    // ============ External Functions ============\n\n    /**\n     * @notice Announces a validator signature storage location\n     * @param _storageLocation Information encoding the location of signed\n     * checkpoints\n     * @param _signature The signed validator announcement\n     * @return True upon success\n     */\n    function announce(\n        address _validator,\n        string calldata _storageLocation,\n        bytes calldata _signature\n    ) external returns (bool) {\n        // Ensure that the same storage metadata isn't being announced\n        // multiple times for the same validator.\n        bytes32 _replayId = keccak256(\n            abi.encodePacked(_validator, _storageLocation)\n        );\n        require(replayProtection[_replayId] == false, \"replay\");\n        replayProtection[_replayId] = true;\n\n        // Verify that the signature matches the declared validator\n        bytes32 _announcementDigest = getAnnouncementDigest(_storageLocation);\n        address _signer = ECDSA.recover(_announcementDigest, _signature);\n        require(_signer == _validator, \"!signature\");\n\n        // Store the announcement\n        if (!validators.contains(_validator)) {\n            validators.add(_validator);\n        }\n        storageLocations[_validator].push(_storageLocation);\n        emit ValidatorAnnouncement(_validator, _storageLocation);\n        return true;\n    }\n\n    /**\n     * @notice Returns a list of all announced storage locations\n     * @param _validators The list of validators to get registrations for\n     * @return A list of registered storage metadata\n     */\n    function getAnnouncedStorageLocations(\n        address[] calldata _validators\n    ) external view returns (string[][] memory) {\n        string[][] memory _metadata = new string[][](_validators.length);\n        for (uint256 i = 0; i < _validators.length; i++) {\n            _metadata[i] = storageLocations[_validators[i]];\n        }\n        return _metadata;\n    }\n\n    /// @notice Returns a list of validators that have made announcements\n    function getAnnouncedValidators() external view returns (address[] memory) {\n        return validators.values();\n    }\n\n    /**\n     * @notice Returns the digest validators are expected to sign when signing announcements.\n     * @param _storageLocation Storage location string.\n     * @return The digest of the announcement.\n     */\n    function getAnnouncementDigest(\n        string memory _storageLocation\n    ) public view returns (bytes32) {\n        return\n            ECDSA.toEthSignedMessageHash(\n                keccak256(abi.encodePacked(_domainHash(), _storageLocation))\n            );\n    }\n\n    /**\n     * @notice Returns the domain separator used in validator announcements.\n     */\n    function _domainHash() internal view returns (bytes32) {\n        return\n            keccak256(\n                abi.encodePacked(\n                    localDomain,\n                    address(mailbox).addressToBytes32(),\n                    \"HYPERLANE_ANNOUNCEMENT\"\n                )\n            );\n    }\n}\n"},"contracts/isms/multisig/WeightedMultisigIsm.sol":{"content":"// SPDX-License-Identifier: MIT OR Apache-2.0\npragma solidity >=0.8.0;\n\n/*@@@@@@@       @@@@@@@@@\n @@@@@@@@@       @@@@@@@@@\n  @@@@@@@@@       @@@@@@@@@\n   @@@@@@@@@       @@@@@@@@@\n    @@@@@@@@@@@@@@@@@@@@@@@@@\n     @@@@@  HYPERLANE  @@@@@@@\n    @@@@@@@@@@@@@@@@@@@@@@@@@\n   @@@@@@@@@       @@@@@@@@@\n  @@@@@@@@@       @@@@@@@@@\n @@@@@@@@@       @@@@@@@@@\n@@@@@@@@@       @@@@@@@@*/\n\nimport {IInterchainSecurityModule} from \"../../interfaces/IInterchainSecurityModule.sol\";\nimport {AbstractMerkleRootMultisigIsm} from \"./AbstractMerkleRootMultisigIsm.sol\";\nimport {AbstractMessageIdMultisigIsm} from \"./AbstractMessageIdMultisigIsm.sol\";\nimport {AbstractStaticWeightedMultisigIsm} from \"./AbstractWeightedMultisigIsm.sol\";\nimport {StaticWeightedValidatorSetFactory} from \"../../libs/StaticWeightedValidatorSetFactory.sol\";\nimport {MetaProxy} from \"../../libs/MetaProxy.sol\";\n\nabstract contract AbstractMetaProxyWeightedMultisigIsm is\n    AbstractStaticWeightedMultisigIsm\n{\n    /**\n     * @inheritdoc AbstractStaticWeightedMultisigIsm\n     */\n    function validatorsAndThresholdWeight(\n        bytes calldata /* _message*/\n    ) public pure override returns (ValidatorInfo[] memory, uint96) {\n        return abi.decode(MetaProxy.metadata(), (ValidatorInfo[], uint96));\n    }\n}\n\ncontract StaticMerkleRootWeightedMultisigIsm is\n    AbstractMerkleRootMultisigIsm,\n    AbstractMetaProxyWeightedMultisigIsm\n{\n    uint8 public constant moduleType =\n        uint8(IInterchainSecurityModule.Types.WEIGHTED_MERKLE_ROOT_MULTISIG);\n}\n\ncontract StaticMessageIdWeightedMultisigIsm is\n    AbstractMessageIdMultisigIsm,\n    AbstractMetaProxyWeightedMultisigIsm\n{\n    uint8 public constant moduleType =\n        uint8(IInterchainSecurityModule.Types.WEIGHTED_MESSAGE_ID_MULTISIG);\n}\n\ncontract StaticMerkleRootWeightedMultisigIsmFactory is\n    StaticWeightedValidatorSetFactory\n{\n    function _deployImplementation() internal override returns (address) {\n        return address(new StaticMerkleRootWeightedMultisigIsm());\n    }\n}\n\ncontract StaticMessageIdWeightedMultisigIsmFactory is\n    StaticWeightedValidatorSetFactory\n{\n    function _deployImplementation() internal override returns (address) {\n        return address(new StaticMessageIdWeightedMultisigIsm());\n    }\n}\n"},"contracts/isms/NoopIsm.sol":{"content":"// SPDX-License-Identifier: MIT OR Apache-2.0\npragma solidity >=0.8.0;\n\nimport {IInterchainSecurityModule} from \"../interfaces/IInterchainSecurityModule.sol\";\nimport {PackageVersioned} from \"../PackageVersioned.sol\";\n\ncontract NoopIsm is IInterchainSecurityModule, PackageVersioned {\n    uint8 public constant override moduleType = uint8(Types.NULL);\n\n    function verify(\n        bytes calldata,\n        bytes calldata\n    ) public pure override returns (bool) {\n        return true;\n    }\n}\n"},"contracts/isms/PausableIsm.sol":{"content":"// SPDX-License-Identifier: MIT OR Apache-2.0\npragma solidity >=0.8.0;\n\n// ============ External Imports ============\nimport {Pausable} from \"@openzeppelin/contracts/security/Pausable.sol\";\nimport {Ownable} from \"@openzeppelin/contracts/access/Ownable.sol\";\n\n// ============ Internal Imports ============\nimport {IInterchainSecurityModule} from \"../interfaces/IInterchainSecurityModule.sol\";\nimport {PackageVersioned} from \"../PackageVersioned.sol\";\n\ncontract PausableIsm is\n    IInterchainSecurityModule,\n    Ownable,\n    Pausable,\n    PackageVersioned\n{\n    uint8 public constant override moduleType = uint8(Types.NULL);\n\n    constructor(address owner) Ownable() Pausable() {\n        _transferOwnership(owner);\n    }\n\n    /**\n     * @inheritdoc IInterchainSecurityModule\n     * @dev Reverts when paused, otherwise returns `true`.\n     */\n    function verify(\n        bytes calldata,\n        bytes calldata\n    ) external view whenNotPaused returns (bool) {\n        return true;\n    }\n\n    function pause() external onlyOwner {\n        _pause();\n    }\n\n    function unpause() external onlyOwner {\n        _unpause();\n    }\n}\n"},"contracts/isms/routing/AbstractRoutingIsm.sol":{"content":"// SPDX-License-Identifier: MIT OR Apache-2.0\npragma solidity >=0.8.0;\n\n// ============ Internal Imports ============\nimport {IInterchainSecurityModule} from \"../../interfaces/IInterchainSecurityModule.sol\";\nimport {IRoutingIsm} from \"../../interfaces/isms/IRoutingIsm.sol\";\n\n/**\n * @title RoutingIsm\n */\nabstract contract AbstractRoutingIsm is IRoutingIsm {\n    // ============ Constants ============\n\n    // solhint-disable-next-line const-name-snakecase\n    uint8 public constant moduleType =\n        uint8(IInterchainSecurityModule.Types.ROUTING);\n\n    // ============ Virtual Functions ============\n    // ======= OVERRIDE THESE TO IMPLEMENT =======\n\n    /**\n     * @notice Returns the ISM responsible for verifying _message\n     * @dev Can change based on the content of _message\n     * @param _message Formatted Hyperlane message (see Message.sol).\n     * @return module The ISM to use to verify _message\n     */\n    function route(\n        bytes calldata _message\n    ) public view virtual returns (IInterchainSecurityModule);\n\n    // ============ Public Functions ============\n\n    /**\n     * @notice Routes _metadata and _message to the correct ISM\n     * @param _metadata ABI encoded module metadata\n     * @param _message Formatted Hyperlane message (see Message.sol).\n     */\n    function verify(\n        bytes calldata _metadata,\n        bytes calldata _message\n    ) public returns (bool) {\n        return route(_message).verify(_metadata, _message);\n    }\n}\n"},"contracts/isms/routing/DefaultFallbackRoutingIsm.sol":{"content":"// SPDX-License-Identifier: MIT OR Apache-2.0\npragma solidity >=0.8.0;\n\n// ============ Internal Imports ============\nimport {DomainRoutingIsm} from \"./DomainRoutingIsm.sol\";\nimport {IInterchainSecurityModule} from \"../../interfaces/IInterchainSecurityModule.sol\";\nimport {EnumerableMapExtended} from \"../../libs/EnumerableMapExtended.sol\";\nimport {TypeCasts} from \"../../libs/TypeCasts.sol\";\nimport {MailboxClient} from \"../../client/MailboxClient.sol\";\n\n// ============ External Imports ============\nimport {Address} from \"@openzeppelin/contracts/utils/Address.sol\";\n\ncontract DefaultFallbackRoutingIsm is DomainRoutingIsm, MailboxClient {\n    using EnumerableMapExtended for EnumerableMapExtended.UintToBytes32Map;\n    using Address for address;\n    using TypeCasts for bytes32;\n\n    constructor(address _mailbox) MailboxClient(_mailbox) {}\n\n    function module(\n        uint32 origin\n    ) public view override returns (IInterchainSecurityModule) {\n        (bool contained, bytes32 _module) = _modules.tryGet(origin);\n        if (contained) {\n            return IInterchainSecurityModule(_module.bytes32ToAddress());\n        } else {\n            return mailbox.defaultIsm();\n        }\n    }\n}\n"},"contracts/isms/routing/DomainRoutingIsm.sol":{"content":"// SPDX-License-Identifier: MIT OR Apache-2.0\npragma solidity >=0.8.0;\n\n// ============ External Imports ============\nimport {Address} from \"@openzeppelin/contracts/utils/Address.sol\";\nimport {OwnableUpgradeable} from \"@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol\";\nimport {Strings} from \"@openzeppelin/contracts/utils/Strings.sol\";\n\n// ============ Internal Imports ============\nimport {AbstractRoutingIsm} from \"./AbstractRoutingIsm.sol\";\nimport {IInterchainSecurityModule} from \"../../interfaces/IInterchainSecurityModule.sol\";\nimport {Message} from \"../../libs/Message.sol\";\nimport {TypeCasts} from \"../../libs/TypeCasts.sol\";\nimport {EnumerableMapExtended} from \"../../libs/EnumerableMapExtended.sol\";\nimport {PackageVersioned} from \"../../PackageVersioned.sol\";\n\n/**\n * @title DomainRoutingIsm\n */\ncontract DomainRoutingIsm is\n    AbstractRoutingIsm,\n    OwnableUpgradeable,\n    PackageVersioned\n{\n    using EnumerableMapExtended for EnumerableMapExtended.UintToBytes32Map;\n    using Message for bytes;\n    using TypeCasts for bytes32;\n    using TypeCasts for address;\n    using Address for address;\n    using Strings for uint32;\n\n    // ============ Mutable Storage ============\n    EnumerableMapExtended.UintToBytes32Map internal _modules;\n\n    // ============ External Functions ============\n\n    /**\n     * @param _owner The owner of the contract.\n     */\n    function initialize(address _owner) public initializer {\n        __Ownable_init();\n        _transferOwnership(_owner);\n    }\n\n    /**\n     * @notice Sets the ISMs to be used for the specified origin domains\n     * @param _owner The owner of the contract.\n     * @param _domains The origin domains\n     * @param __modules The ISMs to use to verify messages\n     */\n    function initialize(\n        address _owner,\n        uint32[] calldata _domains,\n        IInterchainSecurityModule[] calldata __modules\n    ) public initializer {\n        __Ownable_init();\n        require(_domains.length == __modules.length, \"length mismatch\");\n        uint256 _length = _domains.length;\n        for (uint256 i = 0; i < _length; ++i) {\n            _set(_domains[i], address(__modules[i]));\n        }\n        _transferOwnership(_owner);\n    }\n\n    /**\n     * @notice Sets the ISM to be used for the specified origin domain\n     * @param _domain The origin domain\n     * @param _module The ISM to use to verify messages\n     */\n    function set(\n        uint32 _domain,\n        IInterchainSecurityModule _module\n    ) external onlyOwner {\n        _set(_domain, address(_module));\n    }\n\n    /**\n     * @notice Removes the specified origin domain\n     * @param _domain The origin domain\n     */\n    function remove(uint32 _domain) external onlyOwner {\n        _remove(_domain);\n    }\n\n    function domains() external view returns (uint256[] memory) {\n        return _modules.keys();\n    }\n\n    function module(\n        uint32 origin\n    ) public view virtual returns (IInterchainSecurityModule) {\n        (bool contained, bytes32 _module) = _modules.tryGet(origin);\n        if (contained) {\n            return IInterchainSecurityModule(_module.bytes32ToAddress());\n        }\n        revert(_originNotFoundError(origin));\n    }\n\n    // ============ Public Functions ============\n    /**\n     * @notice Returns the ISM responsible for verifying _message\n     * @dev Can change based on the content of _message\n     * @param _message Formatted Hyperlane message (see Message.sol).\n     * @return module The ISM to use to verify _message\n     */\n    function route(\n        bytes calldata _message\n    ) public view override returns (IInterchainSecurityModule) {\n        return module(_message.origin());\n    }\n\n    // ============ Internal Functions ============\n\n    /**\n     * @notice Removes the specified origin domain's ISM\n     * @param _domain The origin domain\n     */\n    function _remove(uint32 _domain) internal {\n        require(_modules.remove(_domain), _originNotFoundError(_domain));\n    }\n\n    function _originNotFoundError(\n        uint32 _origin\n    ) internal pure returns (string memory) {\n        return string.concat(\"No ISM found for origin: \", _origin.toString());\n    }\n\n    /**\n     * @notice Sets the ISM to be used for the specified origin domain\n     * @param _domain The origin domain\n     * @param _module The ISM to use to verify messages\n     */\n    function _set(uint32 _domain, address _module) internal {\n        require(_module.isContract(), \"ISM must be a contract\");\n        _modules.set(_domain, _module.addressToBytes32());\n    }\n}\n"},"contracts/isms/routing/DomainRoutingIsmFactory.sol":{"content":"// SPDX-License-Identifier: MIT OR Apache-2.0\npragma solidity >=0.8.0;\n\n// ============ Internal Imports ============\nimport {DomainRoutingIsm} from \"./DomainRoutingIsm.sol\";\nimport {IInterchainSecurityModule} from \"../../interfaces/IInterchainSecurityModule.sol\";\nimport {MinimalProxy} from \"../../libs/MinimalProxy.sol\";\nimport {PackageVersioned} from \"../../PackageVersioned.sol\";\n\nabstract contract AbstractDomainRoutingIsmFactory is PackageVersioned {\n    /**\n     * @notice Emitted when a routing module is deployed\n     * @param module The deployed ISM\n     */\n    event ModuleDeployed(DomainRoutingIsm module);\n\n    // ============ External Functions ============\n\n    /**\n     * @notice Deploys and initializes a DomainRoutingIsm using a minimal proxy\n     * @param _owner The owner to set on the ISM\n     * @param _domains The origin domains\n     * @param _modules The ISMs to use to verify messages\n     */\n    function deploy(\n        address _owner,\n        uint32[] calldata _domains,\n        IInterchainSecurityModule[] calldata _modules\n    ) external returns (DomainRoutingIsm) {\n        DomainRoutingIsm _ism = DomainRoutingIsm(\n            MinimalProxy.create(implementation())\n        );\n        emit ModuleDeployed(_ism);\n        _ism.initialize(_owner, _domains, _modules);\n        return _ism;\n    }\n\n    function implementation() public view virtual returns (address);\n}\n\n/**\n * @title DomainRoutingIsmFactory\n */\ncontract DomainRoutingIsmFactory is AbstractDomainRoutingIsmFactory {\n    // ============ Immutables ============\n    address internal immutable _implementation;\n\n    constructor() {\n        _implementation = address(new DomainRoutingIsm());\n    }\n\n    function implementation() public view override returns (address) {\n        return _implementation;\n    }\n}\n"},"contracts/isms/TrustedRelayerIsm.sol":{"content":"// SPDX-License-Identifier: MIT OR Apache-2.0\npragma solidity >=0.8.0;\n\n// ============ Internal Imports ============\nimport {IInterchainSecurityModule} from \"../interfaces/IInterchainSecurityModule.sol\";\nimport {Address} from \"@openzeppelin/contracts/utils/Address.sol\";\nimport {Message} from \"../libs/Message.sol\";\nimport {Mailbox} from \"../Mailbox.sol\";\nimport {PackageVersioned} from \"../PackageVersioned.sol\";\n\ncontract TrustedRelayerIsm is IInterchainSecurityModule, PackageVersioned {\n    using Message for bytes;\n\n    uint8 public immutable moduleType = uint8(Types.NULL);\n    Mailbox public immutable mailbox;\n    address public immutable trustedRelayer;\n\n    constructor(address _mailbox, address _trustedRelayer) {\n        require(\n            _trustedRelayer != address(0),\n            \"TrustedRelayerIsm: invalid relayer\"\n        );\n        require(\n            Address.isContract(_mailbox),\n            \"TrustedRelayerIsm: invalid mailbox\"\n        );\n        mailbox = Mailbox(_mailbox);\n        trustedRelayer = _trustedRelayer;\n    }\n\n    function verify(\n        bytes calldata,\n        bytes calldata message\n    ) external view returns (bool) {\n        return mailbox.processor(message.id()) == trustedRelayer;\n    }\n}\n"},"contracts/isms/warp-route/AmountRoutingIsm.sol":{"content":"// SPDX-License-Identifier: MIT OR Apache-2.0\npragma solidity >=0.8.0;\n\n// ============ Internal Imports ============\nimport {IInterchainSecurityModule} from \"../../interfaces/IInterchainSecurityModule.sol\";\nimport {AmountPartition} from \"../../token/libs/AmountPartition.sol\";\nimport {AbstractRoutingIsm} from \"../routing/AbstractRoutingIsm.sol\";\n\n/**\n * @title AmountRoutingIsm\n */\ncontract AmountRoutingIsm is AmountPartition, AbstractRoutingIsm {\n    constructor(\n        address _lowerIsm,\n        address _upperIsm,\n        uint256 _threshold\n    ) AmountPartition(_lowerIsm, _upperIsm, _threshold) {}\n\n    // ============ Public Functions ============\n    /**\n     * @notice Returns the ISM responsible for verifying _message\n     * @dev Routes to upperISM ISM if amount > threshold, otherwise lowerISM ISM.\n     * @param _message Formatted Hyperlane message (see Message.sol).\n     * @return module The ISM to use to verify _message\n     */\n    function route(\n        bytes calldata _message\n    ) public view override returns (IInterchainSecurityModule) {\n        return IInterchainSecurityModule(_partition(_message));\n    }\n}\n"},"contracts/isms/warp-route/RateLimitedIsm.sol":{"content":"// SPDX-License-Identifier: MIT OR Apache-2.0\npragma solidity >=0.8.0;\n\n// ============ Internal Imports ============\nimport {IInterchainSecurityModule} from \"../../interfaces/IInterchainSecurityModule.sol\";\nimport {MailboxClient} from \"../../client/MailboxClient.sol\";\nimport {RateLimited} from \"../../libs/RateLimited.sol\";\nimport {Message} from \"../../libs/Message.sol\";\nimport {TokenMessage} from \"../../token/libs/TokenMessage.sol\";\n\ncontract RateLimitedIsm is\n    MailboxClient,\n    RateLimited,\n    IInterchainSecurityModule\n{\n    using Message for bytes;\n    using TokenMessage for bytes;\n\n    address public immutable recipient;\n\n    mapping(bytes32 messageId => bool validated) public messageValidated;\n\n    modifier validateMessageOnce(bytes calldata _message) {\n        bytes32 messageId = _message.id();\n        require(!messageValidated[messageId], \"MessageAlreadyValidated\");\n        messageValidated[messageId] = true;\n        _;\n    }\n\n    modifier onlyRecipient(bytes calldata _message) {\n        require(_message.recipientAddress() == recipient, \"InvalidRecipient\");\n        _;\n    }\n\n    constructor(\n        address _mailbox,\n        uint256 _maxCapacity,\n        address _recipient\n    ) MailboxClient(_mailbox) RateLimited(_maxCapacity) {\n        recipient = _recipient;\n    }\n\n    /// @inheritdoc IInterchainSecurityModule\n    function moduleType() external pure returns (uint8) {\n        return uint8(IInterchainSecurityModule.Types.NULL);\n    }\n\n    /**\n     * Verify a message, rate limit, and increment the sender's limit.\n     * @dev ensures that this gets called by the Mailbox\n     */\n    function verify(\n        bytes calldata,\n        bytes calldata _message\n    )\n        external\n        onlyRecipient(_message)\n        validateMessageOnce(_message)\n        returns (bool)\n    {\n        require(_isDelivered(_message.id()), \"InvalidDeliveredMessage\");\n\n        uint256 newAmount = _message.body().amount();\n        _validateAndConsumeFilledLevel(newAmount);\n\n        return true;\n    }\n}\n"},"contracts/libs/CctpMessage.sol":{"content":"/*\n * Copyright (c) 2022, Circle Internet Financial Limited.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npragma solidity >=0.8.0;\n\nimport {TypedMemView} from \"./TypedMemView.sol\";\n\n// @dev CCTP Message version 1\n// @dev copied from https://github.com/circlefin/evm-cctp-contracts/blob/release-2025-03-11T143015/src/messages/Message.sol\n\n/**\n * @title Message Library\n * @notice Library for formatted messages used by Relayer and Receiver.\n *\n * @dev The message body is dynamically-sized to support custom message body\n * formats. Other fields must be fixed-size to avoid hash collisions.\n * Each other input value has an explicit type to guarantee fixed-size.\n * Padding: uintNN fields are left-padded, and bytesNN fields are right-padded.\n *\n * Field                 Bytes      Type       Index\n * version               4          uint32     0\n * sourceDomain          4          uint32     4\n * destinationDomain     4          uint32     8\n * nonce                 8          uint64     12\n * sender                32         bytes32    20\n * recipient             32         bytes32    52\n * destinationCaller     32         bytes32    84\n * messageBody           dynamic    bytes      116\n *\n **/\nlibrary CctpMessage {\n    using TypedMemView for bytes;\n    using TypedMemView for bytes29;\n\n    // Indices of each field in message\n    uint8 private constant VERSION_INDEX = 0;\n    uint8 private constant SOURCE_DOMAIN_INDEX = 4;\n    uint8 private constant DESTINATION_DOMAIN_INDEX = 8;\n    uint8 private constant NONCE_INDEX = 12;\n    uint8 private constant SENDER_INDEX = 20;\n    uint8 private constant RECIPIENT_INDEX = 52;\n    uint8 private constant DESTINATION_CALLER_INDEX = 84;\n    uint8 private constant MESSAGE_BODY_INDEX = 116;\n\n    /**\n     * @notice Returns formatted (packed) message with provided fields\n     * @param _msgVersion the version of the message format\n     * @param _msgSourceDomain Domain of home chain\n     * @param _msgDestinationDomain Domain of destination chain\n     * @param _msgNonce Destination-specific nonce\n     * @param _msgSender Address of sender on source chain as bytes32\n     * @param _msgRecipient Address of recipient on destination chain as bytes32\n     * @param _msgDestinationCaller Address of caller on destination chain as bytes32\n     * @param _msgRawBody Raw bytes of message body\n     * @return Formatted message\n     **/\n    function _formatMessage(\n        uint32 _msgVersion,\n        uint32 _msgSourceDomain,\n        uint32 _msgDestinationDomain,\n        uint64 _msgNonce,\n        bytes32 _msgSender,\n        bytes32 _msgRecipient,\n        bytes32 _msgDestinationCaller,\n        bytes memory _msgRawBody\n    ) internal pure returns (bytes memory) {\n        return\n            abi.encodePacked(\n                _msgVersion,\n                _msgSourceDomain,\n                _msgDestinationDomain,\n                _msgNonce,\n                _msgSender,\n                _msgRecipient,\n                _msgDestinationCaller,\n                _msgRawBody\n            );\n    }\n\n    // @notice Returns _message's version field\n    function _version(bytes29 _message) internal pure returns (uint32) {\n        return uint32(_message.indexUint(VERSION_INDEX, 4));\n    }\n\n    // @notice Returns _message's sourceDomain field\n    function _sourceDomain(bytes29 _message) internal pure returns (uint32) {\n        return uint32(_message.indexUint(SOURCE_DOMAIN_INDEX, 4));\n    }\n\n    // @notice Returns _message's destinationDomain field\n    function _destinationDomain(\n        bytes29 _message\n    ) internal pure returns (uint32) {\n        return uint32(_message.indexUint(DESTINATION_DOMAIN_INDEX, 4));\n    }\n\n    // @notice Returns _message's nonce field\n    function _nonce(bytes29 _message) internal pure returns (uint64) {\n        return uint64(_message.indexUint(NONCE_INDEX, 8));\n    }\n\n    // @notice Returns _message's sender field\n    function _sender(bytes29 _message) internal pure returns (bytes32) {\n        return _message.index(SENDER_INDEX, 32);\n    }\n\n    // @notice Returns _message's recipient field\n    function _recipient(bytes29 _message) internal pure returns (bytes32) {\n        return _message.index(RECIPIENT_INDEX, 32);\n    }\n\n    // @notice Returns _message's destinationCaller field\n    function _destinationCaller(\n        bytes29 _message\n    ) internal pure returns (bytes32) {\n        return _message.index(DESTINATION_CALLER_INDEX, 32);\n    }\n\n    // @notice Returns _message's messageBody field\n    function _messageBody(bytes29 _message) internal pure returns (bytes29) {\n        return\n            _message.slice(\n                MESSAGE_BODY_INDEX,\n                _message.len() - MESSAGE_BODY_INDEX,\n                0\n            );\n    }\n\n    /**\n     * @notice converts address to bytes32 (alignment preserving cast.)\n     * @param addr the address to convert to bytes32\n     */\n    function addressToBytes32(address addr) external pure returns (bytes32) {\n        return bytes32(uint256(uint160(addr)));\n    }\n\n    /**\n     * @notice converts bytes32 to address (alignment preserving cast.)\n     * @dev Warning: it is possible to have different input values _buf map to the same address.\n     * For use cases where this is not acceptable, validate that the first 12 bytes of _buf are zero-padding.\n     * @param _buf the bytes32 to convert to address\n     */\n    function bytes32ToAddress(bytes32 _buf) public pure returns (address) {\n        return address(uint160(uint256(_buf)));\n    }\n\n    /**\n     * @notice Reverts if message is malformed or incorrect length\n     * @param _message The message as bytes29\n     */\n    function _validateMessageFormat(bytes29 _message) internal pure {\n        require(_message.isValid(), \"Malformed message\");\n        require(\n            _message.len() >= MESSAGE_BODY_INDEX,\n            \"Invalid message: too short\"\n        );\n    }\n}\n\n// @dev copied from https://raw.githubusercontent.com/circlefin/evm-cctp-contracts/refs/tags/release-2025-03-11T143015/src/messages/BurnMessage.sol\n\n/**\n * @title BurnMessage Library\n * @notice Library for formatted BurnMessages used by TokenMessenger.\n * @dev BurnMessage format:\n * Field                 Bytes      Type       Index\n * version               4          uint32     0\n * burnToken             32         bytes32    4\n * mintRecipient         32         bytes32    36\n * amount                32         uint256    68\n * messageSender         32         bytes32    100\n **/\nlibrary BurnMessage {\n    using TypedMemView for bytes;\n    using TypedMemView for bytes29;\n\n    uint8 private constant VERSION_INDEX = 0;\n    uint8 private constant VERSION_LEN = 4;\n    uint8 private constant BURN_TOKEN_INDEX = 4;\n    uint8 private constant BURN_TOKEN_LEN = 32;\n    uint8 private constant MINT_RECIPIENT_INDEX = 36;\n    uint8 private constant MINT_RECIPIENT_LEN = 32;\n    uint8 private constant AMOUNT_INDEX = 68;\n    uint8 private constant AMOUNT_LEN = 32;\n    uint8 private constant MSG_SENDER_INDEX = 100;\n    uint8 private constant MSG_SENDER_LEN = 32;\n    // 4 byte version + 32 bytes burnToken + 32 bytes mintRecipient + 32 bytes amount + 32 bytes messageSender\n    uint8 private constant BURN_MESSAGE_LEN = 132;\n\n    /**\n     * @notice Formats Burn message\n     * @param _version The message body version\n     * @param _burnToken The burn token address on source domain as bytes32\n     * @param _mintRecipient The mint recipient address as bytes32\n     * @param _amount The burn amount\n     * @param _messageSender The message sender\n     * @return Burn formatted message.\n     */\n    function _formatMessage(\n        uint32 _version,\n        bytes32 _burnToken,\n        bytes32 _mintRecipient,\n        uint256 _amount,\n        bytes32 _messageSender\n    ) internal pure returns (bytes memory) {\n        return\n            abi.encodePacked(\n                _version,\n                _burnToken,\n                _mintRecipient,\n                _amount,\n                _messageSender\n            );\n    }\n\n    /**\n     * @notice Retrieves the burnToken from a DepositForBurn BurnMessage\n     * @param _message The message\n     * @return sourceToken address as bytes32\n     */\n    function _getMessageSender(\n        bytes29 _message\n    ) internal pure returns (bytes32) {\n        return _message.index(MSG_SENDER_INDEX, MSG_SENDER_LEN);\n    }\n\n    /**\n     * @notice Retrieves the burnToken from a DepositForBurn BurnMessage\n     * @param _message The message\n     * @return sourceToken address as bytes32\n     */\n    function _getBurnToken(bytes29 _message) internal pure returns (bytes32) {\n        return _message.index(BURN_TOKEN_INDEX, BURN_TOKEN_LEN);\n    }\n\n    /**\n     * @notice Retrieves the mintRecipient from a BurnMessage\n     * @param _message The message\n     * @return mintRecipient\n     */\n    function _getMintRecipient(\n        bytes29 _message\n    ) internal pure returns (bytes32) {\n        return _message.index(MINT_RECIPIENT_INDEX, MINT_RECIPIENT_LEN);\n    }\n\n    /**\n     * @notice Retrieves the amount from a BurnMessage\n     * @param _message The message\n     * @return amount\n     */\n    function _getAmount(bytes29 _message) internal pure returns (uint256) {\n        return _message.indexUint(AMOUNT_INDEX, AMOUNT_LEN);\n    }\n\n    /**\n     * @notice Retrieves the version from a Burn message\n     * @param _message The message\n     * @return version\n     */\n    function _getVersion(bytes29 _message) internal pure returns (uint32) {\n        return uint32(_message.indexUint(VERSION_INDEX, VERSION_LEN));\n    }\n\n    /**\n     * @notice Reverts if burn message is malformed or invalid length\n     * @param _message The burn message as bytes29\n     */\n    function _validateBurnMessageFormat(bytes29 _message) internal pure {\n        require(_message.isValid(), \"Malformed message\");\n        require(_message.len() == BURN_MESSAGE_LEN, \"Invalid message length\");\n    }\n}\n"},"contracts/libs/CctpMessageV2.sol":{"content":"/*\n * Copyright 2024 Circle Internet Group, Inc. All rights reserved.\n *\n * SPDX-License-Identifier: Apache-2.0\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npragma solidity >=0.8.0;\n\nimport {TypedMemView} from \"./TypedMemView.sol\";\n\n// @dev copied from https://github.com/circlefin/evm-cctp-contracts/blob/release-2025-03-11T143015/src/messages/v2/MessageV2.sol\n// @dev We need only source domain and nonce which have the same indexes of Cctp message version 1\n// @dev We are using the 'latest-solidity' branch for @memview-sol, which supports solidity version\n// greater or equal than 0.8.0\nlibrary CctpMessageV2 {\n    using TypedMemView for bytes;\n    using TypedMemView for bytes29;\n\n    // Indices of each field in message\n    uint8 private constant NONCE_INDEX = 12;\n\n    function _getNonce(bytes29 _message) internal pure returns (bytes32) {\n        return _message.index(NONCE_INDEX, 32);\n    }\n}\n"},"contracts/libs/CheckpointLib.sol":{"content":"// SPDX-License-Identifier: MIT OR Apache-2.0\npragma solidity >=0.8.0;\n\nimport {ECDSA} from \"@openzeppelin/contracts/utils/cryptography/ECDSA.sol\";\nimport {TypeCasts} from \"./TypeCasts.sol\";\n\nstruct Checkpoint {\n    uint32 origin;\n    bytes32 merkleTree;\n    bytes32 root;\n    uint32 index;\n    bytes32 messageId;\n}\n\nlibrary CheckpointLib {\n    using TypeCasts for bytes32;\n\n    /**\n     * @notice Returns the digest validators are expected to sign when signing checkpoints.\n     * @param _origin The origin domain of the checkpoint.\n     * @param _merkleTreeHook The address of the origin merkle tree hook as bytes32.\n     * @param _checkpointRoot The root of the checkpoint.\n     * @param _checkpointIndex The index of the checkpoint.\n     * @param _messageId The message ID of the checkpoint.\n     * @dev Message ID must match leaf content of checkpoint root at index.\n     * @return The digest of the checkpoint.\n     */\n    function digest(\n        uint32 _origin,\n        bytes32 _merkleTreeHook,\n        bytes32 _checkpointRoot,\n        uint32 _checkpointIndex,\n        bytes32 _messageId\n    ) internal pure returns (bytes32) {\n        bytes32 _domainHash = domainHash(_origin, _merkleTreeHook);\n        return\n            ECDSA.toEthSignedMessageHash(\n                keccak256(\n                    abi.encodePacked(\n                        _domainHash,\n                        _checkpointRoot,\n                        _checkpointIndex,\n                        _messageId\n                    )\n                )\n            );\n    }\n\n    /**\n     * @notice Returns the digest validators are expected to sign when signing checkpoints.\n     * @param checkpoint The checkpoint (struct) to hash.\n     * @return The digest of the checkpoint.\n     */\n    function digest(\n        Checkpoint memory checkpoint\n    ) internal pure returns (bytes32) {\n        return\n            digest(\n                checkpoint.origin,\n                checkpoint.merkleTree,\n                checkpoint.root,\n                checkpoint.index,\n                checkpoint.messageId\n            );\n    }\n\n    function merkleTreeAddress(\n        Checkpoint calldata checkpoint\n    ) internal pure returns (address) {\n        return checkpoint.merkleTree.bytes32ToAddress();\n    }\n\n    /**\n     * @notice Returns the domain hash that validators are expected to use\n     * when signing checkpoints.\n     * @param _origin The origin domain of the checkpoint.\n     * @param _merkleTreeHook The address of the origin merkle tree as bytes32.\n     * @return The domain hash.\n     */\n    function domainHash(\n        uint32 _origin,\n        bytes32 _merkleTreeHook\n    ) internal pure returns (bytes32) {\n        // Including the origin merkle tree address in the signature allows the slashing\n        // protocol to enroll multiple trees. Otherwise, a valid signature for\n        // tree A would be indistinguishable from a fraudulent signature for tree B.\n        // The slashing protocol should slash if validators sign attestations for\n        // anything other than a whitelisted tree.\n        return\n            keccak256(abi.encodePacked(_origin, _merkleTreeHook, \"HYPERLANE\"));\n    }\n}\n"},"contracts/libs/EnumerableMapEnrollment.sol":{"content":"// SPDX-License-Identifier: MIT OR Apache-2.0\npragma solidity >=0.6.11;\n\n// ============ External Imports ============\nimport \"@openzeppelin/contracts/utils/structs/EnumerableMap.sol\";\nimport \"@openzeppelin/contracts/utils/structs/EnumerableSet.sol\";\n// ============ Internal Imports ============\nimport {TypeCasts} from \"./TypeCasts.sol\";\n\nenum EnrollmentStatus {\n    UNENROLLED,\n    ENROLLED,\n    PENDING_UNENROLLMENT\n}\n\nstruct Enrollment {\n    EnrollmentStatus status;\n    uint248 unenrollmentStartBlock;\n}\n\n// extends EnumerableMap with address => bytes32 type\n// modelled after https://github.com/OpenZeppelin/openzeppelin-contracts/blob/v4.8.0/contracts/utils/structs/EnumerableMap.sol\nlibrary EnumerableMapEnrollment {\n    using EnumerableMap for EnumerableMap.Bytes32ToBytes32Map;\n    using EnumerableSet for EnumerableSet.Bytes32Set;\n    using TypeCasts for address;\n    using TypeCasts for bytes32;\n\n    struct AddressToEnrollmentMap {\n        EnumerableMap.Bytes32ToBytes32Map _inner;\n    }\n\n    // ============ Library Functions ============\n\n    function encode(\n        Enrollment memory enrollment\n    ) public pure returns (bytes32) {\n        return\n            bytes32(\n                abi.encodePacked(\n                    uint8(enrollment.status),\n                    enrollment.unenrollmentStartBlock\n                )\n            );\n    }\n\n    function decode(bytes32 encoded) public pure returns (Enrollment memory) {\n        uint8 status = uint8(encoded[0]);\n        uint248 unenrollmentStartBlock = uint248(uint256((encoded << 8) >> 8));\n        return Enrollment(EnrollmentStatus(status), unenrollmentStartBlock);\n    }\n\n    function keys(\n        AddressToEnrollmentMap storage map\n    ) internal view returns (address[] memory _keys) {\n        uint256 _length = map._inner.length();\n        _keys = new address[](_length);\n        for (uint256 i = 0; i < _length; i++) {\n            _keys[i] = address(uint160(uint256(map._inner._keys.at(i))));\n        }\n    }\n\n    function set(\n        AddressToEnrollmentMap storage map,\n        address key,\n        Enrollment memory value\n    ) internal returns (bool) {\n        return map._inner.set(key.addressToBytes32(), encode(value));\n    }\n\n    function get(\n        AddressToEnrollmentMap storage map,\n        address key\n    ) internal view returns (Enrollment memory) {\n        return decode(map._inner.get(key.addressToBytes32()));\n    }\n\n    function tryGet(\n        AddressToEnrollmentMap storage map,\n        address key\n    ) internal view returns (bool, Enrollment memory) {\n        (bool success, bytes32 value) = map._inner.tryGet(\n            key.addressToBytes32()\n        );\n        return (success, decode(value));\n    }\n\n    function remove(\n        AddressToEnrollmentMap storage map,\n        address key\n    ) internal returns (bool) {\n        return map._inner.remove(key.addressToBytes32());\n    }\n\n    function contains(\n        AddressToEnrollmentMap storage map,\n        address key\n    ) internal view returns (bool) {\n        return map._inner.contains(key.addressToBytes32());\n    }\n\n    function length(\n        AddressToEnrollmentMap storage map\n    ) internal view returns (uint256) {\n        return map._inner.length();\n    }\n\n    function at(\n        AddressToEnrollmentMap storage map,\n        uint256 index\n    ) internal view returns (uint256, Enrollment memory) {\n        (bytes32 key, bytes32 value) = map._inner.at(index);\n        return (uint256(key), decode(value));\n    }\n}\n"},"contracts/libs/EnumerableMapExtended.sol":{"content":"// SPDX-License-Identifier: MIT OR Apache-2.0\npragma solidity >=0.6.11;\n\n// ============ External Imports ============\nimport \"@openzeppelin/contracts/utils/structs/EnumerableMap.sol\";\nimport \"@openzeppelin/contracts/utils/structs/EnumerableSet.sol\";\n\n// extends EnumerableMap with uint256 => bytes32 type\n// modelled after https://github.com/OpenZeppelin/openzeppelin-contracts/blob/v4.8.0/contracts/utils/structs/EnumerableMap.sol\nlibrary EnumerableMapExtended {\n    using EnumerableMap for EnumerableMap.Bytes32ToBytes32Map;\n    using EnumerableSet for EnumerableSet.Bytes32Set;\n\n    struct UintToBytes32Map {\n        EnumerableMap.Bytes32ToBytes32Map _inner;\n    }\n\n    // ============ Library Functions ============\n    function keys(\n        UintToBytes32Map storage map\n    ) internal view returns (uint256[] memory _keys) {\n        uint256 _length = map._inner.length();\n        _keys = new uint256[](_length);\n        for (uint256 i = 0; i < _length; i++) {\n            _keys[i] = uint256(map._inner._keys.at(i));\n        }\n    }\n\n    function uint32Keys(\n        UintToBytes32Map storage map\n    ) internal view returns (uint32[] memory _keys) {\n        uint256[] memory uint256keys = keys(map);\n        _keys = new uint32[](uint256keys.length);\n        for (uint256 i = 0; i < uint256keys.length; i++) {\n            _keys[i] = uint32(uint256keys[i]);\n        }\n    }\n\n    function set(\n        UintToBytes32Map storage map,\n        uint256 key,\n        bytes32 value\n    ) internal {\n        map._inner.set(bytes32(key), value);\n    }\n\n    function get(\n        UintToBytes32Map storage map,\n        uint256 key\n    ) internal view returns (bytes32) {\n        return map._inner.get(bytes32(key));\n    }\n\n    function tryGet(\n        UintToBytes32Map storage map,\n        uint256 key\n    ) internal view returns (bool, bytes32) {\n        return map._inner.tryGet(bytes32(key));\n    }\n\n    function remove(\n        UintToBytes32Map storage map,\n        uint256 key\n    ) internal returns (bool) {\n        return map._inner.remove(bytes32(key));\n    }\n\n    function contains(\n        UintToBytes32Map storage map,\n        uint256 key\n    ) internal view returns (bool) {\n        return map._inner.contains(bytes32(key));\n    }\n\n    function length(\n        UintToBytes32Map storage map\n    ) internal view returns (uint256) {\n        return map._inner.length();\n    }\n\n    function at(\n        UintToBytes32Map storage map,\n        uint256 index\n    ) internal view returns (uint256, bytes32) {\n        (bytes32 key, bytes32 value) = map._inner.at(index);\n        return (uint256(key), value);\n    }\n}\n"},"contracts/libs/Indexed.sol":{"content":"// SPDX-License-Identifier: MIT OR Apache-2.0\npragma solidity >=0.8.0;\n\ncontract Indexed {\n    uint256 public immutable deployedBlock;\n\n    constructor() {\n        deployedBlock = block.number;\n    }\n}\n"},"contracts/libs/LibBit.sol":{"content":"// SPDX-License-Identifier: MIT OR Apache-2.0\npragma solidity >=0.8.0;\n\n/// @notice Library for bit shifting and masking\nlibrary LibBit {\n    function setBit(\n        uint256 _value,\n        uint256 _index\n    ) internal pure returns (uint256) {\n        return _value | (1 << _index);\n    }\n\n    function clearBit(\n        uint256 _value,\n        uint256 _index\n    ) internal pure returns (uint256) {\n        return _value & ~(1 << _index);\n    }\n\n    function isBitSet(\n        uint256 _value,\n        uint256 _index\n    ) internal pure returns (bool) {\n        return (_value >> _index) & 1 == 1;\n    }\n}\n"},"contracts/libs/Merkle.sol":{"content":"// SPDX-License-Identifier: MIT OR Apache-2.0\npragma solidity >=0.6.11;\n\n// work based on eth2 deposit contract, which is used under CC0-1.0\n\nuint256 constant TREE_DEPTH = 32;\nuint256 constant MAX_LEAVES = 2 ** TREE_DEPTH - 1;\n\n/**\n * @title MerkleLib\n * @author Celo Labs Inc.\n * @notice An incremental merkle tree modeled on the eth2 deposit contract.\n **/\nlibrary MerkleLib {\n    /**\n     * @notice Struct representing incremental merkle tree. Contains current\n     * branch and the number of inserted leaves in the tree.\n     **/\n    struct Tree {\n        bytes32[TREE_DEPTH] branch;\n        uint256 count;\n    }\n\n    /**\n     * @notice Inserts `_node` into merkle tree\n     * @dev Reverts if tree is full\n     * @param _node Element to insert into tree\n     **/\n    function insert(Tree storage _tree, bytes32 _node) internal {\n        require(_tree.count < MAX_LEAVES, \"merkle tree full\");\n\n        _tree.count += 1;\n        uint256 size = _tree.count;\n        for (uint256 i = 0; i < TREE_DEPTH; i++) {\n            if ((size & 1) == 1) {\n                _tree.branch[i] = _node;\n                return;\n            }\n            _node = keccak256(abi.encodePacked(_tree.branch[i], _node));\n            size /= 2;\n        }\n        // As the loop should always end prematurely with the `return` statement,\n        // this code should be unreachable. We assert `false` just to be safe.\n        assert(false);\n    }\n\n    /**\n     * @notice Calculates and returns`_tree`'s current root given array of zero\n     * hashes\n     * @param _zeroes Array of zero hashes\n     * @return _current Calculated root of `_tree`\n     **/\n    function rootWithCtx(\n        Tree storage _tree,\n        bytes32[TREE_DEPTH] memory _zeroes\n    ) internal view returns (bytes32 _current) {\n        uint256 _index = _tree.count;\n\n        for (uint256 i = 0; i < TREE_DEPTH; i++) {\n            uint256 _ithBit = (_index >> i) & 0x01;\n            bytes32 _next = _tree.branch[i];\n            if (_ithBit == 1) {\n                _current = keccak256(abi.encodePacked(_next, _current));\n            } else {\n                _current = keccak256(abi.encodePacked(_current, _zeroes[i]));\n            }\n        }\n    }\n\n    /// @notice Calculates and returns`_tree`'s current root\n    function root(Tree storage _tree) internal view returns (bytes32) {\n        return rootWithCtx(_tree, zeroHashes());\n    }\n\n    /// @notice Returns array of TREE_DEPTH zero hashes\n    /// @return _zeroes Array of TREE_DEPTH zero hashes\n    function zeroHashes()\n        internal\n        pure\n        returns (bytes32[TREE_DEPTH] memory _zeroes)\n    {\n        _zeroes[0] = Z_0;\n        _zeroes[1] = Z_1;\n        _zeroes[2] = Z_2;\n        _zeroes[3] = Z_3;\n        _zeroes[4] = Z_4;\n        _zeroes[5] = Z_5;\n        _zeroes[6] = Z_6;\n        _zeroes[7] = Z_7;\n        _zeroes[8] = Z_8;\n        _zeroes[9] = Z_9;\n        _zeroes[10] = Z_10;\n        _zeroes[11] = Z_11;\n        _zeroes[12] = Z_12;\n        _zeroes[13] = Z_13;\n        _zeroes[14] = Z_14;\n        _zeroes[15] = Z_15;\n        _zeroes[16] = Z_16;\n        _zeroes[17] = Z_17;\n        _zeroes[18] = Z_18;\n        _zeroes[19] = Z_19;\n        _zeroes[20] = Z_20;\n        _zeroes[21] = Z_21;\n        _zeroes[22] = Z_22;\n        _zeroes[23] = Z_23;\n        _zeroes[24] = Z_24;\n        _zeroes[25] = Z_25;\n        _zeroes[26] = Z_26;\n        _zeroes[27] = Z_27;\n        _zeroes[28] = Z_28;\n        _zeroes[29] = Z_29;\n        _zeroes[30] = Z_30;\n        _zeroes[31] = Z_31;\n    }\n\n    /**\n     * @notice Calculates and returns the merkle root for the given leaf\n     * `_item`, a merkle branch, and the index of `_item` in the tree.\n     * @param _item Merkle leaf\n     * @param _branch Merkle proof\n     * @param _index Index of `_item` in tree\n     * @return _current Calculated merkle root\n     **/\n    function branchRoot(\n        bytes32 _item,\n        bytes32[TREE_DEPTH] memory _branch, // cheaper than calldata indexing\n        uint256 _index\n    ) internal pure returns (bytes32 _current) {\n        _current = _item;\n\n        for (uint256 i = 0; i < TREE_DEPTH; i++) {\n            uint256 _ithBit = (_index >> i) & 0x01;\n            // cheaper than calldata indexing _branch[i*32:(i+1)*32];\n            bytes32 _next = _branch[i];\n            if (_ithBit == 1) {\n                _current = keccak256(abi.encodePacked(_next, _current));\n            } else {\n                _current = keccak256(abi.encodePacked(_current, _next));\n            }\n        }\n    }\n\n    /**\n     * @notice Calculates and returns the merkle root as if the index is\n     * the topmost leaf in the tree.\n     * @param _item Merkle leaf\n     * @param _branch Merkle proof\n     * @param _index Index of `_item` in tree\n     * @dev Replaces siblings greater than the index (right subtrees) with zeroes.\n     * @return _current Calculated merkle root\n     **/\n    function reconstructRoot(\n        bytes32 _item,\n        bytes32[TREE_DEPTH] memory _branch, // cheaper than calldata indexing\n        uint256 _index\n    ) internal pure returns (bytes32 _current) {\n        _current = _item;\n\n        bytes32[TREE_DEPTH] memory _zeroes = zeroHashes();\n\n        for (uint256 i = 0; i < TREE_DEPTH; i++) {\n            uint256 _ithBit = (_index >> i) & 0x01;\n            // cheaper than calldata indexing _branch[i*32:(i+1)*32];\n            if (_ithBit == 1) {\n                _current = keccak256(abi.encodePacked(_branch[i], _current));\n            } else {\n                // remove right subtree from proof\n                _current = keccak256(abi.encodePacked(_current, _zeroes[i]));\n            }\n        }\n    }\n\n    // keccak256 zero hashes\n    bytes32 internal constant Z_0 =\n        hex\"0000000000000000000000000000000000000000000000000000000000000000\";\n    bytes32 internal constant Z_1 =\n        hex\"ad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5\";\n    bytes32 internal constant Z_2 =\n        hex\"b4c11951957c6f8f642c4af61cd6b24640fec6dc7fc607ee8206a99e92410d30\";\n    bytes32 internal constant Z_3 =\n        hex\"21ddb9a356815c3fac1026b6dec5df3124afbadb485c9ba5a3e3398a04b7ba85\";\n    bytes32 internal constant Z_4 =\n        hex\"e58769b32a1beaf1ea27375a44095a0d1fb664ce2dd358e7fcbfb78c26a19344\";\n    bytes32 internal constant Z_5 =\n        hex\"0eb01ebfc9ed27500cd4dfc979272d1f0913cc9f66540d7e8005811109e1cf2d\";\n    bytes32 internal constant Z_6 =\n        hex\"887c22bd8750d34016ac3c66b5ff102dacdd73f6b014e710b51e8022af9a1968\";\n    bytes32 internal constant Z_7 =\n        hex\"ffd70157e48063fc33c97a050f7f640233bf646cc98d9524c6b92bcf3ab56f83\";\n    bytes32 internal constant Z_8 =\n        hex\"9867cc5f7f196b93bae1e27e6320742445d290f2263827498b54fec539f756af\";\n    bytes32 internal constant Z_9 =\n        hex\"cefad4e508c098b9a7e1d8feb19955fb02ba9675585078710969d3440f5054e0\";\n    bytes32 internal constant Z_10 =\n        hex\"f9dc3e7fe016e050eff260334f18a5d4fe391d82092319f5964f2e2eb7c1c3a5\";\n    bytes32 internal constant Z_11 =\n        hex\"f8b13a49e282f609c317a833fb8d976d11517c571d1221a265d25af778ecf892\";\n    bytes32 internal constant Z_12 =\n        hex\"3490c6ceeb450aecdc82e28293031d10c7d73bf85e57bf041a97360aa2c5d99c\";\n    bytes32 internal constant Z_13 =\n        hex\"c1df82d9c4b87413eae2ef048f94b4d3554cea73d92b0f7af96e0271c691e2bb\";\n    bytes32 internal constant Z_14 =\n        hex\"5c67add7c6caf302256adedf7ab114da0acfe870d449a3a489f781d659e8becc\";\n    bytes32 internal constant Z_15 =\n        hex\"da7bce9f4e8618b6bd2f4132ce798cdc7a60e7e1460a7299e3c6342a579626d2\";\n    bytes32 internal constant Z_16 =\n        hex\"2733e50f526ec2fa19a22b31e8ed50f23cd1fdf94c9154ed3a7609a2f1ff981f\";\n    bytes32 internal constant Z_17 =\n        hex\"e1d3b5c807b281e4683cc6d6315cf95b9ade8641defcb32372f1c126e398ef7a\";\n    bytes32 internal constant Z_18 =\n        hex\"5a2dce0a8a7f68bb74560f8f71837c2c2ebbcbf7fffb42ae1896f13f7c7479a0\";\n    bytes32 internal constant Z_19 =\n        hex\"b46a28b6f55540f89444f63de0378e3d121be09e06cc9ded1c20e65876d36aa0\";\n    bytes32 internal constant Z_20 =\n        hex\"c65e9645644786b620e2dd2ad648ddfcbf4a7e5b1a3a4ecfe7f64667a3f0b7e2\";\n    bytes32 internal constant Z_21 =\n        hex\"f4418588ed35a2458cffeb39b93d26f18d2ab13bdce6aee58e7b99359ec2dfd9\";\n    bytes32 internal constant Z_22 =\n        hex\"5a9c16dc00d6ef18b7933a6f8dc65ccb55667138776f7dea101070dc8796e377\";\n    bytes32 internal constant Z_23 =\n        hex\"4df84f40ae0c8229d0d6069e5c8f39a7c299677a09d367fc7b05e3bc380ee652\";\n    bytes32 internal constant Z_24 =\n        hex\"cdc72595f74c7b1043d0e1ffbab734648c838dfb0527d971b602bc216c9619ef\";\n    bytes32 internal constant Z_25 =\n        hex\"0abf5ac974a1ed57f4050aa510dd9c74f508277b39d7973bb2dfccc5eeb0618d\";\n    bytes32 internal constant Z_26 =\n        hex\"b8cd74046ff337f0a7bf2c8e03e10f642c1886798d71806ab1e888d9e5ee87d0\";\n    bytes32 internal constant Z_27 =\n        hex\"838c5655cb21c6cb83313b5a631175dff4963772cce9108188b34ac87c81c41e\";\n    bytes32 internal constant Z_28 =\n        hex\"662ee4dd2dd7b2bc707961b1e646c4047669dcb6584f0d8d770daf5d7e7deb2e\";\n    bytes32 internal constant Z_29 =\n        hex\"388ab20e2573d171a88108e79d820e98f26c0b84aa8b2f4aa4968dbb818ea322\";\n    bytes32 internal constant Z_30 =\n        hex\"93237c50ba75ee485f4c22adf2f741400bdf8d6a9cc7df7ecae576221665d735\";\n    bytes32 internal constant Z_31 =\n        hex\"8448818bb4ae4562849e949e17ac16e0be16688e156b5cf15e098c627c0056a9\";\n}\n"},"contracts/libs/Message.sol":{"content":"// SPDX-License-Identifier: MIT OR Apache-2.0\npragma solidity >=0.8.0;\n\nimport {TypeCasts} from \"./TypeCasts.sol\";\n\n/**\n * @title Hyperlane Message Library\n * @notice Library for formatted messages used by Mailbox\n **/\nlibrary Message {\n    using TypeCasts for bytes32;\n\n    uint256 private constant VERSION_OFFSET = 0;\n    uint256 private constant NONCE_OFFSET = 1;\n    uint256 private constant ORIGIN_OFFSET = 5;\n    uint256 private constant SENDER_OFFSET = 9;\n    uint256 private constant DESTINATION_OFFSET = 41;\n    uint256 private constant RECIPIENT_OFFSET = 45;\n    uint256 private constant BODY_OFFSET = 77;\n\n    /**\n     * @notice Returns formatted (packed) Hyperlane message with provided fields\n     * @dev This function should only be used in memory message construction.\n     * @param _version The version of the origin and destination Mailboxes\n     * @param _nonce A nonce to uniquely identify the message on its origin chain\n     * @param _originDomain Domain of origin chain\n     * @param _sender Address of sender as bytes32\n     * @param _destinationDomain Domain of destination chain\n     * @param _recipient Address of recipient on destination chain as bytes32\n     * @param _messageBody Raw bytes of message body\n     * @return Formatted message\n     */\n    function formatMessage(\n        uint8 _version,\n        uint32 _nonce,\n        uint32 _originDomain,\n        bytes32 _sender,\n        uint32 _destinationDomain,\n        bytes32 _recipient,\n        bytes calldata _messageBody\n    ) internal pure returns (bytes memory) {\n        return\n            abi.encodePacked(\n                _version,\n                _nonce,\n                _originDomain,\n                _sender,\n                _destinationDomain,\n                _recipient,\n                _messageBody\n            );\n    }\n\n    /**\n     * @notice Returns the message ID.\n     * @param _message ABI encoded Hyperlane message.\n     * @return ID of `_message`\n     */\n    function id(bytes memory _message) internal pure returns (bytes32) {\n        return keccak256(_message);\n    }\n\n    /**\n     * @notice Returns the message version.\n     * @param _message ABI encoded Hyperlane message.\n     * @return Version of `_message`\n     */\n    function version(bytes calldata _message) internal pure returns (uint8) {\n        return uint8(bytes1(_message[VERSION_OFFSET:NONCE_OFFSET]));\n    }\n\n    /**\n     * @notice Returns the message nonce.\n     * @param _message ABI encoded Hyperlane message.\n     * @return Nonce of `_message`\n     */\n    function nonce(bytes calldata _message) internal pure returns (uint32) {\n        return uint32(bytes4(_message[NONCE_OFFSET:ORIGIN_OFFSET]));\n    }\n\n    /**\n     * @notice Returns the message origin domain.\n     * @param _message ABI encoded Hyperlane message.\n     * @return Origin domain of `_message`\n     */\n    function origin(bytes calldata _message) internal pure returns (uint32) {\n        return uint32(bytes4(_message[ORIGIN_OFFSET:SENDER_OFFSET]));\n    }\n\n    /**\n     * @notice Returns the message sender as bytes32.\n     * @param _message ABI encoded Hyperlane message.\n     * @return Sender of `_message` as bytes32\n     */\n    function sender(bytes calldata _message) internal pure returns (bytes32) {\n        return bytes32(_message[SENDER_OFFSET:DESTINATION_OFFSET]);\n    }\n\n    /**\n     * @notice Returns the message sender as address.\n     * @param _message ABI encoded Hyperlane message.\n     * @return Sender of `_message` as address\n     */\n    function senderAddress(\n        bytes calldata _message\n    ) internal pure returns (address) {\n        return sender(_message).bytes32ToAddress();\n    }\n\n    /**\n     * @notice Returns the message destination domain.\n     * @param _message ABI encoded Hyperlane message.\n     * @return Destination domain of `_message`\n     */\n    function destination(\n        bytes calldata _message\n    ) internal pure returns (uint32) {\n        return uint32(bytes4(_message[DESTINATION_OFFSET:RECIPIENT_OFFSET]));\n    }\n\n    /**\n     * @notice Returns the message recipient as bytes32.\n     * @param _message ABI encoded Hyperlane message.\n     * @return Recipient of `_message` as bytes32\n     */\n    function recipient(\n        bytes calldata _message\n    ) internal pure returns (bytes32) {\n        return bytes32(_message[RECIPIENT_OFFSET:BODY_OFFSET]);\n    }\n\n    /**\n     * @notice Returns the message recipient as address.\n     * @param _message ABI encoded Hyperlane message.\n     * @return Recipient of `_message` as address\n     */\n    function recipientAddress(\n        bytes calldata _message\n    ) internal pure returns (address) {\n        return recipient(_message).bytes32ToAddress();\n    }\n\n    /**\n     * @notice Returns the message body.\n     * @param _message ABI encoded Hyperlane message.\n     * @return Body of `_message`\n     */\n    function body(\n        bytes calldata _message\n    ) internal pure returns (bytes calldata) {\n        return bytes(_message[BODY_OFFSET:]);\n    }\n}\n"},"contracts/libs/MetaProxy.sol":{"content":"// SPDX-License-Identifier: CC0-1.0\npragma solidity >=0.7.6;\n\n/// @dev Adapted from https://eips.ethereum.org/EIPS/eip-3448\nlibrary MetaProxy {\n    bytes32 private constant PREFIX =\n        hex\"600b380380600b3d393df3363d3d373d3d3d3d60368038038091363936013d73\";\n    bytes13 private constant SUFFIX = hex\"5af43d3d93803e603457fd5bf3\";\n\n    function bytecode(\n        address _implementation,\n        bytes memory _metadata\n    ) internal pure returns (bytes memory) {\n        return\n            abi.encodePacked(\n                PREFIX,\n                bytes20(_implementation),\n                SUFFIX,\n                _metadata,\n                _metadata.length\n            );\n    }\n\n    function metadata() internal pure returns (bytes memory) {\n        bytes memory data;\n        assembly {\n            let posOfMetadataSize := sub(calldatasize(), 32)\n            let size := calldataload(posOfMetadataSize)\n            let dataPtr := sub(posOfMetadataSize, size)\n            data := mload(64)\n            // increment free memory pointer by metadata size + 32 bytes (length)\n            mstore(64, add(data, add(size, 32)))\n            mstore(data, size)\n            let memPtr := add(data, 32)\n            calldatacopy(memPtr, dataPtr, size)\n        }\n        return data;\n    }\n}\n"},"contracts/libs/MinimalProxy.sol":{"content":"// SPDX-License-Identifier: MIT OR Apache-2.0\npragma solidity >=0.6.11;\n\n// Library for building bytecode of minimal proxies (see https://eips.ethereum.org/EIPS/eip-1167)\nlibrary MinimalProxy {\n    bytes20 private constant PREFIX =\n        hex\"3d602d80600a3d3981f3363d3d373d3d3d363d73\";\n    bytes15 private constant SUFFIX = hex\"5af43d82803e903d91602b57fd5bf3\";\n\n    function create(address implementation) internal returns (address proxy) {\n        bytes memory _bytecode = bytecode(implementation);\n        assembly {\n            proxy := create(0, add(_bytecode, 32), mload(_bytecode))\n        }\n    }\n\n    function bytecode(\n        address implementation\n    ) internal pure returns (bytes memory) {\n        return abi.encodePacked(PREFIX, bytes20(implementation), SUFFIX);\n    }\n}\n"},"contracts/libs/OPL2ToL1Metadata.sol":{"content":"// SPDX-License-Identifier: MIT OR Apache-2.0\npragma solidity >=0.8.0;\n\n/**\n * @title Hyperlane OPL2ToL1Metadata Library\n * @notice Library for formatted metadata used by OPL2ToL1Ism\n */\nlibrary OPL2ToL1Metadata {\n    // bottom offset to the start of message id in the metadata\n    uint256 private constant MESSAGE_ID_OFFSET = 120;\n    // from IOptimismPortal.WithdrawalTransaction\n    // Σ {\n    //      nonce                          = 32 bytes\n    //      PADDING + sender               = 32 bytes\n    //      PADDING + target               = 32 bytes\n    //      value                          = 32 bytes\n    //      gasLimit                       = 32 bytes\n    //      _data\n    //          OFFSET                      = 32 bytes\n    //          LENGTH                      = 32 bytes\n    // } = 252 bytes\n    uint256 private constant FIXED_METADATA_LENGTH = 252;\n    // metadata here is double encoded call relayMessage(..., preVerifyMessage)\n    // Σ {\n    //      _selector                       =  4 bytes\n    //      _nonce                          = 32 bytes\n    //      PADDING + _sender               = 32 bytes\n    //      PADDING + _target               = 32 bytes\n    //      _value                          = 32 bytes\n    //      _minGasLimit                    = 32 bytes\n    //      _data\n    //          OFFSET                      = 32 bytes\n    //          LENGTH                      = 32 bytes\n    //          PADDING + preVerifyMessage   = 96 bytes\n    // } = 324 bytes\n    uint256 private constant MESSENGER_CALLDATA_LENGTH = 324;\n\n    /**\n     * @notice Returns the message ID.\n     * @param _metadata OptimismPortal.WithdrawalTransaction encoded calldata\n     * @return ID of `_metadata`\n     */\n    function messageId(\n        bytes calldata _metadata\n    ) internal pure returns (bytes32) {\n        uint256 metadataLength = _metadata.length;\n        return\n            bytes32(\n                _metadata[metadataLength - MESSAGE_ID_OFFSET:metadataLength -\n                    MESSAGE_ID_OFFSET +\n                    32]\n            );\n    }\n\n    function checkCalldataLength(\n        bytes calldata _metadata\n    ) internal pure returns (bool) {\n        return\n            _metadata.length ==\n            MESSENGER_CALLDATA_LENGTH + FIXED_METADATA_LENGTH;\n    }\n}\n"},"contracts/libs/OPL2ToL1Withdrawal.sol":{"content":"// SPDX-License-Identifier: MIT OR Apache-2.0\npragma solidity >=0.8.0;\n\nimport {IOptimismPortal} from \"../interfaces/optimism/IOptimismPortal.sol\";\n\n/**\n * @title Hyperlane OPL2ToL1Withdrawal Library\n * @notice Library to calculate the withdrawal hash for OPL2ToL1CcipReadIsm\n * validation\n */\nlibrary OPL2ToL1Withdrawal {\n    /// @dev Copied from Hashing.sol of Optimism\n    function hashWithdrawal(\n        IOptimismPortal.WithdrawalTransaction memory _tx\n    ) internal pure returns (bytes32) {\n        return\n            keccak256(\n                abi.encode(\n                    _tx.nonce,\n                    _tx.sender,\n                    _tx.target,\n                    _tx.value,\n                    _tx.gasLimit,\n                    _tx.data\n                )\n            );\n    }\n\n    function encodeData(\n        bytes32 _proveMessageId,\n        bytes32 _finalizeMessageId\n    ) internal pure returns (bytes memory) {\n        return abi.encode(_proveMessageId, _finalizeMessageId);\n    }\n\n    function proveMessageId(\n        IOptimismPortal.WithdrawalTransaction memory _tx\n    ) internal pure returns (bytes32) {\n        (bytes32 _proveMessageId, ) = abi.decode(_tx.data, (bytes32, bytes32));\n        return _proveMessageId;\n    }\n\n    function finalizeMessageId(\n        IOptimismPortal.WithdrawalTransaction memory _tx\n    ) internal pure returns (bytes32) {\n        (, bytes32 _finalizeMessageId) = abi.decode(\n            _tx.data,\n            (bytes32, bytes32)\n        );\n        return _finalizeMessageId;\n    }\n}\n"},"contracts/libs/RateLimited.sol":{"content":"// SPDX-License-Identifier: MIT OR Apache-2.0\npragma solidity >=0.8.0;\n\n/*@@@@@@@       @@@@@@@@@\n @@@@@@@@@       @@@@@@@@@\n  @@@@@@@@@       @@@@@@@@@\n   @@@@@@@@@       @@@@@@@@@\n    @@@@@@@@@@@@@@@@@@@@@@@@@\n     @@@@@  HYPERLANE  @@@@@@@\n    @@@@@@@@@@@@@@@@@@@@@@@@@\n   @@@@@@@@@       @@@@@@@@@\n  @@@@@@@@@       @@@@@@@@@\n @@@@@@@@@       @@@@@@@@@\n@@@@@@@@@       @@@@@@@@*/\n\n// ============ External Imports ============\nimport {OwnableUpgradeable} from \"@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol\";\n\n/**\n * @title RateLimited\n * @notice A contract used to keep track of an address sender's token amount limits.\n * @dev Implements a modified token bucket algorithm where the bucket is full in the beginning and gradually refills\n * See: https://dev.to/satrobit/rate-limiting-using-the-token-bucket-algorithm-3cjh\n *\n */\ncontract RateLimited is OwnableUpgradeable {\n    uint256 public constant DURATION = 1 days; // 86400\n    /// @notice Current filled level\n    uint256 public filledLevel;\n    /// @notice Tokens per second refill rate\n    uint256 public refillRate;\n    /// @notice Timestamp of the last time an action has been taken\n    uint256 public lastUpdated;\n\n    event RateLimitSet(uint256 _oldCapacity, uint256 _newCapacity);\n\n    event ConsumedFilledLevel(uint256 filledLevel, uint256 lastUpdated);\n\n    constructor(uint256 _capacity) {\n        require(\n            _capacity >= DURATION,\n            \"Capacity must be greater than DURATION\"\n        );\n        _transferOwnership(msg.sender);\n        setRefillRate(_capacity);\n        filledLevel = _capacity;\n    }\n\n    error RateLimitExceeded(uint256 newLimit, uint256 targetLimit);\n\n    /**\n     * @return The max capacity where the bucket will no longer refill\n     */\n    function maxCapacity() public view returns (uint256) {\n        return refillRate * DURATION;\n    }\n\n    /**\n     * Calculates the refilled amount based on time and refill rate\n     *\n     * Consider an example where there is a 1e18 max token limit per day (86400s)\n     * If half of the tokens has been used, and half a day (43200s) has passed,\n     * then there should be a refill of 0.5e18\n     *\n     * To calculate:\n     *   Refilled = Elapsed * RefilledRate\n     *   Elapsed = timestamp - Limit.lastUpdated\n     *   RefilledRate = Capacity / DURATION\n     *\n     *   If half of the day (43200) has passed, then\n     *   (86400 - 43200) * (1e18 / 86400)  = 0.5e18\n     */\n    function calculateRefilledAmount() internal view returns (uint256) {\n        uint256 elapsed = block.timestamp - lastUpdated;\n        return elapsed * refillRate;\n    }\n\n    /**\n     * Calculates the adjusted fill level based on time\n     */\n    function calculateCurrentLevel() public view returns (uint256) {\n        uint256 _capacity = maxCapacity();\n        require(_capacity > 0, \"RateLimitNotSet\");\n\n        if (block.timestamp > lastUpdated + DURATION) {\n            // If last update is in the previous window, return the max capacity\n            return _capacity;\n        } else {\n            // If within the window, refill the capacity\n            uint256 replenishedLevel = filledLevel + calculateRefilledAmount();\n\n            // Only return _capacity, in the case where newCurrentCapcacity overflows\n            return replenishedLevel > _capacity ? _capacity : replenishedLevel;\n        }\n    }\n\n    /**\n     * Sets the refill rate by giving a capacity\n     * @param _capacity new maximum capacity to set\n     */\n    function setRefillRate(\n        uint256 _capacity\n    ) public onlyOwner returns (uint256) {\n        uint256 _oldRefillRate = refillRate;\n        uint256 _newRefillRate = _capacity / DURATION;\n        refillRate = _newRefillRate;\n\n        emit RateLimitSet(_oldRefillRate, _newRefillRate);\n\n        return _newRefillRate;\n    }\n\n    /**\n     * Validate an amount and decreases the currentCapacity\n     * @param _consumedAmount The amount to consume the fill level\n     * @return The new filled level\n     */\n    function _validateAndConsumeFilledLevel(\n        uint256 _consumedAmount\n    ) internal returns (uint256) {\n        uint256 adjustedFilledLevel = calculateCurrentLevel();\n        require(_consumedAmount <= adjustedFilledLevel, \"RateLimitExceeded\");\n\n        // Reduce the filledLevel and update lastUpdated\n        uint256 _filledLevel = adjustedFilledLevel - _consumedAmount;\n        filledLevel = _filledLevel;\n        lastUpdated = block.timestamp;\n\n        emit ConsumedFilledLevel(filledLevel, lastUpdated);\n\n        return _filledLevel;\n    }\n}\n"},"contracts/libs/RateLimitMidpointCommonLibrary.sol":{"content":"// SPDX-License-Identifier: BSD-3.0\npragma solidity >=0.8.19 <0.9.0;\n\n/// @notice two rate storage slots per rate limit\nstruct RateLimitMidPoint {\n    //// -------------------------------------------- ////\n    //// ------------------ SLOT 0 ------------------ ////\n    //// -------------------------------------------- ////\n    /// @notice the rate per second for this contract\n    uint128 rateLimitPerSecond;\n    /// @notice the cap of the buffer that can be used at once\n    uint112 bufferCap;\n    //// -------------------------------------------- ////\n    //// ------------------ SLOT 1 ------------------ ////\n    //// -------------------------------------------- ////\n    /// @notice the last time the buffer was used by the contract\n    uint32 lastBufferUsedTime;\n    /// @notice the buffer at the timestamp of lastBufferUsedTime\n    uint112 bufferStored;\n    /// @notice the mid point of the buffer\n    uint112 midPoint;\n}\n"},"contracts/libs/StaticAddressSetFactory.sol":{"content":"// SPDX-License-Identifier: MIT OR Apache-2.0\npragma solidity >=0.8.0;\n// ============ External Imports ============\nimport {Address} from \"@openzeppelin/contracts/utils/Address.sol\";\nimport {Create2} from \"@openzeppelin/contracts/utils/Create2.sol\";\n\n// ============ Internal Imports ============\nimport {MetaProxy} from \"./MetaProxy.sol\";\nimport {PackageVersioned} from \"../PackageVersioned.sol\";\nimport {IThresholdAddressFactory} from \"../interfaces/IThresholdAddressFactory.sol\";\n\nabstract contract StaticThresholdAddressSetFactory is\n    PackageVersioned,\n    IThresholdAddressFactory\n{\n    // ============ Immutables ============\n    address public immutable implementation;\n\n    // ============ Constructor ============\n\n    constructor() {\n        implementation = _deployImplementation();\n    }\n\n    function _deployImplementation() internal virtual returns (address);\n\n    /**\n     * @notice Deploys a StaticThresholdAddressSet contract address for the given\n     * values\n     * @dev Consider sorting addresses to ensure contract reuse\n     * @param _values An array of addresses\n     * @param _threshold The threshold value to use\n     * @return set The contract address representing this StaticThresholdAddressSet\n     */\n    function deploy(\n        address[] calldata _values,\n        uint8 _threshold\n    ) public returns (address) {\n        require(\n            0 < _threshold && _threshold <= _values.length,\n            \"Invalid threshold\"\n        );\n        (bytes32 _salt, bytes memory _bytecode) = _saltAndBytecode(\n            _values,\n            _threshold\n        );\n        address _set = _getAddress(_salt, _bytecode);\n        if (!Address.isContract(_set)) {\n            _set = Create2.deploy(0, _salt, _bytecode);\n        }\n        return _set;\n    }\n\n    /**\n     * @notice Returns the StaticThresholdAddressSet contract address for the given\n     * values\n     * @dev Consider sorting addresses to ensure contract reuse\n     * @param _values An array of addresses\n     * @param _threshold The threshold value to use\n     * @return set The contract address representing this StaticThresholdAddressSet\n     */\n    function getAddress(\n        address[] calldata _values,\n        uint8 _threshold\n    ) external view returns (address) {\n        (bytes32 _salt, bytes memory _bytecode) = _saltAndBytecode(\n            _values,\n            _threshold\n        );\n        return _getAddress(_salt, _bytecode);\n    }\n\n    /**\n     * @notice Returns the StaticThresholdAddressSet contract address for the given\n     * values\n     * @param _salt The salt used in Create2\n     * @param _bytecode The metaproxy bytecode used in Create2\n     * @return set The contract address representing this StaticThresholdAddressSet\n     */\n    function _getAddress(\n        bytes32 _salt,\n        bytes memory _bytecode\n    ) internal view returns (address) {\n        bytes32 _bytecodeHash = keccak256(_bytecode);\n        return Create2.computeAddress(_salt, _bytecodeHash);\n    }\n\n    /**\n     * @notice Returns the create2 salt and bytecode for the given values\n     * @param _values An array of addresses\n     * @param _threshold The threshold value to use\n     * @return _salt The salt used in Create2\n     * @return _bytecode The metaproxy bytecode used in Create2\n     */\n    function _saltAndBytecode(\n        address[] calldata _values,\n        uint8 _threshold\n    ) internal view returns (bytes32, bytes memory) {\n        bytes memory _metadata = abi.encode(_values, _threshold);\n        bytes memory _bytecode = MetaProxy.bytecode(implementation, _metadata);\n        bytes32 _salt = keccak256(_metadata);\n        return (_salt, _bytecode);\n    }\n}\n\nabstract contract StaticAddressSetFactory is StaticThresholdAddressSetFactory {\n    /**\n     * @notice Deploys a StaticAddressSet contract address for the given\n     * values\n     * @dev Consider sorting addresses to ensure contract reuse\n     * @param _values An array of addresses\n     * @return set The contract address representing this StaticAddressSet\n     */\n    function deploy(address[] calldata _values) external returns (address) {\n        return super.deploy(_values, uint8(_values.length));\n    }\n\n    /**\n     * @notice Returns the StaticAddressSet contract address for the given\n     * values\n     * @dev Consider sorting addresses to ensure contract reuse\n     * @param _values An array of addresses\n     * @return set The contract address representing this StaticAddressSet\n     */\n    function getAddress(\n        address[] calldata _values\n    ) external view returns (address) {\n        (bytes32 _salt, bytes memory _bytecode) = _saltAndBytecode(\n            _values,\n            uint8(_values.length)\n        );\n        return super._getAddress(_salt, _bytecode);\n    }\n}\n"},"contracts/libs/StaticWeightedValidatorSetFactory.sol":{"content":"// SPDX-License-Identifier: MIT OR Apache-2.0\npragma solidity >=0.8.0;\n// ============ External Imports ============\n\nimport {Address} from \"@openzeppelin/contracts/utils/Address.sol\";\nimport {Create2} from \"@openzeppelin/contracts/utils/Create2.sol\";\nimport {IStaticWeightedMultisigIsm} from \"../interfaces/isms/IWeightedMultisigIsm.sol\";\n\n// ============ Internal Imports ============\nimport {MetaProxy} from \"./MetaProxy.sol\";\nimport {PackageVersioned} from \"../PackageVersioned.sol\";\n\nabstract contract StaticWeightedValidatorSetFactory is PackageVersioned {\n    // ============ Immutables ============\n    address public immutable implementation;\n\n    // ============ Constructor ============\n\n    constructor() {\n        implementation = _deployImplementation();\n    }\n\n    function _deployImplementation() internal virtual returns (address);\n\n    /**\n     * @notice Deploys a StaticWeightedValidatorSet contract address for the given\n     * values\n     * @dev Consider sorting addresses to ensure contract reuse\n     * @param _validators An array of addresses\n     * @param _thresholdWeight The threshold weight value to use\n     * @return set The contract address representing this StaticWeightedValidatorSet\n     */\n    function deploy(\n        IStaticWeightedMultisigIsm.ValidatorInfo[] calldata _validators,\n        uint96 _thresholdWeight\n    ) public returns (address) {\n        (bytes32 _salt, bytes memory _bytecode) = _saltAndBytecode(\n            _validators,\n            _thresholdWeight\n        );\n        address _set = _getAddress(_salt, _bytecode);\n        if (!Address.isContract(_set)) {\n            _set = Create2.deploy(0, _salt, _bytecode);\n        }\n        return _set;\n    }\n\n    /**\n     * @notice Returns the StaticWeightedValidatorSet contract address for the given\n     * values\n     * @dev Consider sorting addresses to ensure contract reuse\n     * @param _validators An array of addresses\n     * @param _thresholdWeight The threshold weight value to use\n     * @return set The contract address representing this StaticWeightedValidatorSet\n     */\n    function getAddress(\n        IStaticWeightedMultisigIsm.ValidatorInfo[] calldata _validators,\n        uint96 _thresholdWeight\n    ) external view returns (address) {\n        (bytes32 _salt, bytes memory _bytecode) = _saltAndBytecode(\n            _validators,\n            _thresholdWeight\n        );\n        return _getAddress(_salt, _bytecode);\n    }\n\n    /**\n     * @notice Returns the StaticWeightedValidatorSet contract address for the given\n     * values\n     * @param _salt The salt used in Create2\n     * @param _bytecode The metaproxy bytecode used in Create2\n     * @return set The contract address representing this StaticWeightedValidatorSet\n     */\n    function _getAddress(\n        bytes32 _salt,\n        bytes memory _bytecode\n    ) internal view returns (address) {\n        bytes32 _bytecodeHash = keccak256(_bytecode);\n        return Create2.computeAddress(_salt, _bytecodeHash);\n    }\n\n    /**\n     * @notice Returns the create2 salt and bytecode for the given values\n     * @param _validators An array of addresses\n     * @param _thresholdWeight The threshold weight value to use\n     * @return _salt The salt used in Create2\n     * @return _bytecode The metaproxy bytecode used in Create2\n     */\n    function _saltAndBytecode(\n        IStaticWeightedMultisigIsm.ValidatorInfo[] calldata _validators,\n        uint96 _thresholdWeight\n    ) internal view returns (bytes32, bytes memory) {\n        bytes memory _metadata = abi.encode(_validators, _thresholdWeight);\n        bytes memory _bytecode = MetaProxy.bytecode(implementation, _metadata);\n        bytes32 _salt = keccak256(_metadata);\n        return (_salt, _bytecode);\n    }\n}\n"},"contracts/libs/TypeCasts.sol":{"content":"// SPDX-License-Identifier: MIT OR Apache-2.0\npragma solidity >=0.6.11;\n\nlibrary TypeCasts {\n    // alignment preserving cast\n    function addressToBytes32(address _addr) internal pure returns (bytes32) {\n        return bytes32(uint256(uint160(_addr)));\n    }\n\n    // alignment preserving cast\n    function bytes32ToAddress(bytes32 _buf) internal pure returns (address) {\n        require(\n            uint256(_buf) <= uint256(type(uint160).max),\n            \"TypeCasts: bytes32ToAddress overflow\"\n        );\n        return address(uint160(uint256(_buf)));\n    }\n}\n"},"contracts/libs/TypedMemView.sol":{"content":"// SPDX-License-Identifier: MIT OR Apache-2.0\npragma solidity >=0.8.12;\n\nlibrary TypedMemView {\n    // Why does this exist?\n    // the solidity `bytes memory` type has a few weaknesses.\n    // 1. You can't index ranges effectively\n    // 2. You can't slice without copying\n    // 3. The underlying data may represent any type\n    // 4. Solidity never deallocates memory, and memory costs grow\n    //    superlinearly\n\n    // By using a memory view instead of a `bytes memory` we get the following\n    // advantages:\n    // 1. Slices are done on the stack, by manipulating the pointer\n    // 2. We can index arbitrary ranges and quickly convert them to stack types\n    // 3. We can insert type info into the pointer, and typecheck at runtime\n\n    // This makes `TypedMemView` a useful tool for efficient zero-copy\n    // algorithms.\n\n    // Why bytes29?\n    // We want to avoid confusion between views, digests, and other common\n    // types so we chose a large and uncommonly used odd number of bytes\n    //\n    // Note that while bytes are left-aligned in a word, integers and addresses\n    // are right-aligned. This means when working in assembly we have to\n    // account for the 3 unused bytes on the righthand side\n    //\n    // First 5 bytes are a type flag.\n    // - ff_ffff_fffe is reserved for unknown type.\n    // - ff_ffff_ffff is reserved for invalid types/errors.\n    // next 12 are memory address\n    // next 12 are len\n    // bottom 3 bytes are empty\n\n    // Assumptions:\n    // - non-modification of memory.\n    // - No Solidity updates\n    // - - wrt free mem point\n    // - - wrt bytes representation in memory\n    // - - wrt memory addressing in general\n\n    // Usage:\n    // - create type constants\n    // - use `assertType` for runtime type assertions\n    // - - unfortunately we can't do this at compile time yet :(\n    // - recommended: implement modifiers that perform type checking\n    // - - e.g.\n    // - - `uint40 constant MY_TYPE = 3;`\n    // - - ` modifier onlyMyType(bytes29 myView) { myView.assertType(MY_TYPE); }`\n    // - instantiate a typed view from a bytearray using `ref`\n    // - use `index` to inspect the contents of the view\n    // - use `slice` to create smaller views into the same memory\n    // - - `slice` can increase the offset\n    // - - `slice can decrease the length`\n    // - - must specify the output type of `slice`\n    // - - `slice` will return a null view if you try to overrun\n    // - - make sure to explicitly check for this with `notNull` or `assertType`\n    // - use `equal` for typed comparisons.\n\n    // The null view\n    bytes29 public constant NULL =\n        hex\"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\";\n    // Mask a low uint96\n    uint256 constant LOW_12_MASK = 0xffffffffffffffffffffffff;\n    // Shift constants\n    uint8 constant SHIFT_TO_LEN = 24;\n    uint8 constant SHIFT_TO_LOC = 96 + 24;\n    uint8 constant SHIFT_TO_TYPE = 96 + 96 + 24;\n    // For nibble encoding\n    bytes private constant NIBBLE_LOOKUP = \"0123456789abcdef\";\n\n    /**\n     * @notice Returns the encoded hex character that represents the lower 4 bits of the argument.\n     * @param _byte The byte\n     * @return _char The encoded hex character\n     */\n    function nibbleHex(uint8 _byte) internal pure returns (uint8 _char) {\n        uint8 _nibble = _byte & 0x0f; // keep bottom 4, 0 top 4\n        _char = uint8(NIBBLE_LOOKUP[_nibble]);\n    }\n\n    /**\n     * @notice      Returns a uint16 containing the hex-encoded byte.\n     * @param _b    The byte\n     * @return      encoded - The hex-encoded byte\n     */\n    function byteHex(uint8 _b) internal pure returns (uint16 encoded) {\n        encoded |= nibbleHex(_b >> 4); // top 4 bits\n        encoded <<= 8;\n        encoded |= nibbleHex(_b); // lower 4 bits\n    }\n\n    /**\n     * @notice      Encodes the uint256 to hex. `first` contains the encoded top 16 bytes.\n     *              `second` contains the encoded lower 16 bytes.\n     *\n     * @param _b    The 32 bytes as uint256\n     * @return      first - The top 16 bytes\n     * @return      second - The bottom 16 bytes\n     */\n    function encodeHex(\n        uint256 _b\n    ) internal pure returns (uint256 first, uint256 second) {\n        for (uint8 i = 31; i > 15; ) {\n            uint8 _byte = uint8(_b >> (i * 8));\n            first |= byteHex(_byte);\n            if (i != 16) {\n                first <<= 16;\n            }\n            unchecked {\n                i -= 1;\n            }\n        }\n\n        // abusing underflow here =_=\n        for (uint8 i = 15; i < 255; ) {\n            uint8 _byte = uint8(_b >> (i * 8));\n            second |= byteHex(_byte);\n            if (i != 0) {\n                second <<= 16;\n            }\n            unchecked {\n                i -= 1;\n            }\n        }\n    }\n\n    /**\n     * @notice          Changes the endianness of a uint256.\n     * @dev             https://graphics.stanford.edu/~seander/bithacks.html#ReverseParallel\n     * @param _b        The unsigned integer to reverse\n     * @return          v - The reversed value\n     */\n    function reverseUint256(uint256 _b) internal pure returns (uint256 v) {\n        v = _b;\n\n        // swap bytes\n        v =\n            ((v >> 8) &\n                0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) |\n            ((v &\n                0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) <<\n                8);\n        // swap 2-byte long pairs\n        v =\n            ((v >> 16) &\n                0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) |\n            ((v &\n                0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) <<\n                16);\n        // swap 4-byte long pairs\n        v =\n            ((v >> 32) &\n                0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) |\n            ((v &\n                0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) <<\n                32);\n        // swap 8-byte long pairs\n        v =\n            ((v >> 64) &\n                0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) |\n            ((v &\n                0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) <<\n                64);\n        // swap 16-byte long pairs\n        v = (v >> 128) | (v << 128);\n    }\n\n    /**\n     * @notice      Create a mask with the highest `_len` bits set.\n     * @param _len  The length\n     * @return      mask - The mask\n     */\n    function leftMask(uint8 _len) private pure returns (uint256 mask) {\n        // ugly. redo without assembly?\n        assembly {\n            // solhint-disable-previous-line no-inline-assembly\n            mask := sar(\n                sub(_len, 1),\n                0x8000000000000000000000000000000000000000000000000000000000000000\n            )\n        }\n    }\n\n    /**\n     * @notice      Return the null view.\n     * @return      bytes29 - The null view\n     */\n    function nullView() internal pure returns (bytes29) {\n        return NULL;\n    }\n\n    /**\n     * @notice      Check if the view is null.\n     * @return      bool - True if the view is null\n     */\n    function isNull(bytes29 memView) internal pure returns (bool) {\n        return memView == NULL;\n    }\n\n    /**\n     * @notice      Check if the view is not null.\n     * @return      bool - True if the view is not null\n     */\n    function notNull(bytes29 memView) internal pure returns (bool) {\n        return !isNull(memView);\n    }\n\n    /**\n     * @notice          Check if the view is of a valid type and points to a valid location\n     *                  in memory.\n     * @dev             We perform this check by examining solidity's unallocated memory\n     *                  pointer and ensuring that the view's upper bound is less than that.\n     * @param memView   The view\n     * @return          ret - True if the view is valid\n     */\n    function isValid(bytes29 memView) internal pure returns (bool ret) {\n        if (typeOf(memView) == 0xffffffffff) return false;\n        uint256 _end = end(memView);\n        assembly {\n            // solhint-disable-previous-line no-inline-assembly\n            ret := iszero(gt(_end, mload(0x40)))\n        }\n    }\n\n    /**\n     * @notice          Require that a typed memory view be valid.\n     * @dev             Returns the view for easy chaining.\n     * @param memView   The view\n     * @return          bytes29 - The validated view\n     */\n    function assertValid(bytes29 memView) internal pure returns (bytes29) {\n        require(isValid(memView), \"Validity assertion failed\");\n        return memView;\n    }\n\n    /**\n     * @notice          Return true if the memview is of the expected type. Otherwise false.\n     * @param memView   The view\n     * @param _expected The expected type\n     * @return          bool - True if the memview is of the expected type\n     */\n    function isType(\n        bytes29 memView,\n        uint40 _expected\n    ) internal pure returns (bool) {\n        return typeOf(memView) == _expected;\n    }\n\n    /**\n     * @notice          Require that a typed memory view has a specific type.\n     * @dev             Returns the view for easy chaining.\n     * @param memView   The view\n     * @param _expected The expected type\n     * @return          bytes29 - The view with validated type\n     */\n    function assertType(\n        bytes29 memView,\n        uint40 _expected\n    ) internal pure returns (bytes29) {\n        if (!isType(memView, _expected)) {\n            (, uint256 g) = encodeHex(uint256(typeOf(memView)));\n            (, uint256 e) = encodeHex(uint256(_expected));\n            string memory err = string(\n                abi.encodePacked(\n                    \"Type assertion failed. Got 0x\",\n                    uint80(g),\n                    \". Expected 0x\",\n                    uint80(e)\n                )\n            );\n            revert(err);\n        }\n        return memView;\n    }\n\n    /**\n     * @notice          Return an identical view with a different type.\n     * @param memView   The view\n     * @param _newType  The new type\n     * @return          newView - The new view with the specified type\n     */\n    function castTo(\n        bytes29 memView,\n        uint40 _newType\n    ) internal pure returns (bytes29 newView) {\n        // then | in the new type\n        uint256 _typeShift = SHIFT_TO_TYPE;\n        uint256 _typeBits = 40;\n        assembly {\n            // solhint-disable-previous-line no-inline-assembly\n            // shift off the top 5 bytes\n            newView := or(newView, shr(_typeBits, shl(_typeBits, memView)))\n            newView := or(newView, shl(_typeShift, _newType))\n        }\n    }\n\n    /**\n     * @notice          Unsafe raw pointer construction. This should generally not be called\n     *                  directly. Prefer `ref` wherever possible.\n     * @dev             Unsafe raw pointer construction. This should generally not be called\n     *                  directly. Prefer `ref` wherever possible.\n     * @param _type     The type\n     * @param _loc      The memory address\n     * @param _len      The length\n     * @return          newView - The new view with the specified type, location and length\n     */\n    function unsafeBuildUnchecked(\n        uint256 _type,\n        uint256 _loc,\n        uint256 _len\n    ) private pure returns (bytes29 newView) {\n        uint256 _uint96Bits = 96;\n        uint256 _emptyBits = 24;\n        assembly {\n            // solium-disable-previous-line security/no-inline-assembly\n            newView := shl(_uint96Bits, or(newView, _type)) // insert type\n            newView := shl(_uint96Bits, or(newView, _loc)) // insert loc\n            newView := shl(_emptyBits, or(newView, _len)) // empty bottom 3 bytes\n        }\n    }\n\n    /**\n     * @notice          Instantiate a new memory view. This should generally not be called\n     *                  directly. Prefer `ref` wherever possible.\n     * @dev             Instantiate a new memory view. This should generally not be called\n     *                  directly. Prefer `ref` wherever possible.\n     * @param _type     The type\n     * @param _loc      The memory address\n     * @param _len      The length\n     * @return          newView - The new view with the specified type, location and length\n     */\n    function build(\n        uint256 _type,\n        uint256 _loc,\n        uint256 _len\n    ) internal pure returns (bytes29 newView) {\n        uint256 _end = _loc + _len;\n        assembly {\n            // solhint-disable-previous-line no-inline-assembly\n            if gt(_end, mload(0x40)) {\n                _end := 0\n            }\n        }\n        if (_end == 0) {\n            return NULL;\n        }\n        newView = unsafeBuildUnchecked(_type, _loc, _len);\n    }\n\n    /**\n     * @notice          Instantiate a memory view from a byte array.\n     * @dev             Note that due to Solidity memory representation, it is not possible to\n     *                  implement a deref, as the `bytes` type stores its len in memory.\n     * @param arr       The byte array\n     * @param newType   The type\n     * @return          bytes29 - The memory view\n     */\n    function ref(\n        bytes memory arr,\n        uint40 newType\n    ) internal pure returns (bytes29) {\n        uint256 _len = arr.length;\n\n        uint256 _loc;\n        assembly {\n            // solhint-disable-previous-line no-inline-assembly\n            _loc := add(arr, 0x20) // our view is of the data, not the struct\n        }\n\n        return build(newType, _loc, _len);\n    }\n\n    /**\n     * @notice          Return the associated type information.\n     * @param memView   The memory view\n     * @return          _type - The type associated with the view\n     */\n    function typeOf(bytes29 memView) internal pure returns (uint40 _type) {\n        uint256 _shift = SHIFT_TO_TYPE;\n        assembly {\n            // solium-disable-previous-line security/no-inline-assembly\n            _type := shr(_shift, memView) // shift out lower 27 bytes\n        }\n    }\n\n    /**\n     * @notice          Optimized type comparison. Checks that the 5-byte type flag is equal.\n     * @param left      The first view\n     * @param right     The second view\n     * @return          bool - True if the 5-byte type flag is equal\n     */\n    function sameType(\n        bytes29 left,\n        bytes29 right\n    ) internal pure returns (bool) {\n        return (left ^ right) >> SHIFT_TO_TYPE == 0;\n    }\n\n    /**\n     * @notice          Return the memory address of the underlying bytes.\n     * @param memView   The view\n     * @return          _loc - The memory address\n     */\n    function loc(bytes29 memView) internal pure returns (uint96 _loc) {\n        uint256 _mask = LOW_12_MASK; // assembly can't use globals\n        uint256 _shift = SHIFT_TO_LOC;\n        assembly {\n            // solium-disable-previous-line security/no-inline-assembly\n            _loc := and(shr(_shift, memView), _mask)\n        }\n    }\n\n    /**\n     * @notice          The number of memory words this memory view occupies, rounded up.\n     * @param memView   The view\n     * @return          uint256 - The number of memory words\n     */\n    function words(bytes29 memView) internal pure returns (uint256) {\n        return (uint256(len(memView)) + 31) / 32;\n    }\n\n    /**\n     * @notice          The in-memory footprint of a fresh copy of the view.\n     * @param memView   The view\n     * @return          uint256 - The in-memory footprint of a fresh copy of the view.\n     */\n    function footprint(bytes29 memView) internal pure returns (uint256) {\n        return words(memView) * 32;\n    }\n\n    /**\n     * @notice          The number of bytes of the view.\n     * @param memView   The view\n     * @return          _len - The length of the view\n     */\n    function len(bytes29 memView) internal pure returns (uint96 _len) {\n        uint256 _mask = LOW_12_MASK; // assembly can't use globals\n        uint256 _emptyBits = 24;\n        assembly {\n            // solium-disable-previous-line security/no-inline-assembly\n            _len := and(shr(_emptyBits, memView), _mask)\n        }\n    }\n\n    /**\n     * @notice          Returns the endpoint of `memView`.\n     * @param memView   The view\n     * @return          uint256 - The endpoint of `memView`\n     */\n    function end(bytes29 memView) internal pure returns (uint256) {\n        unchecked {\n            return loc(memView) + len(memView);\n        }\n    }\n\n    /**\n     * @notice          Safe slicing without memory modification.\n     * @param memView   The view\n     * @param _index    The start index\n     * @param _len      The length\n     * @param newType   The new type\n     * @return          bytes29 - The new view\n     */\n    function slice(\n        bytes29 memView,\n        uint256 _index,\n        uint256 _len,\n        uint40 newType\n    ) internal pure returns (bytes29) {\n        uint256 _loc = loc(memView);\n\n        // Ensure it doesn't overrun the view\n        if (_loc + _index + _len > end(memView)) {\n            return NULL;\n        }\n\n        _loc = _loc + _index;\n        return build(newType, _loc, _len);\n    }\n\n    /**\n     * @notice          Shortcut to `slice`. Gets a view representing the first `_len` bytes.\n     * @param memView   The view\n     * @param _len      The length\n     * @param newType   The new type\n     * @return          bytes29 - The new view\n     */\n    function prefix(\n        bytes29 memView,\n        uint256 _len,\n        uint40 newType\n    ) internal pure returns (bytes29) {\n        return slice(memView, 0, _len, newType);\n    }\n\n    /**\n     * @notice          Shortcut to `slice`. Gets a view representing the last `_len` byte.\n     * @param memView   The view\n     * @param _len      The length\n     * @param newType   The new type\n     * @return          bytes29 - The new view\n     */\n    function postfix(\n        bytes29 memView,\n        uint256 _len,\n        uint40 newType\n    ) internal pure returns (bytes29) {\n        return slice(memView, uint256(len(memView)) - _len, _len, newType);\n    }\n\n    /**\n     * @notice          Construct an error message for an indexing overrun.\n     * @param _loc      The memory address\n     * @param _len      The length\n     * @param _index    The index\n     * @param _slice    The slice where the overrun occurred\n     * @return          err - The err\n     */\n    function indexErrOverrun(\n        uint256 _loc,\n        uint256 _len,\n        uint256 _index,\n        uint256 _slice\n    ) internal pure returns (string memory err) {\n        (, uint256 a) = encodeHex(_loc);\n        (, uint256 b) = encodeHex(_len);\n        (, uint256 c) = encodeHex(_index);\n        (, uint256 d) = encodeHex(_slice);\n        err = string(\n            abi.encodePacked(\n                \"TypedMemView/index - Overran the view. Slice is at 0x\",\n                uint48(a),\n                \" with length 0x\",\n                uint48(b),\n                \". Attempted to index at offset 0x\",\n                uint48(c),\n                \" with length 0x\",\n                uint48(d),\n                \".\"\n            )\n        );\n    }\n\n    /**\n     * @notice          Load up to 32 bytes from the view onto the stack.\n     * @dev             Returns a bytes32 with only the `_bytes` highest bytes set.\n     *                  This can be immediately cast to a smaller fixed-length byte array.\n     *                  To automatically cast to an integer, use `indexUint`.\n     * @param memView   The view\n     * @param _index    The index\n     * @param _bytes    The bytes\n     * @return          result - The 32 byte result\n     */\n    function index(\n        bytes29 memView,\n        uint256 _index,\n        uint8 _bytes\n    ) internal pure returns (bytes32 result) {\n        if (_bytes == 0) return bytes32(0);\n        if (_index + _bytes > len(memView)) {\n            revert(\n                indexErrOverrun(\n                    loc(memView),\n                    len(memView),\n                    _index,\n                    uint256(_bytes)\n                )\n            );\n        }\n        require(\n            _bytes <= 32,\n            \"TypedMemView/index - Attempted to index more than 32 bytes\"\n        );\n\n        uint8 bitLength;\n        unchecked {\n            bitLength = _bytes * 8;\n        }\n        uint256 _loc = loc(memView);\n        uint256 _mask = leftMask(bitLength);\n        assembly {\n            // solhint-disable-previous-line no-inline-assembly\n            result := and(mload(add(_loc, _index)), _mask)\n        }\n    }\n\n    /**\n     * @notice          Parse an unsigned integer from the view at `_index`.\n     * @dev             Requires that the view have >= `_bytes` bytes following that index.\n     * @param memView   The view\n     * @param _index    The index\n     * @param _bytes    The bytes\n     * @return          result - The unsigned integer\n     */\n    function indexUint(\n        bytes29 memView,\n        uint256 _index,\n        uint8 _bytes\n    ) internal pure returns (uint256 result) {\n        return uint256(index(memView, _index, _bytes)) >> ((32 - _bytes) * 8);\n    }\n\n    /**\n     * @notice          Parse an unsigned integer from LE bytes.\n     * @param memView   The view\n     * @param _index    The index\n     * @param _bytes    The bytes\n     * @return          result - The unsigned integer\n     */\n    function indexLEUint(\n        bytes29 memView,\n        uint256 _index,\n        uint8 _bytes\n    ) internal pure returns (uint256 result) {\n        return reverseUint256(uint256(index(memView, _index, _bytes)));\n    }\n\n    /**\n     * @notice          Parse an address from the view at `_index`. Requires that the view have >= 20 bytes\n     *                  following that index.\n     * @param memView   The view\n     * @param _index    The index\n     * @return          address - The address\n     */\n    function indexAddress(\n        bytes29 memView,\n        uint256 _index\n    ) internal pure returns (address) {\n        return address(uint160(indexUint(memView, _index, 20)));\n    }\n\n    /**\n     * @notice          Return the keccak256 hash of the underlying memory\n     * @param memView   The view\n     * @return          digest - The keccak256 hash of the underlying memory\n     */\n    function keccak(bytes29 memView) internal pure returns (bytes32 digest) {\n        uint256 _loc = loc(memView);\n        uint256 _len = len(memView);\n        assembly {\n            // solhint-disable-previous-line no-inline-assembly\n            digest := keccak256(_loc, _len)\n        }\n    }\n\n    /**\n     * @notice          Return the sha2 digest of the underlying memory.\n     * @dev             We explicitly deallocate memory afterwards.\n     * @param memView   The view\n     * @return          digest - The sha2 hash of the underlying memory\n     */\n    function sha2(bytes29 memView) internal view returns (bytes32 digest) {\n        uint256 _loc = loc(memView);\n        uint256 _len = len(memView);\n\n        bool res;\n        assembly {\n            // solhint-disable-previous-line no-inline-assembly\n            let ptr := mload(0x40)\n            res := staticcall(gas(), 2, _loc, _len, ptr, 0x20) // sha2 #1\n            digest := mload(ptr)\n        }\n        require(res, \"sha2 OOG\");\n    }\n\n    /**\n     * @notice          Implements bitcoin's hash160 (rmd160(sha2()))\n     * @param memView   The pre-image\n     * @return          digest - the Digest\n     */\n    function hash160(bytes29 memView) internal view returns (bytes20 digest) {\n        uint256 _loc = loc(memView);\n        uint256 _len = len(memView);\n        bool res;\n        assembly {\n            // solhint-disable-previous-line no-inline-assembly\n            let ptr := mload(0x40)\n            res := staticcall(gas(), 2, _loc, _len, ptr, 0x20) // sha2\n            res := and(res, staticcall(gas(), 3, ptr, 0x20, ptr, 0x20)) // rmd160\n            digest := mload(add(ptr, 0xc)) // return value is 0-prefixed.\n        }\n        require(res, \"hash160 OOG\");\n    }\n\n    /**\n     * @notice          Implements bitcoin's hash256 (double sha2)\n     * @param memView   A view of the preimage\n     * @return          digest - the Digest\n     */\n    function hash256(bytes29 memView) internal view returns (bytes32 digest) {\n        uint256 _loc = loc(memView);\n        uint256 _len = len(memView);\n        bool res;\n        assembly {\n            // solhint-disable-previous-line no-inline-assembly\n            let ptr := mload(0x40)\n            res := staticcall(gas(), 2, _loc, _len, ptr, 0x20) // sha2 #1\n            res := and(res, staticcall(gas(), 2, ptr, 0x20, ptr, 0x20)) // sha2 #2\n            digest := mload(ptr)\n        }\n        require(res, \"hash256 OOG\");\n    }\n\n    /**\n     * @notice          Return true if the underlying memory is equal. Else false.\n     * @param left      The first view\n     * @param right     The second view\n     * @return          bool - True if the underlying memory is equal\n     */\n    function untypedEqual(\n        bytes29 left,\n        bytes29 right\n    ) internal pure returns (bool) {\n        return\n            (loc(left) == loc(right) && len(left) == len(right)) ||\n            keccak(left) == keccak(right);\n    }\n\n    /**\n     * @notice          Return false if the underlying memory is equal. Else true.\n     * @param left      The first view\n     * @param right     The second view\n     * @return          bool - False if the underlying memory is equal\n     */\n    function untypedNotEqual(\n        bytes29 left,\n        bytes29 right\n    ) internal pure returns (bool) {\n        return !untypedEqual(left, right);\n    }\n\n    /**\n     * @notice          Compares type equality.\n     * @dev             Shortcuts if the pointers are identical, otherwise compares type and digest.\n     * @param left      The first view\n     * @param right     The second view\n     * @return          bool - True if the types are the same\n     */\n    function equal(bytes29 left, bytes29 right) internal pure returns (bool) {\n        return\n            left == right ||\n            (typeOf(left) == typeOf(right) && keccak(left) == keccak(right));\n    }\n\n    /**\n     * @notice          Compares type inequality.\n     * @dev             Shortcuts if the pointers are identical, otherwise compares type and digest.\n     * @param left      The first view\n     * @param right     The second view\n     * @return          bool - True if the types are not the same\n     */\n    function notEqual(\n        bytes29 left,\n        bytes29 right\n    ) internal pure returns (bool) {\n        return !equal(left, right);\n    }\n\n    /**\n     * @notice          Copy the view to a location, return an unsafe memory reference\n     * @dev             Super Dangerous direct memory access.\n     *\n     *                  This reference can be overwritten if anything else modifies memory (!!!).\n     *                  As such it MUST be consumed IMMEDIATELY.\n     *                  This function is private to prevent unsafe usage by callers.\n     * @param memView   The view\n     * @param _newLoc   The new location\n     * @return          written - the unsafe memory reference\n     */\n    function unsafeCopyTo(\n        bytes29 memView,\n        uint256 _newLoc\n    ) private view returns (bytes29 written) {\n        require(notNull(memView), \"TypedMemView/copyTo - Null pointer deref\");\n        require(\n            isValid(memView),\n            \"TypedMemView/copyTo - Invalid pointer deref\"\n        );\n        uint256 _len = len(memView);\n        uint256 _oldLoc = loc(memView);\n\n        uint256 ptr;\n        bool res;\n        assembly {\n            // solhint-disable-previous-line no-inline-assembly\n            ptr := mload(0x40)\n            // revert if we're writing in occupied memory\n            if gt(ptr, _newLoc) {\n                revert(0x60, 0x20)\n            } // empty revert message\n\n            // use the identity precompile to copy\n            res := staticcall(gas(), 4, _oldLoc, _len, _newLoc, _len)\n        }\n        require(res, \"identity OOG\");\n        written = unsafeBuildUnchecked(typeOf(memView), _newLoc, _len);\n    }\n\n    /**\n     * @notice          Copies the referenced memory to a new loc in memory, returning a `bytes` pointing to\n     *                  the new memory\n     * @dev             Shortcuts if the pointers are identical, otherwise compares type and digest.\n     * @param memView   The view\n     * @return          ret - The view pointing to the new memory\n     */\n    function clone(bytes29 memView) internal view returns (bytes memory ret) {\n        uint256 ptr;\n        uint256 _len = len(memView);\n        assembly {\n            // solhint-disable-previous-line no-inline-assembly\n            ptr := mload(0x40) // load unused memory pointer\n            ret := ptr\n        }\n        unchecked {\n            unsafeCopyTo(memView, ptr + 0x20);\n        }\n        assembly {\n            // solhint-disable-previous-line no-inline-assembly\n            mstore(0x40, add(add(ptr, _len), 0x20)) // write new unused pointer\n            mstore(ptr, _len) // write len of new array (in bytes)\n        }\n    }\n\n    /**\n     * @notice          Join the views in memory, return an unsafe reference to the memory.\n     * @dev             Super Dangerous direct memory access.\n     *\n     *                  This reference can be overwritten if anything else modifies memory (!!!).\n     *                  As such it MUST be consumed IMMEDIATELY.\n     *                  This function is private to prevent unsafe usage by callers.\n     * @param memViews  The views\n     * @param _location The location in memory to which to copy & concatenate\n     * @return          unsafeView - The conjoined view pointing to the new memory\n     */\n    function unsafeJoin(\n        bytes29[] memory memViews,\n        uint256 _location\n    ) private view returns (bytes29 unsafeView) {\n        assembly {\n            // solhint-disable-previous-line no-inline-assembly\n            let ptr := mload(0x40)\n            // revert if we're writing in occupied memory\n            if gt(ptr, _location) {\n                revert(0x60, 0x20)\n            } // empty revert message\n        }\n\n        uint256 _offset = 0;\n        for (uint256 i = 0; i < memViews.length; i++) {\n            bytes29 memView = memViews[i];\n            unchecked {\n                unsafeCopyTo(memView, _location + _offset);\n                _offset += len(memView);\n            }\n        }\n        unsafeView = unsafeBuildUnchecked(0, _location, _offset);\n    }\n\n    /**\n     * @notice          Produce the keccak256 digest of the concatenated contents of multiple views.\n     * @param memViews  The views\n     * @return          bytes32 - The keccak256 digest\n     */\n    function joinKeccak(\n        bytes29[] memory memViews\n    ) internal view returns (bytes32) {\n        uint256 ptr;\n        assembly {\n            // solhint-disable-previous-line no-inline-assembly\n            ptr := mload(0x40) // load unused memory pointer\n        }\n        return keccak(unsafeJoin(memViews, ptr));\n    }\n\n    /**\n     * @notice          Produce the sha256 digest of the concatenated contents of multiple views.\n     * @param memViews  The views\n     * @return          bytes32 - The sha256 digest\n     */\n    function joinSha2(\n        bytes29[] memory memViews\n    ) internal view returns (bytes32) {\n        uint256 ptr;\n        assembly {\n            // solhint-disable-previous-line no-inline-assembly\n            ptr := mload(0x40) // load unused memory pointer\n        }\n        return sha2(unsafeJoin(memViews, ptr));\n    }\n\n    /**\n     * @notice          copies all views, joins them into a new bytearray.\n     * @param memViews  The views\n     * @return          ret - The new byte array\n     */\n    function join(\n        bytes29[] memory memViews\n    ) internal view returns (bytes memory ret) {\n        uint256 ptr;\n        assembly {\n            // solhint-disable-previous-line no-inline-assembly\n            ptr := mload(0x40) // load unused memory pointer\n        }\n\n        bytes29 _newView;\n        unchecked {\n            _newView = unsafeJoin(memViews, ptr + 0x20);\n        }\n        uint256 _written = len(_newView);\n        uint256 _footprint = footprint(_newView);\n\n        assembly {\n            // solhint-disable-previous-line no-inline-assembly\n            // store the length\n            mstore(ptr, _written)\n            // new pointer is old + 0x20 + the footprint of the body\n            mstore(0x40, add(add(ptr, _footprint), 0x20))\n            ret := ptr\n        }\n    }\n}\n"},"contracts/Mailbox.sol":{"content":"// SPDX-License-Identifier: MIT OR Apache-2.0\npragma solidity >=0.8.0;\n\n// ============ Internal Imports ============\nimport {Versioned} from \"./upgrade/Versioned.sol\";\nimport {Indexed} from \"./libs/Indexed.sol\";\nimport {Message} from \"./libs/Message.sol\";\nimport {TypeCasts} from \"./libs/TypeCasts.sol\";\nimport {IInterchainSecurityModule, ISpecifiesInterchainSecurityModule} from \"./interfaces/IInterchainSecurityModule.sol\";\nimport {IPostDispatchHook} from \"./interfaces/hooks/IPostDispatchHook.sol\";\nimport {IMessageRecipient} from \"./interfaces/IMessageRecipient.sol\";\nimport {IMailbox} from \"./interfaces/IMailbox.sol\";\nimport {PackageVersioned} from \"./PackageVersioned.sol\";\n\n// ============ External Imports ============\nimport {Address} from \"@openzeppelin/contracts/utils/Address.sol\";\nimport {OwnableUpgradeable} from \"@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol\";\n\ncontract Mailbox is\n    IMailbox,\n    Indexed,\n    Versioned,\n    OwnableUpgradeable,\n    PackageVersioned\n{\n    // ============ Libraries ============\n\n    using Message for bytes;\n    using TypeCasts for bytes32;\n    using TypeCasts for address;\n\n    // ============ Constants ============\n\n    // Domain of chain on which the contract is deployed\n    uint32 public immutable localDomain;\n\n    // ============ Public Storage ============\n\n    // A monotonically increasing nonce for outbound unique message IDs.\n    uint32 public nonce;\n\n    // The latest dispatched message ID used for auth in post-dispatch hooks.\n    bytes32 public latestDispatchedId;\n\n    // The default ISM, used if the recipient fails to specify one.\n    IInterchainSecurityModule public defaultIsm;\n\n    // The default post dispatch hook, used for post processing of opting-in dispatches.\n    IPostDispatchHook public defaultHook;\n\n    // The required post dispatch hook, used for post processing of ALL dispatches.\n    IPostDispatchHook public requiredHook;\n\n    // Mapping of message ID to delivery context that processed the message.\n    struct Delivery {\n        address processor;\n        uint48 blockNumber;\n    }\n\n    mapping(bytes32 messageId => Delivery delivery) internal deliveries;\n\n    // ============ Events ============\n\n    /**\n     * @notice Emitted when the default ISM is updated\n     * @param module The new default ISM\n     */\n    event DefaultIsmSet(address indexed module);\n\n    /**\n     * @notice Emitted when the default hook is updated\n     * @param hook The new default hook\n     */\n    event DefaultHookSet(address indexed hook);\n\n    /**\n     * @notice Emitted when the required hook is updated\n     * @param hook The new required hook\n     */\n    event RequiredHookSet(address indexed hook);\n\n    // ============ Constructor ============\n    constructor(uint32 _localDomain) {\n        localDomain = _localDomain;\n    }\n\n    // ============ Initializers ============\n    function initialize(\n        address _owner,\n        address _defaultIsm,\n        address _defaultHook,\n        address _requiredHook\n    ) external initializer {\n        __Ownable_init();\n        setDefaultIsm(_defaultIsm);\n        setDefaultHook(_defaultHook);\n        setRequiredHook(_requiredHook);\n        transferOwnership(_owner);\n    }\n\n    // ============ External Functions ============\n    /**\n     * @notice Dispatches a message to the destination domain & recipient\n     * using the default hook and empty metadata.\n     * @param _destinationDomain Domain of destination chain\n     * @param _recipientAddress Address of recipient on destination chain as bytes32\n     * @param _messageBody Raw bytes content of message body\n     * @return The message ID inserted into the Mailbox's merkle tree\n     */\n    function dispatch(\n        uint32 _destinationDomain,\n        bytes32 _recipientAddress,\n        bytes calldata _messageBody\n    ) external payable override returns (bytes32) {\n        return\n            dispatch(\n                _destinationDomain,\n                _recipientAddress,\n                _messageBody,\n                _messageBody[0:0],\n                defaultHook\n            );\n    }\n\n    /**\n     * @notice Dispatches a message to the destination domain & recipient.\n     * @param destinationDomain Domain of destination chain\n     * @param recipientAddress Address of recipient on destination chain as bytes32\n     * @param messageBody Raw bytes content of message body\n     * @param hookMetadata Metadata used by the post dispatch hook\n     * @return The message ID inserted into the Mailbox's merkle tree\n     */\n    function dispatch(\n        uint32 destinationDomain,\n        bytes32 recipientAddress,\n        bytes calldata messageBody,\n        bytes calldata hookMetadata\n    ) external payable override returns (bytes32) {\n        return\n            dispatch(\n                destinationDomain,\n                recipientAddress,\n                messageBody,\n                hookMetadata,\n                defaultHook\n            );\n    }\n\n    /**\n     * @notice Computes quote for dipatching a message to the destination domain & recipient\n     * using the default hook and empty metadata.\n     * @param destinationDomain Domain of destination chain\n     * @param recipientAddress Address of recipient on destination chain as bytes32\n     * @param messageBody Raw bytes content of message body\n     * @return fee The payment required to dispatch the message\n     */\n    function quoteDispatch(\n        uint32 destinationDomain,\n        bytes32 recipientAddress,\n        bytes calldata messageBody\n    ) external view returns (uint256 fee) {\n        return\n            quoteDispatch(\n                destinationDomain,\n                recipientAddress,\n                messageBody,\n                messageBody[0:0],\n                defaultHook\n            );\n    }\n\n    /**\n     * @notice Computes quote for dispatching a message to the destination domain & recipient.\n     * @param destinationDomain Domain of destination chain\n     * @param recipientAddress Address of recipient on destination chain as bytes32\n     * @param messageBody Raw bytes content of message body\n     * @param defaultHookMetadata Metadata used by the default post dispatch hook\n     * @return fee The payment required to dispatch the message\n     */\n    function quoteDispatch(\n        uint32 destinationDomain,\n        bytes32 recipientAddress,\n        bytes calldata messageBody,\n        bytes calldata defaultHookMetadata\n    ) external view returns (uint256 fee) {\n        return\n            quoteDispatch(\n                destinationDomain,\n                recipientAddress,\n                messageBody,\n                defaultHookMetadata,\n                defaultHook\n            );\n    }\n\n    /**\n     * @notice Attempts to deliver `_message` to its recipient. Verifies\n     * `_message` via the recipient's ISM using the provided `_metadata`.\n     * @param _metadata Metadata used by the ISM to verify `_message`.\n     * @param _message Formatted Hyperlane message (refer to Message.sol).\n     */\n    function process(\n        bytes calldata _metadata,\n        bytes calldata _message\n    ) external payable override {\n        /// CHECKS ///\n\n        // Check that the message was intended for this mailbox.\n        require(_message.version() == VERSION, \"Mailbox: bad version\");\n        require(\n            _message.destination() == localDomain,\n            \"Mailbox: unexpected destination\"\n        );\n\n        // Check that the message hasn't already been delivered.\n        bytes32 _id = _message.id();\n        require(delivered(_id) == false, \"Mailbox: already delivered\");\n\n        // Get the recipient's ISM.\n        address recipient = _message.recipientAddress();\n        IInterchainSecurityModule ism = recipientIsm(recipient);\n\n        /// EFFECTS ///\n\n        deliveries[_id] = Delivery({\n            processor: msg.sender,\n            blockNumber: uint48(block.number)\n        });\n        emit Process(_message.origin(), _message.sender(), recipient);\n        emit ProcessId(_id);\n\n        /// INTERACTIONS ///\n\n        // Verify the message via the interchain security module.\n        require(\n            ism.verify(_metadata, _message),\n            \"Mailbox: ISM verification failed\"\n        );\n\n        // Deliver the message to the recipient.\n        IMessageRecipient(recipient).handle{value: msg.value}(\n            _message.origin(),\n            _message.sender(),\n            _message.body()\n        );\n    }\n\n    /**\n     * @notice Returns the account that processed the message.\n     * @param _id The message ID to check.\n     * @return The account that processed the message.\n     */\n    function processor(bytes32 _id) external view returns (address) {\n        return deliveries[_id].processor;\n    }\n\n    /**\n     * @notice Returns the account that processed the message.\n     * @param _id The message ID to check.\n     * @return The number of the block that the message was processed at.\n     */\n    function processedAt(bytes32 _id) external view returns (uint48) {\n        return deliveries[_id].blockNumber;\n    }\n\n    // ============ Public Functions ============\n\n    /**\n     * @notice Dispatches a message to the destination domain & recipient.\n     * @param destinationDomain Domain of destination chain\n     * @param recipientAddress Address of recipient on destination chain as bytes32\n     * @param messageBody Raw bytes content of message body\n     * @param metadata Metadata used by the post dispatch hook\n     * @param hook Custom hook to use instead of the default\n     * @return The message ID inserted into the Mailbox's merkle tree\n     */\n    function dispatch(\n        uint32 destinationDomain,\n        bytes32 recipientAddress,\n        bytes calldata messageBody,\n        bytes calldata metadata,\n        IPostDispatchHook hook\n    ) public payable virtual returns (bytes32) {\n        if (address(hook) == address(0)) {\n            hook = defaultHook;\n        }\n\n        /// CHECKS ///\n\n        // Format the message into packed bytes.\n        bytes memory message = _buildMessage(\n            destinationDomain,\n            recipientAddress,\n            messageBody\n        );\n        bytes32 id = message.id();\n\n        /// EFFECTS ///\n\n        latestDispatchedId = id;\n        nonce += 1;\n        emit Dispatch(msg.sender, destinationDomain, recipientAddress, message);\n        emit DispatchId(id);\n\n        /// INTERACTIONS ///\n        uint256 requiredValue = requiredHook.quoteDispatch(metadata, message);\n        // if underpaying, defer to required hook's reverting behavior\n        if (msg.value < requiredValue) {\n            requiredValue = msg.value;\n        }\n        requiredHook.postDispatch{value: requiredValue}(metadata, message);\n        hook.postDispatch{value: msg.value - requiredValue}(metadata, message);\n\n        return id;\n    }\n\n    /**\n     * @notice Computes quote for dispatching a message to the destination domain & recipient.\n     * @param destinationDomain Domain of destination chain\n     * @param recipientAddress Address of recipient on destination chain as bytes32\n     * @param messageBody Raw bytes content of message body\n     * @param metadata Metadata used by the post dispatch hook\n     * @param hook Custom hook to use instead of the default\n     * @return fee The payment required to dispatch the message\n     */\n    function quoteDispatch(\n        uint32 destinationDomain,\n        bytes32 recipientAddress,\n        bytes calldata messageBody,\n        bytes calldata metadata,\n        IPostDispatchHook hook\n    ) public view returns (uint256 fee) {\n        if (address(hook) == address(0)) {\n            hook = defaultHook;\n        }\n\n        bytes memory message = _buildMessage(\n            destinationDomain,\n            recipientAddress,\n            messageBody\n        );\n        return\n            requiredHook.quoteDispatch(metadata, message) +\n            hook.quoteDispatch(metadata, message);\n    }\n\n    /**\n     * @notice Returns true if the message has been processed.\n     * @param _id The message ID to check.\n     * @return True if the message has been delivered.\n     */\n    function delivered(bytes32 _id) public view override returns (bool) {\n        return deliveries[_id].blockNumber > 0;\n    }\n\n    /**\n     * @notice Sets the default ISM for the Mailbox.\n     * @param _module The new default ISM. Must be a contract.\n     */\n    function setDefaultIsm(address _module) public onlyOwner {\n        require(\n            Address.isContract(_module),\n            \"Mailbox: default ISM not contract\"\n        );\n        defaultIsm = IInterchainSecurityModule(_module);\n        emit DefaultIsmSet(_module);\n    }\n\n    /**\n     * @notice Sets the default post dispatch hook for the Mailbox.\n     * @param _hook The new default post dispatch hook. Must be a contract.\n     */\n    function setDefaultHook(address _hook) public onlyOwner {\n        require(\n            Address.isContract(_hook),\n            \"Mailbox: default hook not contract\"\n        );\n        defaultHook = IPostDispatchHook(_hook);\n        emit DefaultHookSet(_hook);\n    }\n\n    /**\n     * @notice Sets the required post dispatch hook for the Mailbox.\n     * @param _hook The new default post dispatch hook. Must be a contract.\n     */\n    function setRequiredHook(address _hook) public onlyOwner {\n        require(\n            Address.isContract(_hook),\n            \"Mailbox: required hook not contract\"\n        );\n        requiredHook = IPostDispatchHook(_hook);\n        emit RequiredHookSet(_hook);\n    }\n\n    /**\n     * @notice Returns the ISM to use for the recipient, defaulting to the\n     * default ISM if none is specified.\n     * @param _recipient The message recipient whose ISM should be returned.\n     * @return The ISM to use for `_recipient`.\n     */\n    function recipientIsm(\n        address _recipient\n    ) public view returns (IInterchainSecurityModule) {\n        // use low-level staticcall in case of revert or empty return data\n        (bool success, bytes memory returnData) = _recipient.staticcall(\n            abi.encodeCall(\n                ISpecifiesInterchainSecurityModule.interchainSecurityModule,\n                ()\n            )\n        );\n        // check if call was successful and returned data\n        if (success && returnData.length != 0) {\n            // check if returnData is a valid address\n            address ism = abi.decode(returnData, (address));\n            // check if the ISM is a contract\n            if (ism != address(0)) {\n                return IInterchainSecurityModule(ism);\n            }\n        }\n        // Use the default if a valid one is not specified by the recipient.\n        return defaultIsm;\n    }\n\n    // ============ Internal Functions ============\n    function _buildMessage(\n        uint32 destinationDomain,\n        bytes32 recipientAddress,\n        bytes calldata messageBody\n    ) internal view returns (bytes memory) {\n        return\n            Message.formatMessage(\n                VERSION,\n                nonce,\n                localDomain,\n                msg.sender.addressToBytes32(),\n                destinationDomain,\n                recipientAddress,\n                messageBody\n            );\n    }\n}\n"},"contracts/middleware/InterchainAccountRouter.sol":{"content":"// SPDX-License-Identifier: Apache-2.0\npragma solidity ^0.8.13;\n\n/*@@@@@@@       @@@@@@@@@\n @@@@@@@@@       @@@@@@@@@\n  @@@@@@@@@       @@@@@@@@@\n   @@@@@@@@@       @@@@@@@@@\n    @@@@@@@@@@@@@@@@@@@@@@@@@\n     @@@@@  HYPERLANE  @@@@@@@\n    @@@@@@@@@@@@@@@@@@@@@@@@@\n   @@@@@@@@@       @@@@@@@@@\n  @@@@@@@@@       @@@@@@@@@\n @@@@@@@@@       @@@@@@@@@\n@@@@@@@@@       @@@@@@@@*/\n\n// ============ Internal Imports ============\nimport {OwnableMulticall} from \"./libs/OwnableMulticall.sol\";\nimport {InterchainAccountMessage, InterchainAccountMessageReveal} from \"./libs/InterchainAccountMessage.sol\";\nimport {CallLib} from \"./libs/Call.sol\";\nimport {MinimalProxy} from \"../libs/MinimalProxy.sol\";\nimport {TypeCasts} from \"../libs/TypeCasts.sol\";\nimport {StandardHookMetadata} from \"../hooks/libs/StandardHookMetadata.sol\";\nimport {Router} from \"../client/Router.sol\";\nimport {IPostDispatchHook} from \"../interfaces/hooks/IPostDispatchHook.sol\";\nimport {IInterchainSecurityModule} from \"../interfaces/IInterchainSecurityModule.sol\";\nimport {CommitmentReadIsm} from \"../isms/ccip-read/CommitmentReadIsm.sol\";\nimport {Mailbox} from \"../Mailbox.sol\";\nimport {Message} from \"../libs/Message.sol\";\nimport {AbstractRoutingIsm} from \"../isms/routing/AbstractRoutingIsm.sol\";\nimport {StandardHookMetadata} from \"../hooks/libs/StandardHookMetadata.sol\";\n\n// ============ External Imports ============\nimport {Create2} from \"@openzeppelin/contracts/utils/Create2.sol\";\nimport {Address} from \"@openzeppelin/contracts/utils/Address.sol\";\n\n/*\n * @title A contract that allows accounts on chain A to call contracts via a\n * proxy contract on chain B.\n */\ncontract InterchainAccountRouter is Router, AbstractRoutingIsm {\n    // ============ Libraries ============\n\n    using TypeCasts for address;\n    using TypeCasts for bytes32;\n    using InterchainAccountMessage for bytes;\n    using Message for bytes;\n    using StandardHookMetadata for bytes;\n\n    // ============ Constants ============\n\n    address public immutable implementation;\n    bytes32 public immutable bytecodeHash;\n    CommitmentReadIsm public immutable CCIP_READ_ISM;\n    uint public immutable COMMIT_TX_GAS_USAGE;\n\n    // ============ Public Storage ============\n    mapping(uint32 destinationDomain => bytes32 ism) public isms;\n\n    // ============ Upgrade Gap ============\n\n    uint256[47] private __GAP;\n\n    // ============ Events ============\n\n    /**\n     * @notice Emitted when a default ISM is set for a remote domain\n     * @param domain The remote domain\n     * @param ism The address of the remote ISM\n     */\n    event RemoteIsmEnrolled(uint32 indexed domain, bytes32 ism);\n\n    /**\n     * @notice Emitted when an interchain call is dispatched to a remote domain\n     * @param destination The destination domain on which to make the call\n     * @param owner The local owner of the remote ICA\n     * @param router The address of the remote router\n     * @param ism The address of the remote ISM\n     * @param salt The salt used to derive the interchain account\n     */\n    event RemoteCallDispatched(\n        uint32 indexed destination,\n        address indexed owner,\n        bytes32 router,\n        bytes32 ism,\n        bytes32 salt\n    );\n\n    /**\n     * @notice Emitted when a commit-reveal interchain call is dispatched to a remote domain\n     * @param commitment The commitment that was dispatched\n     */\n    event CommitRevealDispatched(bytes32 indexed commitment);\n\n    /**\n     * @notice Emitted when an interchain account contract is deployed\n     * @param account The address of the proxy account that was created\n     * @param origin The domain of the chain where the message was sent from\n     * @param router The router on the origin domain\n     * @param owner The address of the account that sent the message\n     * @param ism The address of the local ISM\n     * @param salt The salt used to derive the interchain account\n     */\n    event InterchainAccountCreated(\n        address indexed account,\n        uint32 origin,\n        bytes32 router,\n        bytes32 owner,\n        address ism,\n        bytes32 salt\n    );\n\n    // ============ Constructor ============\n    constructor(\n        address _mailbox,\n        address _hook,\n        address _owner,\n        uint _commit_tx_gas_usage,\n        string[] memory _commitment_urls\n    ) Router(_mailbox) {\n        setHook(_hook);\n        _transferOwnership(_owner);\n\n        bytes memory bytecode = _implementationBytecode(address(this));\n        implementation = Create2.deploy(0, bytes32(0), bytecode);\n        bytecodeHash = _proxyBytecodeHash(implementation);\n\n        CCIP_READ_ISM = new CommitmentReadIsm(_owner, _commitment_urls);\n        COMMIT_TX_GAS_USAGE = _commit_tx_gas_usage;\n    }\n\n    function interchainSecurityModule()\n        external\n        view\n        override\n        returns (IInterchainSecurityModule)\n    {\n        return IInterchainSecurityModule(address(this));\n    }\n\n    /**\n     * @notice Registers the address of remote InterchainAccountRouter\n     * and ISM contracts to use as a default when making interchain calls\n     * @param _destination The remote domain\n     * @param _router The address of the remote InterchainAccountRouter\n     * @param _ism The address of the remote ISM\n     */\n    function enrollRemoteRouterAndIsm(\n        uint32 _destination,\n        bytes32 _router,\n        bytes32 _ism\n    ) external onlyOwner {\n        _enrollRemoteRouterAndIsm(_destination, _router, _ism);\n    }\n\n    /**\n     * @notice Registers the address of remote InterchainAccountRouters\n     * and ISM contracts to use as defaults when making interchain calls\n     * @param _destinations The remote domains\n     * @param _routers The address of the remote InterchainAccountRouters\n     * @param _isms The address of the remote ISMs\n     */\n    function enrollRemoteRouterAndIsms(\n        uint32[] calldata _destinations,\n        bytes32[] calldata _routers,\n        bytes32[] calldata _isms\n    ) external onlyOwner {\n        require(\n            _destinations.length == _routers.length &&\n                _destinations.length == _isms.length,\n            \"length mismatch\"\n        );\n        for (uint256 i = 0; i < _destinations.length; i++) {\n            _enrollRemoteRouterAndIsm(_destinations[i], _routers[i], _isms[i]);\n        }\n    }\n\n    // ============ External Functions ============\n    /**\n     * @notice Dispatches a sequence of remote calls to be made by an owner's\n     * interchain account on the destination domain\n     * @dev Uses the default router and ISM addresses for the destination\n     * domain, reverting if none have been configured\n     * @dev Recommend using CallLib.build to format the interchain calls.\n     * @param _destination The remote domain of the chain to make calls on\n     * @param _calls The sequence of calls to make\n     * @return The Hyperlane message ID\n     */\n    function callRemote(\n        uint32 _destination,\n        CallLib.Call[] calldata _calls\n    ) public payable returns (bytes32) {\n        return callRemote(_destination, _calls, bytes(\"\"));\n    }\n\n    /**\n     * @notice Dispatches a sequence of remote calls to be made by an owner's\n     * interchain account on the destination domain\n     * @dev Uses the default router and ISM addresses for the destination\n     * domain, reverting if none have been configured\n     * @dev Recommend using CallLib.build to format the interchain calls.\n     * @param _destination The remote domain of the chain to make calls on\n     * @param _calls The sequence of calls to make\n     * @param _hookMetadata The hook metadata to override with for the hook set by the owner\n     * @return The Hyperlane message ID\n     */\n    function callRemote(\n        uint32 _destination,\n        CallLib.Call[] calldata _calls,\n        bytes memory _hookMetadata\n    ) public payable returns (bytes32) {\n        bytes32 _router = routers(_destination);\n        bytes32 _ism = isms[_destination];\n        return\n            callRemoteWithOverrides(\n                _destination,\n                _router,\n                _ism,\n                _calls,\n                _hookMetadata\n            );\n    }\n\n    /**\n     * @notice Handles dispatched messages by relaying calls to the interchain account\n     * @param _origin The origin domain of the interchain account\n     * @param _sender The sender of the interchain message\n     * @param _message The InterchainAccountMessage containing the account\n     * owner, ISM, and sequence of calls to be relayed\n     * @dev Does not need to be onlyRemoteRouter, as this application is designed\n     * to receive messages from untrusted remote contracts.\n     */\n    function handle(\n        uint32 _origin,\n        bytes32 _sender,\n        bytes calldata _message\n    ) external payable override onlyMailbox {\n        InterchainAccountMessage.MessageType _messageType = _message\n            .messageType();\n        if (_messageType == InterchainAccountMessage.MessageType.REVEAL) {\n            // If the message is a reveal,\n            // the commitment should have been executed in the `verify` method of the ISM\n            // that verified this message. The commitment is deleted in `revealAndExecute`.\n            // Simply return.\n            return;\n        }\n\n        bytes32 _owner = _message.owner();\n        bytes32 _salt = _message.salt();\n        bytes32 _ism = _message.ism();\n\n        OwnableMulticall ica = getDeployedInterchainAccount(\n            _origin,\n            _owner,\n            _sender,\n            _ism.bytes32ToAddress(),\n            _salt\n        );\n\n        if (_messageType == InterchainAccountMessage.MessageType.CALLS) {\n            CallLib.Call[] memory calls = _message.calls();\n            ica.multicall{value: msg.value}(calls);\n        } else {\n            // This is definitely a message of type COMMITMENT\n            ica.setCommitment(_message.commitment());\n        }\n    }\n\n    function route(\n        bytes calldata _message\n    ) public view override returns (IInterchainSecurityModule) {\n        bytes calldata _body = _message.body();\n        InterchainAccountMessage.MessageType _messageType = _body.messageType();\n\n        // If the ISM is not set, we need to check if the message is a reveal\n        // If it is, we need to set the ISM to the CCIP read ISM\n        // Otherwise, we need to set the ISM to the default ISM\n        address _ism;\n        if (_messageType == InterchainAccountMessage.MessageType.REVEAL) {\n            _ism = InterchainAccountMessageReveal\n                .revealIsm(_body)\n                .bytes32ToAddress();\n            _ism = _ism == address(0) ? address(CCIP_READ_ISM) : _ism;\n        } else {\n            _ism = InterchainAccountMessage.ism(_body).bytes32ToAddress();\n            _ism = _ism == address(0) ? address(mailbox.defaultIsm()) : _ism;\n        }\n\n        return IInterchainSecurityModule(_ism);\n    }\n\n    /**\n     * @notice Returns the local address of an interchain account\n     * @dev This interchain account is not guaranteed to have been deployed\n     * @param _origin The remote origin domain of the interchain account\n     * @param _router The remote origin InterchainAccountRouter\n     * @param _owner The remote owner of the interchain account\n     * @param _ism The local address of the ISM\n     * @return The local address of the interchain account\n     */\n    function getLocalInterchainAccount(\n        uint32 _origin,\n        address _owner,\n        address _router,\n        address _ism\n    ) external view returns (OwnableMulticall) {\n        return\n            getLocalInterchainAccount(\n                _origin,\n                _owner.addressToBytes32(),\n                _router.addressToBytes32(),\n                _ism\n            );\n    }\n\n    /**\n     * @notice Returns the remote address of a locally owned interchain account\n     * @dev This interchain account is not guaranteed to have been deployed\n     * @dev This function will only work if the destination domain is\n     * EVM compatible\n     * @param _destination The remote destination domain of the interchain account\n     * @param _owner The local owner of the interchain account\n     * @return The remote address of the interchain account\n     */\n    function getRemoteInterchainAccount(\n        uint32 _destination,\n        address _owner\n    ) external view returns (address) {\n        return\n            getRemoteInterchainAccount(\n                _destination,\n                _owner,\n                InterchainAccountMessage.EMPTY_SALT\n            );\n    }\n\n    /**\n     * @notice Returns the remote address of a locally owned interchain account\n     * @dev This interchain account is not guaranteed to have been deployed\n     * @dev This function will only work if the destination domain is\n     * EVM compatible\n     * @param _destination The remote destination domain of the interchain account\n     * @param _owner The local owner of the interchain account\n     * @param _userSalt A user provided salt. Allows control over account derivation.\n     * @return The remote address of the interchain account\n     */\n    function getRemoteInterchainAccount(\n        uint32 _destination,\n        address _owner,\n        bytes32 _userSalt\n    ) public view returns (address) {\n        address _router = routers(_destination).bytes32ToAddress();\n        address _ism = isms[_destination].bytes32ToAddress();\n        return getRemoteInterchainAccount(_owner, _router, _ism, _userSalt);\n    }\n\n    // ============ Public Functions ============\n\n    /**\n     * @notice Returns and deploys (if not already) an interchain account\n     * @param _origin The remote origin domain of the interchain account\n     * @param _owner The remote owner of the interchain account\n     * @param _router The remote origin InterchainAccountRouter\n     * @param _ism The local address of the ISM\n     * @return The address of the interchain account\n     */\n    function getDeployedInterchainAccount(\n        uint32 _origin,\n        address _owner,\n        address _router,\n        address _ism\n    ) public returns (OwnableMulticall) {\n        return\n            getDeployedInterchainAccount(\n                _origin,\n                _owner.addressToBytes32(),\n                _router.addressToBytes32(),\n                _ism,\n                InterchainAccountMessage.EMPTY_SALT\n            );\n    }\n\n    /*\n     * @notice Returns and deploys (if not already) an interchain account\n     * @param _origin The remote origin domain of the interchain account\n     * @param _owner The remote owner of the interchain account\n     * @param _router The remote origin InterchainAccountRouter\n     * @param _ism The local address of the ISM\n     * @return The address of the interchain account\n     */\n    function getDeployedInterchainAccount(\n        uint32 _origin,\n        bytes32 _owner,\n        bytes32 _router,\n        address _ism\n    ) public returns (OwnableMulticall) {\n        return\n            getDeployedInterchainAccount(\n                _origin,\n                _owner,\n                _router,\n                _ism,\n                InterchainAccountMessage.EMPTY_SALT\n            );\n    }\n\n    /**\n     * @notice Returns and deploys (if not already) an interchain account\n     * @param _origin The remote origin domain of the interchain account\n     * @param _owner The remote owner of the interchain account\n     * @param _router The remote origin InterchainAccountRouter\n     * @param _ism The local address of the ISM\n     * @return The address of the interchain account\n     */\n    function getDeployedInterchainAccount(\n        uint32 _origin,\n        bytes32 _owner,\n        bytes32 _router,\n        address _ism,\n        bytes32 _userSalt\n    ) public returns (OwnableMulticall) {\n        bytes32 _deploySalt = _getSalt(\n            _origin,\n            _owner,\n            _router,\n            _ism.addressToBytes32(),\n            _userSalt\n        );\n        address payable _account = _getLocalInterchainAccount(_deploySalt);\n        if (!Address.isContract(_account)) {\n            bytes memory _bytecode = MinimalProxy.bytecode(implementation);\n            _account = payable(Create2.deploy(0, _deploySalt, _bytecode));\n            emit InterchainAccountCreated(\n                _account,\n                _origin,\n                _router,\n                _owner,\n                _ism,\n                _userSalt\n            );\n        }\n        return OwnableMulticall(_account);\n    }\n\n    /**\n     * @notice Returns the local address of a remotely owned interchain account\n     * @dev This interchain account is not guaranteed to have been deployed\n     * @param _origin The remote origin domain of the interchain account\n     * @param _owner The remote owner of the interchain account\n     * @param _router The remote InterchainAccountRouter\n     * @param _ism The local address of the ISM\n     * @return The local address of the interchain account\n     */\n    function getLocalInterchainAccount(\n        uint32 _origin,\n        bytes32 _owner,\n        bytes32 _router,\n        address _ism\n    ) public view returns (OwnableMulticall) {\n        return\n            getLocalInterchainAccount(\n                _origin,\n                _owner,\n                _router,\n                _ism,\n                InterchainAccountMessage.EMPTY_SALT\n            );\n    }\n\n    /**\n     * @notice Returns the local address of a remotely owned interchain account\n     * @dev This interchain account is not guaranteed to have been deployed\n     * @param _origin The remote origin domain of the interchain account\n     * @param _owner The remote owner of the interchain account\n     * @param _router The remote InterchainAccountRouter\n     * @param _ism The local address of the ISM\n     * @param _userSalt A user provided salt. Allows control over account derivation.\n     * @return The local address of the interchain account\n     */\n    function getLocalInterchainAccount(\n        uint32 _origin,\n        bytes32 _owner,\n        bytes32 _router,\n        address _ism,\n        bytes32 _userSalt\n    ) public view returns (OwnableMulticall) {\n        return\n            OwnableMulticall(\n                _getLocalInterchainAccount(\n                    _getSalt(\n                        _origin,\n                        _owner,\n                        _router,\n                        _ism.addressToBytes32(),\n                        _userSalt\n                    )\n                )\n            );\n    }\n\n    /**\n     * @notice Returns the remote address of a locally owned interchain account\n     * @dev This interchain account is not guaranteed to have been deployed\n     * @dev This function will only work if the destination domain is\n     * EVM compatible\n     * @param _owner The local owner of the interchain account\n     * @param _router The remote InterchainAccountRouter\n     * @param _ism The remote address of the ISM\n     * @return The remote address of the interchain account\n     */\n    function getRemoteInterchainAccount(\n        address _owner,\n        address _router,\n        address _ism\n    ) public view returns (address) {\n        return\n            getRemoteInterchainAccount(\n                _owner,\n                _router,\n                _ism,\n                InterchainAccountMessage.EMPTY_SALT\n            );\n    }\n\n    /**\n     * @notice Returns the remote address of a locally owned interchain account\n     * @dev This interchain account is not guaranteed to have been deployed\n     * @dev This function will only work if the destination domain is\n     * EVM compatible\n     * @param _owner The local owner of the interchain account\n     * @param _router The remote InterchainAccountRouter\n     * @param _ism The remote address of the ISM\n     * @param _userSalt Salt provided by the user, allows control over account derivation.\n     * @return The remote address of the interchain account\n     */\n    function getRemoteInterchainAccount(\n        address _owner,\n        address _router,\n        address _ism,\n        bytes32 _userSalt\n    ) public view returns (address) {\n        require(_router != address(0), \"no router specified for destination\");\n\n        // replicate router constructor Create2 derivation\n        address _implementation = Create2.computeAddress(\n            bytes32(0),\n            keccak256(_implementationBytecode(_router)),\n            _router\n        );\n\n        bytes32 _bytecodeHash = _proxyBytecodeHash(_implementation);\n        bytes32 _salt = _getSalt(\n            localDomain,\n            _owner.addressToBytes32(),\n            address(this).addressToBytes32(),\n            _ism.addressToBytes32(),\n            _userSalt\n        );\n        return Create2.computeAddress(_salt, _bytecodeHash, _router);\n    }\n\n    /**\n     * @notice Dispatches a sequence of remote calls to be made by an owner's\n     * interchain account on the destination domain\n     * @dev Recommend using CallLib.build to format the interchain calls\n     * @param _destination The remote domain of the chain to make calls on\n     * @param _router The remote router address\n     * @param _ism The remote ISM address\n     * @param _calls The sequence of calls to make\n     * @return The Hyperlane message ID\n     */\n    function callRemoteWithOverrides(\n        uint32 _destination,\n        bytes32 _router,\n        bytes32 _ism,\n        CallLib.Call[] calldata _calls\n    ) public payable returns (bytes32) {\n        return\n            callRemoteWithOverrides(\n                _destination,\n                _router,\n                _ism,\n                _calls,\n                bytes(\"\"),\n                InterchainAccountMessage.EMPTY_SALT\n            );\n    }\n\n    /**\n     * @notice Dispatches a sequence of remote calls to be made by an owner's\n     * interchain account on the destination domain\n     * @dev Recommend using CallLib.build to format the interchain calls\n     * @param _destination The remote domain of the chain to make calls on\n     * @param _router The remote router address\n     * @param _ism The remote ISM address\n     * @param _calls The sequence of calls to make\n     * @return The Hyperlane message ID\n     */\n    function callRemoteWithOverrides(\n        uint32 _destination,\n        bytes32 _router,\n        bytes32 _ism,\n        CallLib.Call[] calldata _calls,\n        bytes32 _userSalt\n    ) public payable returns (bytes32) {\n        return\n            callRemoteWithOverrides(\n                _destination,\n                _router,\n                _ism,\n                _calls,\n                bytes(\"\"),\n                _userSalt\n            );\n    }\n\n    /**\n     * @notice Dispatches a sequence of remote calls to be made by an owner's\n     * interchain account on the destination domain\n     * @dev Recommend using CallLib.build to format the interchain calls\n     * @param _destination The remote domain of the chain to make calls on\n     * @param _router The remote router address\n     * @param _ism The remote ISM address\n     * @param _calls The sequence of calls to make\n     * @param _hookMetadata The hook metadata to override with for the hook set by the owner\n     * @return The Hyperlane message ID\n     */\n    function callRemoteWithOverrides(\n        uint32 _destination,\n        bytes32 _router,\n        bytes32 _ism,\n        CallLib.Call[] calldata _calls,\n        bytes memory _hookMetadata\n    ) public payable returns (bytes32) {\n        return\n            callRemoteWithOverrides(\n                _destination,\n                _router,\n                _ism,\n                _calls,\n                _hookMetadata,\n                InterchainAccountMessage.EMPTY_SALT\n            );\n    }\n\n    /**\n     * @notice Dispatches a sequence of remote calls to be made by an owner's\n     * interchain account on the destination domain\n     * @dev Recommend using CallLib.build to format the interchain calls\n     * @param _destination The remote domain of the chain to make calls on\n     * @param _router The remote router address\n     * @param _ism The remote ISM address\n     * @param _calls The sequence of calls to make\n     * @param _hookMetadata The hook metadata to override with for the hook set by the owner\n     * @param _userSalt Salt provided by the user, allows control over account derivation.\n     * @return The Hyperlane message ID\n     */\n    function callRemoteWithOverrides(\n        uint32 _destination,\n        bytes32 _router,\n        bytes32 _ism,\n        CallLib.Call[] calldata _calls,\n        bytes memory _hookMetadata,\n        bytes32 _userSalt\n    ) public payable returns (bytes32) {\n        return\n            callRemoteWithOverrides(\n                _destination,\n                _router,\n                _ism,\n                _calls,\n                _hookMetadata,\n                _userSalt,\n                hook\n            );\n    }\n\n    /**\n     * @notice Dispatches a sequence of remote calls to be made by an owner's\n     * interchain account on the destination domain\n     * @dev Recommend using CallLib.build to format the interchain calls\n     * @param _destination The remote domain of the chain to make calls on\n     * @param _router The remote router address\n     * @param _ism The remote ISM address\n     * @param _calls The sequence of calls to make\n     * @param _hookMetadata The hook metadata to override with for the hook set by the owner\n     * @param _salt Salt which allows control over account derivation.\n     * @param _hook The hook to use after sending our message to the mailbox\n     * @return The Hyperlane message ID\n     */\n    function callRemoteWithOverrides(\n        uint32 _destination,\n        bytes32 _router,\n        bytes32 _ism,\n        CallLib.Call[] calldata _calls,\n        bytes memory _hookMetadata,\n        bytes32 _salt,\n        IPostDispatchHook _hook\n    ) public payable returns (bytes32) {\n        emit RemoteCallDispatched(\n            _destination,\n            msg.sender,\n            _router,\n            _ism,\n            _salt\n        );\n        bytes memory _body = InterchainAccountMessage.encode(\n            msg.sender,\n            _ism,\n            _calls,\n            _salt\n        );\n        return\n            _dispatchMessageWithHook(\n                _destination,\n                _router,\n                _body,\n                _hookMetadata,\n                _hook\n            );\n    }\n\n    // refunds from the commit dispatch call used to fund reveal dispatch call\n    receive() external payable {}\n\n    /**\n     * @notice Dispatches a commitment and reveal message to the destination domain.\n     *  Useful for when we want to keep calldata secret (e.g. when executing a swap\n     * @dev The commitment message is dispatched first, followed by the reveal message.\n     * To find the calladata, the user must fetch the calldata from the url provided by the OffChainLookupIsm\n     * specified in the _ccipReadIsm parameter.\n     * The revealed calladata is executed by the `revealAndExecute` function, which will be called the OffChainLookupIsm in its `verify` function.\n     * @param _destination The remote domain of the chain to make calls on\n     * @param _router The remote router address\n     * @param _ism The remote ISM address\n     * @param _hookMetadata The hook metadata to override with for the hook set by the owner\n     * @param _salt Salt which allows control over account derivation.\n     * @param _hook The hook to use after sending our message to the mailbox\n     * @param _commitment The commitment to dispatch\n     * @return _commitmentMsgId The Hyperlane message ID of the commitment message\n     * @return _revealMsgId The Hyperlane message ID of the reveal message\n     */\n    function callRemoteCommitReveal(\n        uint32 _destination,\n        bytes32 _router,\n        bytes32 _ism,\n        bytes32 _ccipReadIsm,\n        bytes memory _hookMetadata,\n        IPostDispatchHook _hook,\n        bytes32 _salt,\n        bytes32 _commitment\n    ) public payable returns (bytes32 _commitmentMsgId, bytes32 _revealMsgId) {\n        bytes memory _commitmentMsg = InterchainAccountMessage\n            .encodeCommitment({\n                _owner: msg.sender.addressToBytes32(),\n                _ism: _ism,\n                _commitment: _commitment,\n                _userSalt: _salt\n            });\n\n        emit RemoteCallDispatched(\n            _destination,\n            msg.sender,\n            _router,\n            _ism,\n            _salt\n        );\n        emit CommitRevealDispatched(_commitment);\n\n        _commitmentMsgId = _dispatchMessageWithValue(\n            _destination,\n            _router,\n            _commitmentMsg,\n            StandardHookMetadata.formatMetadata(\n                0,\n                COMMIT_TX_GAS_USAGE,\n                address(this),\n                bytes(\"\")\n            ),\n            _hook,\n            msg.value\n        );\n\n        bytes memory _revealMsg = InterchainAccountMessage.encodeReveal({\n            _ism: _ccipReadIsm,\n            _commitment: _commitment\n        });\n        _revealMsgId = _dispatchMessageWithValue(\n            _destination,\n            _router,\n            _revealMsg,\n            _hookMetadata,\n            _hook,\n            address(this).balance\n        );\n    }\n\n    function callRemoteCommitReveal(\n        uint32 _destination,\n        bytes32 _router,\n        bytes32 _ism,\n        bytes memory _hookMetadata,\n        IPostDispatchHook _hook,\n        bytes32 _salt,\n        bytes32 _commitment\n    ) public payable returns (bytes32 _commitmentMsgId, bytes32 _revealMsgId) {\n        return\n            callRemoteCommitReveal(\n                _destination,\n                _router,\n                _ism,\n                bytes32(0),\n                _hookMetadata,\n                _hook,\n                _salt,\n                _commitment\n            );\n    }\n\n    function callRemoteCommitReveal(\n        uint32 _destination,\n        bytes32 _commitment,\n        uint _gasLimit\n    ) public payable returns (bytes32 _commitmentMsgId, bytes32 _revealMsgId) {\n        bytes32 _router = routers(_destination);\n        bytes32 _ism = isms[_destination];\n\n        bytes memory hookMetadata = StandardHookMetadata.formatMetadata(\n            0,\n            _gasLimit,\n            msg.sender,\n            bytes(\"\")\n        );\n\n        return\n            callRemoteCommitReveal(\n                _destination,\n                _router,\n                _ism,\n                bytes32(0),\n                hookMetadata,\n                hook,\n                InterchainAccountMessage.EMPTY_SALT,\n                _commitment\n            );\n    }\n\n    // ============ Internal Functions ============\n    function _implementationBytecode(\n        address router\n    ) internal pure returns (bytes memory) {\n        return\n            abi.encodePacked(\n                type(OwnableMulticall).creationCode,\n                abi.encode(router)\n            );\n    }\n\n    function _proxyBytecodeHash(\n        address _implementation\n    ) internal pure returns (bytes32) {\n        return keccak256(MinimalProxy.bytecode(_implementation));\n    }\n\n    /**\n     * @dev Required for use of Router, compiler will not include this function in the bytecode\n     */\n    function _handle(uint32, bytes32, bytes calldata) internal pure override {\n        assert(false);\n    }\n\n    /**\n     * @notice Overrides Router._enrollRemoteRouter to also enroll a default ISM\n     * @param _destination The remote domain\n     * @param _address The address of the remote InterchainAccountRouter\n     * @dev Sets the default ISM to the zero address\n     */\n    function _enrollRemoteRouter(\n        uint32 _destination,\n        bytes32 _address\n    ) internal override {\n        _enrollRemoteRouterAndIsm(\n            _destination,\n            _address,\n            InterchainAccountMessage.EMPTY_SALT\n        );\n    }\n\n    // ============ Private Functions ============\n\n    /**\n     * @notice Registers the address of a remote ISM contract to use as default\n     * @param _destination The remote domain\n     * @param _ism The address of the remote ISM\n     */\n    function _enrollRemoteIsm(uint32 _destination, bytes32 _ism) private {\n        isms[_destination] = _ism;\n        emit RemoteIsmEnrolled(_destination, _ism);\n    }\n\n    /**\n     * @notice Registers the address of remote InterchainAccountRouter\n     * and ISM contracts to use as a default when making interchain calls\n     * @param _destination The remote domain\n     * @param _router The address of the remote InterchainAccountRouter\n     * @param _ism The address of the remote ISM\n     */\n    function _enrollRemoteRouterAndIsm(\n        uint32 _destination,\n        bytes32 _router,\n        bytes32 _ism\n    ) private {\n        require(\n            routers(_destination) == InterchainAccountMessage.EMPTY_SALT &&\n                isms[_destination] == InterchainAccountMessage.EMPTY_SALT,\n            \"router and ISM defaults are immutable once set\"\n        );\n        Router._enrollRemoteRouter(_destination, _router);\n        _enrollRemoteIsm(_destination, _ism);\n    }\n\n    /**\n     * @notice Dispatches an InterchainAccountMessage to the remote router\n     * @param _destination The remote domain\n     * @param _router The address of the remote InterchainAccountRouter\n     * @param _body The InterchainAccountMessage body\n     */\n    function _dispatchMessage(\n        uint32 _destination,\n        bytes32 _router,\n        bytes memory _body\n    ) private returns (bytes32) {\n        return\n            _dispatchMessageWithMetadata(\n                _destination,\n                _router,\n                _body,\n                bytes(\"\")\n            );\n    }\n\n    /**\n     * @notice Dispatches an InterchainAccountMessage to the remote router with hook metadata\n     * @param _destination The remote domain\n     * @param _router The address of the remote InterchainAccountRouter\n     * @param _body The InterchainAccountMessage body\n     * @param _hookMetadata The hook metadata to override with for the hook set by the owner\n     */\n    function _dispatchMessageWithMetadata(\n        uint32 _destination,\n        bytes32 _router,\n        bytes memory _body,\n        bytes memory _hookMetadata\n    ) private returns (bytes32) {\n        return\n            _dispatchMessageWithHook(\n                _destination,\n                _router,\n                _body,\n                _hookMetadata,\n                hook\n            );\n    }\n\n    /**\n     * @notice Dispatches an InterchainAccountMessage to the remote router with hook metadata\n     * @param _destination The remote domain\n     * @param _router The address of the remote InterchainAccountRouter\n     * @param _body The InterchainAccountMessage body\n     * @param _hookMetadata The hook metadata to override with for the hook set by the owner\n     * @param _hook The hook to use after sending our message to the mailbox\n     */\n    function _dispatchMessageWithHook(\n        uint32 _destination,\n        bytes32 _router,\n        bytes memory _body,\n        bytes memory _hookMetadata,\n        IPostDispatchHook _hook\n    ) private returns (bytes32) {\n        return\n            _dispatchMessageWithValue(\n                _destination,\n                _router,\n                _body,\n                _hookMetadata,\n                _hook,\n                msg.value\n            );\n    }\n\n    /**\n     * @notice Dispatches an InterchainAccountMessage to the remote router using a `value` parameter for msg.value\n     * @param _value The amount to pass as `msg.value` to the mailbox.dispatch()\n     */\n    function _dispatchMessageWithValue(\n        uint32 _destination,\n        bytes32 _router,\n        bytes memory _body,\n        bytes memory _hookMetadata,\n        IPostDispatchHook _hook,\n        uint _value\n    ) private returns (bytes32) {\n        require(_router != bytes32(0), \"no router specified for destination\");\n        return\n            mailbox.dispatch{value: _value}(\n                _destination,\n                _router,\n                _body,\n                _hookMetadata,\n                _hook\n            );\n    }\n\n    /**\n     * @notice Returns the salt used to deploy an interchain account\n     * @param _origin The remote origin domain of the interchain account\n     * @param _owner The remote owner of the interchain account\n     * @param _router The remote origin InterchainAccountRouter\n     * @param _ism The local address of the ISM\n     * @param _userSalt Salt provided by the user, allows control over account derivation.\n     * @return The CREATE2 salt used for deploying the interchain account\n     */\n    function _getSalt(\n        uint32 _origin,\n        bytes32 _owner,\n        bytes32 _router,\n        bytes32 _ism,\n        bytes32 _userSalt\n    ) private pure returns (bytes32) {\n        return\n            keccak256(\n                abi.encodePacked(_origin, _owner, _router, _ism, _userSalt)\n            );\n    }\n\n    /**\n     * @notice Returns the address of the interchain account on the local chain\n     * @param _salt The CREATE2 salt used for deploying the interchain account\n     * @return The address of the interchain account\n     */\n    function _getLocalInterchainAccount(\n        bytes32 _salt\n    ) private view returns (address payable) {\n        return payable(Create2.computeAddress(_salt, bytecodeHash));\n    }\n\n    /**\n     * @notice Returns the gas payment required to dispatch a message to the given domain's router.\n     * @param _destination The domain of the destination router.\n     * @param _gasLimit The gas limit that the calls will use.\n     * @return _gasPayment Payment computed by the registered hooks via MailboxClient.\n     */\n    function quoteGasPayment(\n        uint32 _destination,\n        uint256 _gasLimit\n    ) public view returns (uint256 _gasPayment) {\n        return\n            _Router_quoteDispatch(\n                _destination,\n                new bytes(0),\n                StandardHookMetadata.overrideGasLimit(_gasLimit),\n                address(hook)\n            );\n    }\n\n    /**\n     * @notice Returns the gas payment required to dispatch a message to the given domain's router.\n     * @param _destination The domain of the destination router.\n     * @return _gasPayment Payment computed by the registered hooks via MailboxClient.\n     */\n    function quoteGasPayment(\n        uint32 _destination\n    ) public view returns (uint256 _gasPayment) {\n        return\n            _Router_quoteDispatch(\n                _destination,\n                bytes(\"\"),\n                bytes(\"\"),\n                address(hook)\n            );\n    }\n\n    /**\n     * @notice Returns the payment required to commit reveal to the destination router.\n     * @param _destination The domain of the destination router.\n     * @param gasLimit The gas limit that the reveal calls will use.\n     * @return _gasPayment Payment computed by the registered hooks via MailboxClient.\n     */\n    function quoteGasForCommitReveal(\n        uint32 _destination,\n        uint256 gasLimit\n    ) external view returns (uint256 _gasPayment) {\n        return\n            _Router_quoteDispatch(\n                _destination,\n                new bytes(0),\n                StandardHookMetadata.overrideGasLimit(COMMIT_TX_GAS_USAGE),\n                address(hook)\n            ) + quoteGasPayment(_destination, gasLimit);\n    }\n}\n"},"contracts/middleware/InterchainQueryRouter.sol":{"content":"// SPDX-License-Identifier: MIT OR Apache-2.0\npragma solidity >=0.8.0;\n\n// ============ Internal Imports ============\nimport {TypeCasts} from \"../libs/TypeCasts.sol\";\nimport {Router} from \"../client/Router.sol\";\nimport {CallLib} from \"./libs/Call.sol\";\nimport {InterchainQueryMessage} from \"./libs/InterchainQueryMessage.sol\";\n\n/**\n * @title Interchain Query Router that performs remote view calls on other chains and returns the result.\n * @dev Currently does not support Sovereign Consensus (user specified Interchain Security Modules).\n */\ncontract InterchainQueryRouter is Router {\n    using TypeCasts for address;\n    using TypeCasts for bytes32;\n    using InterchainQueryMessage for bytes;\n\n    /**\n     * @notice Emitted when a query is dispatched to another chain.\n     * @param destination The domain of the chain to query.\n     * @param sender The address that dispatched the query.\n     */\n    event QueryDispatched(uint32 indexed destination, address indexed sender);\n    /**\n     * @notice Emitted when a query is executed on the and callback dispatched to the origin chain.\n     * @param originDomain The domain of the chain that dispatched the query and receives the callback.\n     * @param sender The address to receive the result.\n     */\n    event QueryExecuted(uint32 indexed originDomain, bytes32 indexed sender);\n    /**\n     * @notice Emitted when a query is resolved on the origin chain.\n     * @param destination The domain of the chain that was queried.\n     * @param sender The address that resolved the query.\n     */\n    event QueryResolved(uint32 indexed destination, address indexed sender);\n\n    constructor(address _mailbox) Router(_mailbox) {}\n\n    /**\n     * @notice Initializes the Router contract with Hyperlane core contracts and the address of the interchain security module.\n     * @param _interchainGasPaymaster The address of the interchain gas paymaster contract.\n     * @param _interchainSecurityModule The address of the interchain security module contract.\n     * @param _owner The address with owner privileges.\n     */\n    function initialize(\n        address _interchainGasPaymaster,\n        address _interchainSecurityModule,\n        address _owner\n    ) external initializer {\n        _MailboxClient_initialize(\n            _interchainGasPaymaster,\n            _interchainSecurityModule,\n            _owner\n        );\n    }\n\n    /**\n     * @notice Dispatches a sequence of static calls (query) to the destination domain and set of callbacks to resolve the results on the dispatcher.\n     * @param _destination The domain of the chain to query.\n     * @param _to The address of the contract to query\n     * @param _data The calldata encoding the query\n     * @param _callback The calldata of the callback that will be made on the sender.\n     * The return value of the query will be appended.\n     * @dev Callbacks must be returned to the `msg.sender` for security reasons. Require this contract is the `msg.sender` on callbacks.\n     */\n    function query(\n        uint32 _destination,\n        address _to,\n        bytes memory _data,\n        bytes memory _callback\n    ) public returns (bytes32 messageId) {\n        emit QueryDispatched(_destination, msg.sender);\n\n        messageId = _dispatch(\n            _destination,\n            InterchainQueryMessage.encode(\n                msg.sender.addressToBytes32(),\n                _to,\n                _data,\n                _callback\n            )\n        );\n    }\n\n    /**\n     * @notice Dispatches a sequence of static calls (query) to the destination domain and set of callbacks to resolve the results on the dispatcher.\n     * @param _destination The domain of the chain to query.\n     * @param calls The sequence of static calls to dispatch and callbacks on the sender to resolve the results.\n     * @dev Recommend using CallLib.build to format the interchain calls.\n     * @dev Callbacks must be returned to the `msg.sender` for security reasons. Require this contract is the `msg.sender` on callbacks.\n     */\n    function query(\n        uint32 _destination,\n        CallLib.StaticCallWithCallback[] calldata calls\n    ) public returns (bytes32 messageId) {\n        emit QueryDispatched(_destination, msg.sender);\n        messageId = _dispatch(\n            _destination,\n            InterchainQueryMessage.encode(msg.sender.addressToBytes32(), calls)\n        );\n    }\n\n    /**\n     * @notice Handles a message from remote enrolled Interchain Query Router.\n     * @param _origin The domain of the chain that sent the message.\n     * @param _message The ABI-encoded interchain query.\n     */\n    function _handle(\n        uint32 _origin,\n        bytes32, // router sender\n        bytes calldata _message\n    ) internal override {\n        InterchainQueryMessage.MessageType messageType = _message.messageType();\n        bytes32 sender = _message.sender();\n        if (messageType == InterchainQueryMessage.MessageType.QUERY) {\n            CallLib.StaticCallWithCallback[]\n                memory callsWithCallback = InterchainQueryMessage\n                    .callsWithCallbacks(_message);\n            bytes[] memory callbacks = CallLib.multistaticcall(\n                callsWithCallback\n            );\n            emit QueryExecuted(_origin, sender);\n            _dispatch(\n                _origin,\n                InterchainQueryMessage.encode(sender, callbacks)\n            );\n        } else if (messageType == InterchainQueryMessage.MessageType.RESPONSE) {\n            address senderAddress = sender.bytes32ToAddress();\n            bytes[] memory rawCalls = _message.rawCalls();\n            CallLib.multicallto(senderAddress, rawCalls);\n            emit QueryResolved(_origin, senderAddress);\n        } else {\n            assert(false);\n        }\n    }\n}\n"},"contracts/middleware/libs/Call.sol":{"content":"// SPDX-License-Identifier: Apache-2.0\npragma solidity ^0.8.13;\n\nimport {Address} from \"@openzeppelin/contracts/utils/Address.sol\";\n\nimport {TypeCasts} from \"../../libs/TypeCasts.sol\";\n\nlibrary CallLib {\n    struct StaticCall {\n        // supporting non EVM targets\n        bytes32 to;\n        bytes data;\n    }\n\n    struct Call {\n        // supporting non EVM targets\n        bytes32 to;\n        uint256 value;\n        bytes data;\n    }\n\n    struct StaticCallWithCallback {\n        StaticCall _call;\n        bytes callback;\n    }\n\n    function call(\n        Call memory _call\n    ) internal returns (bytes memory returnData) {\n        return\n            Address.functionCallWithValue(\n                TypeCasts.bytes32ToAddress(_call.to),\n                _call.data,\n                _call.value\n            );\n    }\n\n    function staticcall(\n        StaticCall memory _call\n    ) private view returns (bytes memory) {\n        return\n            Address.functionStaticCall(\n                TypeCasts.bytes32ToAddress(_call.to),\n                _call.data\n            );\n    }\n\n    function staticcall(\n        StaticCallWithCallback memory _call\n    ) internal view returns (bytes memory callback) {\n        return bytes.concat(_call.callback, staticcall(_call._call));\n    }\n\n    function multicall(Call[] memory calls) internal {\n        uint256 i = 0;\n        uint256 len = calls.length;\n        while (i < len) {\n            call(calls[i]);\n            unchecked {\n                ++i;\n            }\n        }\n    }\n\n    function multistaticcall(\n        StaticCallWithCallback[] memory _calls\n    ) internal view returns (bytes[] memory) {\n        uint256 i = 0;\n        uint256 len = _calls.length;\n        bytes[] memory callbacks = new bytes[](len);\n        while (i < len) {\n            callbacks[i] = staticcall(_calls[i]);\n            unchecked {\n                ++i;\n            }\n        }\n        return callbacks;\n    }\n\n    function multicallto(address to, bytes[] memory calls) internal {\n        uint256 i = 0;\n        uint256 len = calls.length;\n        while (i < len) {\n            Address.functionCall(to, calls[i]);\n            unchecked {\n                ++i;\n            }\n        }\n    }\n\n    function build(\n        bytes32 to,\n        bytes memory data\n    ) internal pure returns (StaticCall memory) {\n        return StaticCall(to, data);\n    }\n\n    function build(\n        address to,\n        bytes memory data\n    ) internal pure returns (StaticCall memory) {\n        return build(TypeCasts.addressToBytes32(to), data);\n    }\n\n    function build(\n        bytes32 to,\n        uint256 value,\n        bytes memory data\n    ) internal pure returns (Call memory) {\n        return Call(to, value, data);\n    }\n\n    function build(\n        address to,\n        uint256 value,\n        bytes memory data\n    ) internal pure returns (Call memory) {\n        return Call(TypeCasts.addressToBytes32(to), value, data);\n    }\n\n    function build(\n        bytes32 to,\n        bytes memory data,\n        bytes memory callback\n    ) internal pure returns (StaticCallWithCallback memory) {\n        return StaticCallWithCallback(build(to, data), callback);\n    }\n\n    function build(\n        address to,\n        bytes memory data,\n        bytes memory callback\n    ) internal pure returns (StaticCallWithCallback memory) {\n        return StaticCallWithCallback(build(to, data), callback);\n    }\n}\n"},"contracts/middleware/libs/InterchainAccountMessage.sol":{"content":"// SPDX-License-Identifier: MIT OR Apache-2.0\npragma solidity >=0.8.0;\n\nimport {CallLib} from \"./Call.sol\";\nimport {TypeCasts} from \"../../libs/TypeCasts.sol\";\n\n/**\n * Format of CALLS message:\n * [   0:   1] MessageType.CALLS (uint8)\n * [   1:  33] ICA owner (bytes32)\n * [  33:  65] ICA ISM (bytes32)\n * [  65:  97] User Salt (bytes32)\n * [  97:????] Calls (CallLib.Call[]), abi encoded\n *\n * Format of COMMITMENT message:\n * [   0:   1] MessageType.COMMITMENT (uint8)\n * [   1:  33] ICA owner (bytes32)\n * [  33:  65] ICA ISM (bytes32)\n * [  65:  97] User Salt (bytes32)\n * [  97: 129] Commitment (bytes32)\n */\nlibrary InterchainAccountMessage {\n    using TypeCasts for bytes32;\n    using TypeCasts for address;\n\n    enum MessageType {\n        CALLS,\n        COMMITMENT,\n        REVEAL\n    }\n\n    bytes32 internal constant EMPTY_SALT = bytes32(0);\n\n    /**\n     * @notice Returns formatted (packed) InterchainAccountMessage\n     * @dev This function should only be used in memory message construction.\n     * @param _owner The owner of the interchain account\n     * @param _ism The address of the remote ISM\n     * @param _calls The sequence of calls to make\n     * @return Formatted message body\n     */\n    function encode(\n        address _owner,\n        bytes32 _ism,\n        CallLib.Call[] calldata _calls\n    ) internal pure returns (bytes memory) {\n        return encode(TypeCasts.addressToBytes32(_owner), _ism, _calls);\n    }\n\n    /**\n     * @notice Returns formatted (packed) InterchainAccountMessage\n     * @dev This function should only be used in memory message construction.\n     * @param _owner The owner of the interchain account\n     * @param _ism The address of the remote ISM\n     * @param _calls The sequence of calls to make\n     * @return Formatted message body\n     */\n    function encode(\n        bytes32 _owner,\n        bytes32 _ism,\n        CallLib.Call[] calldata _calls\n    ) internal pure returns (bytes memory) {\n        return encode(_owner, _ism, _calls, EMPTY_SALT);\n    }\n\n    /**\n     * @notice Returns formatted (packed) InterchainAccountMessage\n     * @dev This function should only be used in memory message construction.\n     * @param _owner The owner of the interchain account\n     * @param _ism The address of the remote ISM\n     * @param _calls The sequence of calls to make\n     * @return Formatted message body\n     */\n    function encode(\n        address _owner,\n        bytes32 _ism,\n        CallLib.Call[] calldata _calls,\n        bytes32 _userSalt\n    ) internal pure returns (bytes memory) {\n        return\n            encode(TypeCasts.addressToBytes32(_owner), _ism, _calls, _userSalt);\n    }\n\n    /**\n     * @notice Returns formatted (packed) InterchainAccountMessage\n     * @dev This function should only be used in memory message construction.\n     * @param _owner The owner of the interchain account\n     * @param _ism The address of the remote ISM\n     * @param _calls The sequence of calls to make\n     * @return Formatted message body\n     */\n    function encode(\n        bytes32 _owner,\n        bytes32 _ism,\n        CallLib.Call[] calldata _calls,\n        bytes32 _userSalt\n    ) internal pure returns (bytes memory) {\n        bytes memory prefix = abi.encodePacked(\n            MessageType.CALLS,\n            _owner,\n            _ism,\n            _userSalt\n        );\n        bytes memory suffix = abi.encode(_calls);\n        return bytes.concat(prefix, suffix);\n    }\n\n    /**\n     * @notice Returns formatted (packed) InterchainAccountMessage\n     * @dev This function should only be used in memory message construction.\n     * @param _owner The owner of the interchain account\n     * @param _ism The address of the remote ISM\n     * @return Formatted message body\n     */\n    function encodeCommitment(\n        bytes32 _owner,\n        bytes32 _ism,\n        bytes32 _commitment,\n        bytes32 _userSalt\n    ) internal pure returns (bytes memory) {\n        return\n            abi.encodePacked(\n                MessageType.COMMITMENT,\n                _owner,\n                _ism,\n                _userSalt,\n                _commitment\n            );\n    }\n\n    function encodeReveal(\n        bytes32 _ism,\n        bytes32 _commitment\n    ) internal pure returns (bytes memory) {\n        return abi.encodePacked(MessageType.REVEAL, _ism, _commitment);\n    }\n\n    function messageType(\n        bytes calldata _message\n    ) internal pure returns (MessageType) {\n        return MessageType(uint8(_message[0]));\n    }\n\n    function owner(bytes calldata _message) internal pure returns (bytes32) {\n        return bytes32(_message[1:33]);\n    }\n\n    /**\n     * @notice Parses and returns the ISM address from the provided message\n     * @param _message The interchain account message\n     * @return The ISM encoded in the message\n     */\n    function ism(bytes calldata _message) internal pure returns (bytes32) {\n        return bytes32(_message[33:65]);\n    }\n\n    function salt(bytes calldata _message) internal pure returns (bytes32) {\n        return bytes32(_message[65:97]);\n    }\n\n    function calls(\n        bytes calldata _message\n    ) internal pure returns (CallLib.Call[] memory) {\n        return abi.decode(_message[97:], (CallLib.Call[]));\n    }\n\n    function commitment(\n        bytes calldata _message\n    ) internal pure returns (bytes32) {\n        return bytes32(_message[97:]);\n    }\n}\n\n/**\n * Format of REVEAL message:\n * [   0:  1] MessageType.REVEAL (uint8)\n * [   1: 33] ICA ISM (bytes32)\n * [  33: 65] Commitment (bytes32)\n */\nlibrary InterchainAccountMessageReveal {\n    function revealIsm(\n        bytes calldata _message\n    ) internal pure returns (bytes32) {\n        return bytes32(_message[1:33]);\n    }\n\n    function revealCommitment(\n        bytes calldata _message\n    ) internal pure returns (bytes32) {\n        return bytes32(_message[33:65]);\n    }\n}\n"},"contracts/middleware/libs/InterchainQueryMessage.sol":{"content":"// SPDX-License-Identifier: Apache-2.0\npragma solidity ^0.8.13;\n\nimport {CallLib} from \"./Call.sol\";\n\n/**\n * Format of message:\n * [   0: 32] Sender address\n * [  32: 64] Message type (left padded with zeroes)\n * [  64:???] Encoded call array\n */\nlibrary InterchainQueryMessage {\n    uint256 private constant SENDER_OFFSET = 0;\n    uint256 private constant TYPE_OFFSET = 32;\n    uint256 private constant CALLS_OFFSET = 64;\n\n    enum MessageType {\n        QUERY,\n        RESPONSE\n    }\n\n    /**\n     * @notice Parses and returns the query sender from the provided message\n     * @param _message The interchain query message\n     * @return The query sender as bytes32\n     */\n    function sender(bytes calldata _message) internal pure returns (bytes32) {\n        return bytes32(_message[SENDER_OFFSET:TYPE_OFFSET]);\n    }\n\n    /**\n     * @notice Parses and returns the message type from the provided message\n     * @param _message The interchain query message\n     * @return The message type (query or response)\n     */\n    function messageType(\n        bytes calldata _message\n    ) internal pure returns (MessageType) {\n        // left padded with zeroes\n        return MessageType(uint8(bytes1(_message[CALLS_OFFSET - 1])));\n    }\n\n    /**\n     * @notice Returns formatted InterchainQueryMessage, type == QUERY\n     * @param _sender The query sender as bytes32\n     * @param _calls The sequence of queries to make, with the corresponding\n     * response callbacks\n     * @return Formatted message body\n     */\n    function encode(\n        bytes32 _sender,\n        CallLib.StaticCallWithCallback[] calldata _calls\n    ) internal pure returns (bytes memory) {\n        return abi.encode(_sender, MessageType.QUERY, _calls);\n    }\n\n    /**\n     * @notice Returns formatted InterchainQueryMessage, type == QUERY\n     * @param _sender The query sender as bytes32\n     * @param _to The address of the contract to query\n     * @param _data The calldata encoding the query\n     * @param _callback The calldata of the callback that will be made on the sender.\n     * The return value of the query will be appended.\n     * @return Formatted message body\n     */\n    function encode(\n        bytes32 _sender,\n        address _to,\n        bytes memory _data,\n        bytes memory _callback\n    ) internal pure returns (bytes memory) {\n        CallLib.StaticCallWithCallback[]\n            memory _calls = new CallLib.StaticCallWithCallback[](1);\n        _calls[0] = CallLib.build(_to, _data, _callback);\n        return abi.encode(_sender, MessageType.QUERY, _calls);\n    }\n\n    /**\n     * @notice Parses and returns the calls and callbacks from the message\n     * @param _message The interchain query message, type == QUERY\n     * @return _calls The sequence of queries to make with the corresponding\n     * response callbacks\n     */\n    function callsWithCallbacks(\n        bytes calldata _message\n    ) internal pure returns (CallLib.StaticCallWithCallback[] memory _calls) {\n        assert(messageType(_message) == MessageType.QUERY);\n        (, , _calls) = abi.decode(\n            _message,\n            (bytes32, MessageType, CallLib.StaticCallWithCallback[])\n        );\n    }\n\n    /**\n     * @notice Returns formatted InterchainQueryMessage, type == RESPONSE\n     * @param _sender The query sender as bytes32\n     * @param _calls The sequence of callbacks to make\n     * @return Formatted message body\n     */\n    function encode(\n        bytes32 _sender,\n        bytes[] memory _calls\n    ) internal pure returns (bytes memory) {\n        return abi.encode(_sender, MessageType.RESPONSE, _calls);\n    }\n\n    /**\n     * @notice Parses and returns the callbacks from the message\n     * @param _message The interchain query message, type == RESPONSE\n     * @return _calls The sequence of callbacks to make\n     */\n    function rawCalls(\n        bytes calldata _message\n    ) internal pure returns (bytes[] memory _calls) {\n        assert(messageType(_message) == MessageType.RESPONSE);\n        (, , _calls) = abi.decode(_message, (bytes32, MessageType, bytes[]));\n    }\n}\n"},"contracts/middleware/libs/OwnableMulticall.sol":{"content":"// SPDX-License-Identifier: Apache-2.0\npragma solidity ^0.8.13;\n\n// ============ Internal Imports ============\nimport {CallLib} from \"./Call.sol\";\n\n/*\n * @title OwnableMulticall\n * @dev Permits immutable owner address to execute calls with value to other contracts.\n */\ncontract OwnableMulticall {\n    /// @dev The owner will be the ICA Router that deployed this contract (via CREATE2).\n    address public immutable owner;\n\n    constructor(address _owner) {\n        require(_owner != address(0), \"OwnableMulticall: invalid owner\");\n        owner = _owner;\n    }\n\n    modifier onlyOwner() {\n        require(msg.sender == owner, \"!owner\");\n        _;\n    }\n\n    function multicall(\n        CallLib.Call[] calldata calls\n    ) external payable onlyOwner {\n        return CallLib.multicall(calls);\n    }\n\n    /// @notice A mapping of commitment hashes to status\n    mapping(bytes32 commitmentHash => bool isPendingExecution)\n        public commitments;\n\n    event CommitmentSet(bytes32 indexed commitmentHash);\n\n    event CommitmentExecuted(bytes32 indexed commitmentHash);\n\n    /// @notice Sets the commitment value that will be executed next\n    /// @param _commitment The new commitment value to be set\n    function setCommitment(bytes32 _commitment) external onlyOwner {\n        require(\n            !commitments[_commitment],\n            \"ICA: Previous commitment pending execution\"\n        );\n        commitments[_commitment] = true;\n        emit CommitmentSet(_commitment);\n    }\n\n    /// @dev The calls represented by the commitment can only be executed once per commitment,\n    /// though you can submit the same commitment again after the calls have been executed.\n    function revealAndExecute(\n        CallLib.Call[] calldata calls,\n        bytes32 salt\n    ) external payable returns (bytes32 executedCommitment) {\n        // Check if metadata matches stored commitment (checks)\n        bytes32 revealedHash = keccak256(\n            abi.encodePacked(salt, abi.encode(calls))\n        );\n        require(commitments[revealedHash], \"ICA: Invalid Reveal\");\n\n        // Delete the commitment (effects)\n        executedCommitment = revealedHash;\n        delete commitments[revealedHash];\n\n        emit CommitmentExecuted(executedCommitment);\n\n        // Execute the calls (interactions)\n        CallLib.multicall(calls);\n        return executedCommitment;\n    }\n\n    // solhint-disable-next-line no-empty-blocks\n    receive() external payable {}\n}\n"},"contracts/mock/MockArbBridge.sol":{"content":"// SPDX-License-Identifier: MIT or Apache-2.0\npragma solidity ^0.8.13;\n\ncontract MockArbSys {\n    event L2ToL1Tx(\n        address caller,\n        address indexed destination,\n        uint256 indexed hash,\n        uint256 indexed position,\n        uint256 arbBlockNum,\n        uint256 ethBlockNum,\n        uint256 timestamp,\n        uint256 callvalue,\n        bytes data\n    );\n\n    function sendTxToL1(\n        address destination,\n        bytes calldata data\n    ) external payable returns (uint256) {\n        emit L2ToL1Tx(\n            msg.sender,\n            destination,\n            uint256(keccak256(data)),\n            42,\n            block.number * 10,\n            block.number,\n            block.timestamp,\n            msg.value,\n            data\n        );\n        return 0;\n    }\n}\n\ncontract MockArbBridge {\n    error BridgeCallFailed();\n\n    address public activeOutbox;\n    address public l2ToL1Sender;\n\n    constructor() {\n        activeOutbox = address(this);\n    }\n\n    function setL2ToL1Sender(address _sender) external {\n        l2ToL1Sender = _sender;\n    }\n\n    function bridge() external view returns (address) {\n        return address(this);\n    }\n\n    function executeTransaction(\n        bytes32[] calldata /*proof*/,\n        uint256 /*index*/,\n        address /*l2Sender*/,\n        address to,\n        uint256 /*l2Block*/,\n        uint256 /*l1Block*/,\n        uint256 /*timestamp*/,\n        uint256 value,\n        bytes calldata data\n    ) external payable {\n        (bool success, bytes memory returndata) = to.call{value: value}(data);\n        if (!success) {\n            if (returndata.length > 0) {\n                // solhint-disable-next-line no-inline-assembly\n                assembly {\n                    let returndata_size := mload(returndata)\n                    revert(add(32, returndata), returndata_size)\n                }\n            } else {\n                revert BridgeCallFailed();\n            }\n        }\n    }\n}\n"},"contracts/mock/MockCircleMessageTransmitter.sol":{"content":"// SPDX-License-Identifier: Apache-2.0\npragma solidity ^0.8.13;\n\nimport {IMessageTransmitter} from \"../interfaces/cctp/IMessageTransmitter.sol\";\nimport {MockToken} from \"./MockToken.sol\";\n\ncontract MockCircleMessageTransmitter is IMessageTransmitter {\n    uint64 public nonce = 0;\n    mapping(bytes32 => bool) processedNonces;\n    MockToken token;\n    uint32 public override version;\n    uint32 public override localDomain = 0;\n\n    constructor(MockToken _token) {\n        token = _token;\n    }\n\n    function sendMessage(\n        uint32 destinationDomain,\n        bytes32 recipient,\n        bytes calldata messageBody\n    ) public override returns (uint64) {\n        emit MessageSent(messageBody);\n        return ++nonce;\n    }\n\n    function sendMessageWithCaller(\n        uint32 destinationDomain,\n        bytes32 recipient,\n        bytes32 destinationCaller,\n        bytes calldata messageBody\n    ) external override returns (uint64) {\n        return sendMessage(destinationDomain, recipient, messageBody);\n    }\n\n    function replaceMessage(\n        bytes calldata originalMessage,\n        bytes calldata originalAttestation,\n        bytes calldata newMessageBody,\n        bytes32 newDestinationCaller\n    ) external override {\n        revert(\"Not implemented\");\n    }\n\n    function receiveMessage(\n        bytes memory,\n        bytes calldata\n    ) external pure override returns (bool success) {\n        success = true;\n    }\n\n    function hashSourceAndNonce(\n        uint32 _source,\n        uint64 _nonce\n    ) public pure returns (bytes32) {\n        return keccak256(abi.encodePacked(_source, _nonce));\n    }\n\n    function process(\n        bytes32 _nonceId,\n        address _recipient,\n        uint256 _amount\n    ) public {\n        processedNonces[_nonceId] = true;\n        token.mint(_recipient, _amount);\n    }\n\n    function usedNonces(\n        bytes32 _nonceId\n    ) external view override returns (uint256) {\n        return processedNonces[_nonceId] ? 1 : 0;\n    }\n\n    function setVersion(uint32 _version) external {\n        version = _version;\n    }\n}\n"},"contracts/mock/MockCircleTokenMessenger.sol":{"content":"// SPDX-License-Identifier: Apache-2.0\npragma solidity ^0.8.13;\n\nimport {ITokenMessenger} from \"../interfaces/cctp/ITokenMessenger.sol\";\nimport {ITokenMessengerV2} from \"../interfaces/cctp/ITokenMessengerV2.sol\";\nimport {MockToken} from \"./MockToken.sol\";\n\ncontract MockCircleTokenMessenger is ITokenMessenger {\n    uint64 public nextNonce = 0;\n    MockToken token;\n\n    constructor(MockToken _token) {\n        token = _token;\n    }\n\n    function depositForBurn(\n        uint256 _amount,\n        uint32,\n        bytes32,\n        address _burnToken\n    ) external returns (uint64 _nonce) {\n        _nonce = nextNonce;\n        nextNonce += 1;\n        require(address(token) == _burnToken);\n        token.transferFrom(msg.sender, address(this), _amount);\n        token.burn(_amount);\n    }\n\n    function depositForBurnWithCaller(\n        uint256,\n        uint32,\n        bytes32,\n        address,\n        bytes32\n    ) external returns (uint64 _nonce) {\n        _nonce = nextNonce;\n        nextNonce += 1;\n    }\n\n    function messageBodyVersion() external returns (uint32) {\n        return 0;\n    }\n}\n\ncontract MockCircleTokenMessengerV2 is ITokenMessengerV2 {\n    uint64 public nextNonce = 0;\n    MockToken token;\n\n    constructor(MockToken _token) {\n        token = _token;\n    }\n\n    function depositForBurn(\n        uint256 _amount,\n        uint32,\n        bytes32,\n        address _burnToken,\n        bytes32,\n        uint256,\n        uint32\n    ) external {\n        nextNonce += 1;\n        require(address(token) == _burnToken);\n        token.transferFrom(msg.sender, address(this), _amount);\n        token.burn(_amount);\n    }\n\n    function messageBodyVersion() external returns (uint32) {\n        return 1;\n    }\n}\n"},"contracts/mock/MockERC4626YieldSharing.sol":{"content":"// SPDX-License-Identifier: Apache-2.0\npragma solidity >=0.8.0;\n\nimport \"@openzeppelin/contracts/token/ERC20/extensions/ERC4626.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/ERC20.sol\";\nimport \"@openzeppelin/contracts/interfaces/IERC20.sol\";\nimport \"@openzeppelin/contracts/access/Ownable.sol\";\n\n/**\n * @title MockERC4626YieldSharing\n * @dev Mock ERC4626 vault for testing yield sharing with the owner of the vault\n * @dev This is a simplified version of the Aave v3 vault here\n * https://github.com/aave/Aave-Vault/blob/main/src/ATokenVault.sol\n */\ncontract MockERC4626YieldSharing is ERC4626, Ownable {\n    using Math for uint256;\n\n    uint256 public constant SCALE = 1e18;\n    uint256 public fee;\n    uint256 public accumulatedFees;\n    uint256 public lastVaultBalance;\n\n    constructor(\n        address _asset,\n        string memory _name,\n        string memory _symbol,\n        uint256 _initialFee\n    ) ERC4626(IERC20(_asset)) ERC20(_name, _symbol) {\n        fee = _initialFee;\n    }\n\n    function setFee(uint256 newFee) external onlyOwner {\n        require(newFee <= SCALE, \"Fee too high\");\n        fee = newFee;\n    }\n\n    function _accrueYield() internal {\n        uint256 newVaultBalance = IERC20(asset()).balanceOf(address(this));\n        if (newVaultBalance > lastVaultBalance) {\n            uint256 newYield = newVaultBalance - lastVaultBalance;\n            uint256 newFees = newYield.mulDiv(fee, SCALE, Math.Rounding.Down);\n            accumulatedFees += newFees;\n            lastVaultBalance = newVaultBalance;\n        }\n    }\n\n    function deposit(\n        uint256 assets,\n        address receiver\n    ) public override returns (uint256) {\n        lastVaultBalance += assets;\n        return super.deposit(assets, receiver);\n    }\n\n    function redeem(\n        uint256 shares,\n        address receiver,\n        address owner\n    ) public override returns (uint256) {\n        _accrueYield();\n        return super.redeem(shares, receiver, owner);\n    }\n\n    function getClaimableFees() public view returns (uint256) {\n        uint256 newVaultBalance = IERC20(asset()).balanceOf(address(this));\n\n        if (newVaultBalance <= lastVaultBalance) {\n            return accumulatedFees;\n        }\n\n        uint256 newYield = newVaultBalance - lastVaultBalance;\n        uint256 newFees = newYield.mulDiv(fee, SCALE, Math.Rounding.Down);\n\n        return accumulatedFees + newFees;\n    }\n\n    function totalAssets() public view override returns (uint256) {\n        return IERC20(asset()).balanceOf(address(this)) - getClaimableFees();\n    }\n}\n"},"contracts/mock/MockERC5164.sol":{"content":"// SPDX-License-Identifier: MIT or Apache-2.0\npragma solidity ^0.8.13;\n\nimport {IMessageDispatcher} from \"../interfaces/hooks/IMessageDispatcher.sol\";\n\ncontract MockMessageDispatcher is IMessageDispatcher {\n    function dispatchMessage(\n        uint256 toChainId,\n        address to,\n        bytes calldata data\n    ) external returns (bytes32) {\n        bytes32 messageId = keccak256(abi.encodePacked(toChainId, to, data));\n\n        // simulate a successful dispatch\n        emit MessageDispatched(messageId, msg.sender, toChainId, to, data);\n\n        return messageId;\n    }\n}\n\ncontract MockMessageExecutor {\n    event MessageIdExecuted(\n        uint256 indexed fromChainId,\n        bytes32 indexed messageId\n    );\n}\n"},"contracts/mock/MockHyperlaneEnvironment.sol":{"content":"// SPDX-License-Identifier: Apache-2.0\npragma solidity ^0.8.13;\n\nimport \"./MockMailbox.sol\";\nimport \"../test/TestInterchainGasPaymaster.sol\";\nimport \"../test/TestIsm.sol\";\n\nimport {TypeCasts} from \"../libs/TypeCasts.sol\";\n\ncontract MockHyperlaneEnvironment {\n    uint32 public originDomain;\n    uint32 public destinationDomain;\n\n    mapping(uint32 => MockMailbox) public mailboxes;\n    mapping(uint32 => TestInterchainGasPaymaster) public igps;\n    mapping(uint32 => IInterchainSecurityModule) public isms;\n\n    constructor(uint32 _originDomain, uint32 _destinationDomain) {\n        originDomain = _originDomain;\n        destinationDomain = _destinationDomain;\n\n        MockMailbox originMailbox = new MockMailbox(_originDomain);\n        MockMailbox destinationMailbox = new MockMailbox(_destinationDomain);\n\n        originMailbox.addRemoteMailbox(_destinationDomain, destinationMailbox);\n        destinationMailbox.addRemoteMailbox(_originDomain, originMailbox);\n\n        isms[originDomain] = new TestIsm();\n        isms[destinationDomain] = new TestIsm();\n\n        originMailbox.setDefaultIsm(address(isms[originDomain]));\n        destinationMailbox.setDefaultIsm(address(isms[destinationDomain]));\n\n        originMailbox.transferOwnership(msg.sender);\n        destinationMailbox.transferOwnership(msg.sender);\n\n        mailboxes[_originDomain] = originMailbox;\n        mailboxes[_destinationDomain] = destinationMailbox;\n    }\n\n    function processNextPendingMessage() public payable {\n        mailboxes[destinationDomain].processNextInboundMessage{\n            value: msg.value\n        }();\n    }\n\n    function processNextPendingMessageFromDestination() public {\n        mailboxes[originDomain].processNextInboundMessage();\n    }\n}\n"},"contracts/mock/MockMailbox.sol":{"content":"// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport {Versioned} from \"../upgrade/Versioned.sol\";\nimport {TypeCasts} from \"../libs/TypeCasts.sol\";\nimport {Message} from \"../libs/Message.sol\";\nimport {IMessageRecipient} from \"../interfaces/IMessageRecipient.sol\";\nimport {IInterchainSecurityModule, ISpecifiesInterchainSecurityModule} from \"../interfaces/IInterchainSecurityModule.sol\";\nimport {Mailbox} from \"../Mailbox.sol\";\nimport {IPostDispatchHook} from \"../interfaces/hooks/IPostDispatchHook.sol\";\n\nimport {TestIsm} from \"../test/TestIsm.sol\";\nimport {TestPostDispatchHook} from \"../test/TestPostDispatchHook.sol\";\n\ncontract MockMailbox is Mailbox {\n    using Message for bytes;\n\n    uint32 public inboundUnprocessedNonce = 0;\n    uint32 public inboundProcessedNonce = 0;\n\n    mapping(uint32 => MockMailbox) public remoteMailboxes;\n    mapping(uint256 nonce => bytes message) public inboundMessages;\n    mapping(uint256 nonce => bytes metadata) public inboundMetadata;\n\n    constructor(uint32 _domain) Mailbox(_domain) {\n        TestIsm ism = new TestIsm();\n        defaultIsm = ism;\n\n        TestPostDispatchHook hook = new TestPostDispatchHook();\n        defaultHook = hook;\n        requiredHook = hook;\n\n        _transferOwnership(msg.sender);\n        _disableInitializers();\n    }\n\n    function addRemoteMailbox(uint32 _domain, MockMailbox _mailbox) external {\n        remoteMailboxes[_domain] = _mailbox;\n    }\n\n    function dispatch(\n        uint32 destinationDomain,\n        bytes32 recipientAddress,\n        bytes calldata messageBody,\n        bytes calldata metadata,\n        IPostDispatchHook hook\n    ) public payable override returns (bytes32) {\n        bytes memory message = _buildMessage(\n            destinationDomain,\n            recipientAddress,\n            messageBody\n        );\n        bytes32 id = super.dispatch(\n            destinationDomain,\n            recipientAddress,\n            messageBody,\n            metadata,\n            hook\n        );\n\n        MockMailbox _destinationMailbox = remoteMailboxes[destinationDomain];\n        require(\n            address(_destinationMailbox) != address(0),\n            \"Missing remote mailbox\"\n        );\n        _destinationMailbox.addInboundMessage(message);\n\n        return id;\n    }\n\n    /// @dev addInboundMessage is used to add a message to the mailbox\n    function addInboundMessage(bytes calldata message) public {\n        inboundMessages[inboundUnprocessedNonce] = message;\n        inboundUnprocessedNonce++;\n    }\n\n    /// @dev processNextInboundMessage is used to process the next inbound message\n    function processNextInboundMessage() public payable {\n        processInboundMessage(inboundProcessedNonce);\n        inboundProcessedNonce++;\n    }\n\n    /// @dev processInboundMessage is used to process an inbound message\n    function processInboundMessage(uint32 _nonce) public payable {\n        bytes memory _message = inboundMessages[_nonce];\n        bytes memory _metadata = inboundMetadata[_nonce];\n        this.process{value: msg.value}(_metadata, _message);\n    }\n\n    /// @dev addInboundMetadata is used to add metadata to an inbound message.\n    /// This metadata will be used to process the inbound message.\n    function addInboundMetadata(uint32 _nonce, bytes memory metadata) public {\n        inboundMetadata[_nonce] = metadata;\n    }\n}\n"},"contracts/mock/MockOptimism.sol":{"content":"// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport {CallLib} from \"../middleware/libs/Call.sol\";\nimport {TypeCasts} from \"../libs/TypeCasts.sol\";\nimport {ICrossDomainMessenger} from \"../interfaces/optimism/ICrossDomainMessenger.sol\";\nimport {IOptimismPortal} from \"../interfaces/optimism/IOptimismPortal.sol\";\nimport {IStandardBridge} from \"../interfaces/optimism/IStandardBridge.sol\";\nimport {OPL2ToL1Withdrawal} from \"../libs/OPL2ToL1Withdrawal.sol\";\n\n// for both L1 and L2\ncontract MockOptimismMessenger is ICrossDomainMessenger {\n    address public xDomainMessageSender;\n    address public PORTAL;\n\n    function sendMessage(\n        address _target,\n        bytes calldata _message,\n        uint32 _gasLimit\n    ) external payable {}\n\n    function relayMessage(\n        uint256 /*_nonce*/,\n        address /*_sender*/,\n        address _target,\n        uint256 _value,\n        uint256 /*_minGasLimit*/,\n        bytes calldata _message\n    ) external payable {\n        CallLib.Call memory call = CallLib.Call(\n            TypeCasts.addressToBytes32(_target),\n            _value,\n            _message\n        );\n        CallLib.call(call);\n    }\n\n    function OTHER_MESSENGER() external view returns (address) {}\n\n    function setXDomainMessageSender(address _sender) external {\n        xDomainMessageSender = _sender;\n    }\n\n    function setPORTAL(address _portal) external {\n        PORTAL = _portal;\n    }\n\n    function baseGas(\n        bytes calldata _message,\n        uint32 _minGasLimit\n    ) external pure returns (uint64) {\n        return 0;\n    }\n\n    function messageNonce() public view returns (uint256) {\n        return 0;\n    }\n}\n\n// mock deployment on L1\ncontract MockOptimismPortal is IOptimismPortal {\n    error WithdrawalTransactionFailed();\n\n    mapping(bytes32 => ProvenWithdrawal) public _provenWithdrawals;\n    mapping(bytes32 => bool) public _finalizedWithdrawals;\n\n    function finalizeWithdrawalTransaction(\n        WithdrawalTransaction memory _tx\n    ) external {\n        bytes32 withdrawalHash = OPL2ToL1Withdrawal.hashWithdrawal(_tx);\n        _finalizedWithdrawals[withdrawalHash] = true;\n    }\n\n    function proveWithdrawalTransaction(\n        WithdrawalTransaction memory _tx,\n        uint256 _disputeGameIndex,\n        OutputRootProof memory _outputRootProof,\n        bytes[] memory _withdrawalProof\n    ) external {\n        bytes32 withdrawalHash = OPL2ToL1Withdrawal.hashWithdrawal(_tx);\n        _provenWithdrawals[withdrawalHash] = ProvenWithdrawal({\n            outputRoot: _outputRootProof.stateRoot,\n            timestamp: uint128(block.timestamp),\n            l2OutputIndex: uint128(0)\n        });\n    }\n\n    function finalizedWithdrawals(\n        bytes32 _withdrawalHash\n    ) external view returns (bool value) {\n        return _finalizedWithdrawals[_withdrawalHash];\n    }\n\n    function provenWithdrawals(\n        bytes32 withdrawalHash\n    ) external view returns (ProvenWithdrawal memory) {\n        return _provenWithdrawals[withdrawalHash];\n    }\n}\n\n// mock deployment on L2\ncontract MockOptimismStandardBridge is IStandardBridge {\n    function MESSENGER() public view returns (ICrossDomainMessenger) {\n        return\n            ICrossDomainMessenger(0x4200000000000000000000000000000000000007);\n    }\n\n    function OTHER_BRIDGE() public view returns (IStandardBridge) {\n        return\n            IStandardBridge(\n                payable(0xFBb0621E0B23b5478B630BD55a5f21f67730B0F1)\n            );\n    }\n\n    function messenger() external view returns (ICrossDomainMessenger) {\n        return MESSENGER();\n    }\n\n    function otherBridge() external view returns (IStandardBridge) {\n        return OTHER_BRIDGE();\n    }\n\n    function bridgeERC20(\n        address _localToken,\n        address _remoteToken,\n        uint256 _amount,\n        uint32 _minGasLimit,\n        bytes memory _extraData\n    ) external {}\n\n    function bridgeERC20To(\n        address _localToken,\n        address _remoteToken,\n        address _to,\n        uint256 _amount,\n        uint32 _minGasLimit,\n        bytes memory _extraData\n    ) external {}\n\n    function bridgeETH(\n        uint32 _minGasLimit,\n        bytes memory _extraData\n    ) external payable {}\n\n    function bridgeETHTo(\n        address _to,\n        uint32 _minGasLimit,\n        bytes memory _extraData\n    ) external payable {}\n\n    function deposits(address, address) external view returns (uint256) {}\n\n    function finalizeBridgeERC20(\n        address _localToken,\n        address _remoteToken,\n        address _from,\n        address _to,\n        uint256 _amount,\n        bytes memory _extraData\n    ) external {}\n\n    function finalizeBridgeETH(\n        address _from,\n        address _to,\n        uint256 _amount,\n        bytes memory _extraData\n    ) external payable {}\n\n    function paused() external view returns (bool) {}\n\n    function __constructor__() external {}\n\n    receive() external payable {}\n}\n\n// mock contract on L2\ncontract MockL2ToL1MessagePasser {\n    uint16 public constant MESSAGE_VERSION = 1;\n\n    function messageNonce() public view returns (uint256) {\n        return 0;\n    }\n}\n"},"contracts/mock/MockToken.sol":{"content":"// SPDX-License-Identifier: Apache-2.0\npragma solidity ^0.8.13;\n\nimport {ERC20Upgradeable} from \"@openzeppelin/contracts-upgradeable/token/ERC20/ERC20Upgradeable.sol\";\n\ncontract MockToken is ERC20Upgradeable {\n    function mint(address account, uint256 amount) external {\n        _mint(account, amount);\n    }\n\n    function burn(uint256 _amount) external {\n        _burn(msg.sender, _amount);\n    }\n}\n"},"contracts/mock/MockValueTransferBridge.sol":{"content":"// SPDX-License-Identifier: Apache-2.0\npragma solidity ^0.8.13;\n\nimport {ValueTransferBridge, Quote} from \"../token/interfaces/ValueTransferBridge.sol\";\n\ncontract MockValueTransferBridge is ValueTransferBridge {\n    event SentTransferRemote(\n        uint32 indexed origin,\n        uint32 indexed destination,\n        bytes32 indexed recipient,\n        uint256 amount\n    );\n\n    function quoteTransferRemote(\n        uint32, //_destinationDomain,\n        bytes32, //_recipient,\n        uint256 //_amountOut\n    ) public view virtual override returns (Quote[] memory) {\n        Quote[] memory quotes = new Quote[](1);\n        quotes[0] = Quote(address(0), 1);\n\n        return quotes;\n    }\n\n    function transferRemote(\n        uint32 _destinationDomain,\n        bytes32 _recipient,\n        uint256 _amountOut\n    ) external payable virtual override returns (bytes32 transferId) {\n        emit SentTransferRemote(\n            uint32(block.chainid),\n            _destinationDomain,\n            _recipient,\n            _amountOut\n        );\n\n        return keccak256(\"transferId\");\n    }\n}\n"},"contracts/PackageVersioned.sol":{"content":"// SPDX-License-Identifier: MIT OR Apache-2.0\npragma solidity >=0.6.11;\n\n/**\n * @title PackageVersioned\n * @notice Package version getter for contracts\n **/\nabstract contract PackageVersioned {\n    // GENERATED CODE - DO NOT EDIT\n    string public constant PACKAGE_VERSION = \"9.0.5\";\n}\n"},"contracts/test/avs/TestAVSDirectory.sol":{"content":"// SPDX-License-Identifier: MIT OR Apache-2.0\npragma solidity >=0.8.0;\n\nimport {IAVSDirectory} from \"../../interfaces/avs/vendored/IAVSDirectory.sol\";\nimport {ISignatureUtils} from \"../../interfaces/avs/vendored/ISignatureUtils.sol\";\nimport {ISlasher} from \"../../interfaces/avs/vendored/ISlasher.sol\";\n\nimport {ECDSA} from \"@openzeppelin/contracts/utils/cryptography/ECDSA.sol\";\n\ncontract TestAVSDirectory is IAVSDirectory {\n    bytes32 public constant OPERATOR_AVS_REGISTRATION_TYPEHASH =\n        keccak256(\n            \"OperatorAVSRegistration(address operator,address avs,bytes32 salt,uint256 expiry)\"\n        );\n    bytes32 public constant DOMAIN_TYPEHASH =\n        keccak256(\n            \"EIP712Domain(string name,uint256 chainId,address verifyingContract)\"\n        );\n\n    mapping(address => mapping(address => OperatorAVSRegistrationStatus))\n        public avsOperatorStatus;\n\n    function updateAVSMetadataURI(string calldata metadataURI) external {\n        emit AVSMetadataURIUpdated(msg.sender, metadataURI);\n    }\n\n    function registerOperatorToAVS(\n        address operator,\n        ISignatureUtils.SignatureWithSaltAndExpiry memory operatorSignature\n    ) external {\n        bytes32 operatorRegistrationDigestHash = calculateOperatorAVSRegistrationDigestHash({\n                operator: operator,\n                avs: msg.sender,\n                salt: operatorSignature.salt,\n                expiry: operatorSignature.expiry\n            });\n        require(\n            ECDSA.recover(\n                operatorRegistrationDigestHash,\n                operatorSignature.signature\n            ) == operator,\n            \"EIP1271SignatureUtils.checkSignature_EIP1271: signature not from signer\"\n        );\n        avsOperatorStatus[msg.sender][operator] = OperatorAVSRegistrationStatus\n            .REGISTERED;\n    }\n\n    function deregisterOperatorFromAVS(address operator) external {\n        avsOperatorStatus[msg.sender][operator] = OperatorAVSRegistrationStatus\n            .UNREGISTERED;\n    }\n\n    function calculateOperatorAVSRegistrationDigestHash(\n        address operator,\n        address avs,\n        bytes32 salt,\n        uint256 expiry\n    ) public view returns (bytes32) {\n        // calculate the struct hash\n        bytes32 structHash = keccak256(\n            abi.encode(\n                OPERATOR_AVS_REGISTRATION_TYPEHASH,\n                operator,\n                avs,\n                salt,\n                expiry\n            )\n        );\n        // calculate the digest hash\n        bytes32 digestHash = keccak256(\n            abi.encodePacked(\"\\x19\\x01\", domainSeparator(), structHash)\n        );\n        return digestHash;\n    }\n\n    function domainSeparator() public view returns (bytes32) {\n        return\n            keccak256(\n                abi.encode(\n                    DOMAIN_TYPEHASH,\n                    keccak256(bytes(\"EigenLayer\")),\n                    block.chainid,\n                    address(this)\n                )\n            );\n    }\n}\n"},"contracts/test/avs/TestDelegationManager.sol":{"content":"// SPDX-License-Identifier: MIT OR Apache-2.0\npragma solidity >=0.8.0;\n\nimport {IDelegationManager} from \"../../interfaces/avs/vendored/IDelegationManager.sol\";\nimport {IStrategy} from \"../../interfaces/avs/vendored/IStrategy.sol\";\n\ncontract TestDelegationManager is IDelegationManager {\n    mapping(address => bool) public isOperator;\n    mapping(address => mapping(IStrategy => uint256)) public operatorShares;\n\n    function registerAsOperator(\n        OperatorDetails calldata registeringOperatorDetails,\n        string calldata metadataURI\n    ) external {}\n\n    function setIsOperator(\n        address operator,\n        bool _isOperatorReturnValue\n    ) external {\n        isOperator[operator] = _isOperatorReturnValue;\n    }\n\n    function getOperatorShares(\n        address operator,\n        IStrategy[] memory strategies\n    ) public view returns (uint256[] memory) {\n        uint256[] memory shares = new uint256[](strategies.length);\n        for (uint256 i = 0; i < strategies.length; ++i) {\n            shares[i] = operatorShares[operator][strategies[i]];\n        }\n        return shares;\n    }\n}\n"},"contracts/test/avs/TestHyperlaneServiceManager.sol":{"content":"// SPDX-License-Identifier: MIT OR Apache-2.0\npragma solidity >=0.8.0;\n\nimport {Enrollment, EnrollmentStatus, EnumerableMapEnrollment} from \"../../libs/EnumerableMapEnrollment.sol\";\nimport {HyperlaneServiceManager} from \"../../avs/HyperlaneServiceManager.sol\";\n\ncontract TestHyperlaneServiceManager is HyperlaneServiceManager {\n    using EnumerableMapEnrollment for EnumerableMapEnrollment.AddressToEnrollmentMap;\n\n    constructor(\n        address _avsDirectory,\n        address _stakeRegistry,\n        address _paymentCoordinator,\n        address _delegationManager\n    )\n        HyperlaneServiceManager(\n            _avsDirectory,\n            _stakeRegistry,\n            _paymentCoordinator,\n            _delegationManager\n        )\n    {}\n\n    function mockSetUnenrolled(address operator, address challenger) external {\n        enrolledChallengers[operator].set(\n            address(challenger),\n            Enrollment(EnrollmentStatus.UNENROLLED, 0)\n        );\n    }\n}\n"},"contracts/test/avs/TestPaymentCoordinator.sol":{"content":"// SPDX-License-Identifier: MIT OR Apache-2.0\npragma solidity >=0.8.0;\n\nimport {IPaymentCoordinator} from \"../../interfaces/avs/vendored/IPaymentCoordinator.sol\";\nimport {IERC20} from \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport {SafeERC20} from \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\n\ncontract TestPaymentCoordinator is IPaymentCoordinator {\n    using SafeERC20 for IERC20;\n\n    function payForRange(RangePayment[] calldata rangePayments) external {\n        for (uint256 i = 0; i < rangePayments.length; i++) {\n            rangePayments[i].token.safeTransferFrom(\n                msg.sender,\n                address(this),\n                rangePayments[i].amount\n            );\n        }\n    }\n}\n"},"contracts/test/avs/TestSlasher.sol":{"content":"// SPDX-License-Identifier: MIT OR Apache-2.0\npragma solidity >=0.8.0;\n\nimport {ISlasher} from \"../../interfaces/avs/vendored/ISlasher.sol\";\n\ncontract TestSlasher is ISlasher {\n    function freezeOperator(address toBeFrozen) external {}\n}\n"},"contracts/test/ERC20Test.sol":{"content":"// SPDX-License-Identifier: Apache-2.0\npragma solidity >=0.8.0;\n\nimport \"@openzeppelin/contracts/token/ERC20/ERC20.sol\";\nimport \"@openzeppelin/contracts/access/Ownable.sol\";\nimport {Math} from \"@openzeppelin/contracts/utils/math/Math.sol\";\n\nimport \"../token/interfaces/IXERC20Lockbox.sol\";\nimport \"../token/interfaces/IXERC20.sol\";\nimport \"../token/interfaces/IXERC20VS.sol\";\nimport \"../token/interfaces/IFiatToken.sol\";\n\ncontract ERC20Test is ERC20 {\n    uint8 public immutable _decimals;\n\n    constructor(\n        string memory name,\n        string memory symbol,\n        uint256 totalSupply,\n        uint8 __decimals\n    ) ERC20(name, symbol) {\n        _decimals = __decimals;\n        _mint(msg.sender, totalSupply);\n    }\n\n    function decimals() public view override returns (uint8) {\n        return _decimals;\n    }\n\n    function mint(uint256 amount) public {\n        _mint(msg.sender, amount);\n    }\n\n    function mintTo(address account, uint256 amount) public {\n        _mint(account, amount);\n    }\n\n    function burnFrom(address account, uint256 amount) public {\n        _burn(account, amount);\n    }\n}\n\ncontract FiatTokenTest is ERC20Test, IFiatToken {\n    constructor(\n        string memory name,\n        string memory symbol,\n        uint256 totalSupply,\n        uint8 __decimals\n    ) ERC20Test(name, symbol, totalSupply, __decimals) {}\n\n    function burn(uint256 amount) public override {\n        _burn(msg.sender, amount);\n    }\n\n    function mint(address account, uint256 amount) public returns (bool) {\n        _mint(account, amount);\n        return true;\n    }\n\n    function minterAllowance(address _minter) public pure returns (uint256) {\n        return type(uint256).max;\n    }\n}\n\ncontract XERC20Test is ERC20Test, Ownable, IXERC20 {\n    constructor(\n        string memory name,\n        string memory symbol,\n        uint256 totalSupply,\n        uint8 __decimals\n    ) ERC20Test(name, symbol, totalSupply, __decimals) Ownable() {}\n\n    function initialize() external {\n        _transferOwnership(msg.sender);\n    }\n\n    function mint(address account, uint256 amount) public override {\n        _mint(account, amount);\n    }\n\n    function burn(address account, uint256 amount) public override {\n        _burn(account, amount);\n    }\n\n    function setLimits(address, uint256, uint256) external pure {\n        assert(false);\n    }\n\n    function owner() public view override(Ownable, IXERC20) returns (address) {\n        return Ownable.owner();\n    }\n\n    function burningCurrentLimitOf(\n        address _bridge\n    ) external view returns (uint256) {\n        return type(uint256).max;\n    }\n\n    function mintingCurrentLimitOf(\n        address _bridge\n    ) external view returns (uint256) {\n        return type(uint256).max;\n    }\n\n    function mintingMaxLimitOf(\n        address _bridge\n    ) external view returns (uint256) {\n        return type(uint256).max;\n    }\n\n    function burningMaxLimitOf(\n        address _bridge\n    ) external view returns (uint256) {\n        return type(uint256).max;\n    }\n}\n\ncontract XERC20VSTest is ERC20Test, Ownable, IXERC20VS {\n    event ConfigurationChanged(\n        address indexed bridge,\n        uint112 bufferCap,\n        uint128 rateLimitPerSecond\n    );\n\n    mapping(address bridge => RateLimitMidPoint bridgeRateLimit)\n        internal _rateLimits;\n\n    constructor(\n        string memory name,\n        string memory symbol,\n        uint256 totalSupply,\n        uint8 __decimals\n    ) ERC20Test(name, symbol, totalSupply, __decimals) Ownable() {\n        _transferOwnership(msg.sender);\n    }\n\n    function initialize() external {\n        _transferOwnership(msg.sender);\n    }\n\n    function owner() public view override(Ownable) returns (address) {\n        return Ownable.owner();\n    }\n\n    function lockbox() external view override returns (address) {\n        return address(0);\n    }\n\n    function rateLimits(\n        address _bridge\n    ) external view override returns (RateLimitMidPoint memory _rateLimit) {\n        return _rateLimits[_bridge];\n    }\n\n    function mintingMaxLimitOf(\n        address _bridge\n    ) external view returns (uint256) {\n        return _rateLimits[_bridge].bufferCap;\n    }\n\n    function burningMaxLimitOf(\n        address _bridge\n    ) external view returns (uint256) {\n        return _rateLimits[_bridge].bufferCap;\n    }\n\n    function burningCurrentLimitOf(\n        address _bridge\n    ) external view returns (uint256) {\n        return _rateLimits[_bridge].bufferCap - _buffer(_rateLimits[_bridge]);\n    }\n\n    function mintingCurrentLimitOf(\n        address _bridge\n    ) external view returns (uint256) {\n        return _buffer(_rateLimits[_bridge]);\n    }\n\n    function mint(address account, uint256 amount) public override {\n        _mint(account, amount);\n    }\n\n    function burn(address account, uint256 amount) public override {\n        _burn(account, amount);\n    }\n\n    function setBufferCap(\n        address _bridge,\n        uint256 _newBufferCap\n    ) external override {}\n\n    function setRateLimitPerSecond(\n        address _bridge,\n        uint128 _newRateLimitPerSecond\n    ) external override {}\n\n    function addBridge(\n        RateLimitMidPointInfo memory rateLimit\n    ) external onlyOwner {\n        _rateLimits[rateLimit.bridge] = RateLimitMidPoint({\n            bufferCap: rateLimit.bufferCap,\n            lastBufferUsedTime: uint32(block.timestamp),\n            bufferStored: uint112(rateLimit.bufferCap / 2),\n            midPoint: uint112(rateLimit.bufferCap / 2),\n            rateLimitPerSecond: rateLimit.rateLimitPerSecond\n        });\n\n        emit ConfigurationChanged(\n            rateLimit.bridge,\n            rateLimit.bufferCap,\n            rateLimit.rateLimitPerSecond\n        );\n    }\n\n    function removeBridge(address _bridge) external override {\n        delete _rateLimits[_bridge];\n    }\n\n    function _buffer(\n        RateLimitMidPoint storage limit\n    ) internal view returns (uint256) {\n        uint256 elapsed;\n        unchecked {\n            elapsed = uint32(block.timestamp) - limit.lastBufferUsedTime;\n        }\n\n        uint256 accrued = uint256(limit.rateLimitPerSecond) * elapsed;\n        if (limit.bufferStored < limit.midPoint) {\n            return\n                Math.min(\n                    uint256(limit.bufferStored) + accrued,\n                    uint256(limit.midPoint)\n                );\n        } else if (limit.bufferStored > limit.midPoint) {\n            /// past midpoint so subtract accrued off bufferStored back down to midpoint\n\n            /// second part of if statement will not be evaluated if first part is true\n            if (\n                accrued > limit.bufferStored ||\n                limit.bufferStored - accrued < limit.midPoint\n            ) {\n                /// if accrued is more than buffer stored, subtracting will underflow,\n                /// and we are at the midpoint, so return that\n                return limit.midPoint;\n            } else {\n                return limit.bufferStored - accrued;\n            }\n        } else {\n            /// no change\n            return limit.bufferStored;\n        }\n    }\n\n    function rateLimitPerSecond(address from) public view returns (uint256) {\n        return _rateLimits[from].rateLimitPerSecond;\n    }\n\n    function bufferCap(address from) public view returns (uint256) {\n        return _rateLimits[from].bufferCap;\n    }\n\n    function mintOnlyOwner(address account, uint256 amount) public onlyOwner {\n        _mint(account, amount);\n    }\n}\n\ncontract XERC20LockboxTest is IXERC20Lockbox {\n    IXERC20 public immutable XERC20;\n    IERC20 public immutable ERC20;\n\n    constructor(\n        string memory name,\n        string memory symbol,\n        uint256 totalSupply,\n        uint8 __decimals\n    ) {\n        ERC20Test erc20 = new ERC20Test(name, symbol, totalSupply, __decimals);\n        erc20.transfer(msg.sender, totalSupply);\n        ERC20 = erc20;\n        XERC20 = new XERC20Test(name, symbol, 0, __decimals);\n    }\n\n    function depositTo(address _user, uint256 _amount) public {\n        ERC20.transferFrom(msg.sender, address(this), _amount);\n        XERC20.mint(_user, _amount);\n    }\n\n    function deposit(uint256 _amount) external {\n        depositTo(msg.sender, _amount);\n    }\n\n    function depositNativeTo(address) external payable {\n        assert(false);\n    }\n\n    function withdrawTo(address _user, uint256 _amount) public {\n        XERC20.burn(msg.sender, _amount);\n        ERC20Test(address(ERC20)).mintTo(_user, _amount);\n    }\n\n    function withdraw(uint256 _amount) external {\n        withdrawTo(msg.sender, _amount);\n    }\n}\n"},"contracts/test/ERC4626/ERC4626Test.sol":{"content":"// SPDX-License-Identifier: Apache-2.0\npragma solidity >=0.8.0;\n\nimport \"@openzeppelin/contracts/token/ERC20/extensions/ERC4626.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/ERC20.sol\";\nimport \"@openzeppelin/contracts/interfaces/IERC20.sol\";\n\ncontract ERC4626Test is ERC4626 {\n    constructor(\n        address _asset,\n        string memory _name,\n        string memory _symbol\n    ) ERC4626(IERC20(_asset)) ERC20(_name, _symbol) {}\n}\n"},"contracts/test/ERC721Test.sol":{"content":"// SPDX-License-Identifier: Apache-2.0\npragma solidity >=0.8.0;\n\nimport \"@openzeppelin/contracts/token/ERC721/extensions/ERC721Enumerable.sol\";\n\ncontract ERC721Test is ERC721Enumerable {\n    constructor(\n        string memory name,\n        string memory symbol,\n        uint256 _mintAmount\n    ) ERC721(name, symbol) {\n        for (uint256 i = 0; i < _mintAmount; i++) {\n            _mint(msg.sender, i);\n        }\n    }\n\n    function _baseURI() internal pure override returns (string memory) {\n        return \"TEST-BASE-URI\";\n    }\n}\n"},"contracts/test/LightTestRecipient.sol":{"content":"// SPDX-License-Identifier: MIT OR Apache-2.0\npragma solidity >=0.6.11;\n\nimport \"./TestRecipient.sol\";\n\ncontract LightTestRecipient is TestRecipient {\n    // solhint-disable-next-line no-empty-blocks\n    function handle(\n        uint32 _origin,\n        bytes32 _sender,\n        bytes calldata _data\n    ) external payable override {\n        // do nothing\n    }\n}\n"},"contracts/test/TestCcipReadIsm.sol":{"content":"// SPDX-License-Identifier: MIT OR Apache-2.0\npragma solidity >=0.8.0;\n\nimport {Message} from \"../libs/Message.sol\";\nimport {IMailbox} from \"../interfaces/IMailbox.sol\";\nimport {AbstractCcipReadIsm} from \"../isms/ccip-read/AbstractCcipReadIsm.sol\";\nimport {ICcipReadIsm} from \"../interfaces/isms/ICcipReadIsm.sol\";\nimport {IMessageRecipient} from \"../interfaces/IMessageRecipient.sol\";\nimport {IOptimismPortal} from \"../interfaces/optimism/IOptimismPortal.sol\";\nimport {IInterchainSecurityModule, ISpecifiesInterchainSecurityModule} from \"../interfaces/IInterchainSecurityModule.sol\";\nimport {MailboxClient} from \"../client/MailboxClient.sol\";\n\ncontract TestCcipReadIsm is AbstractCcipReadIsm, IMessageRecipient {\n    uint8 public receivedMessages = 0;\n\n    event ReceivedMessage(\n        uint32 indexed origin,\n        bytes32 indexed sender,\n        uint256 indexed value,\n        bytes message\n    );\n\n    constructor(string[] memory _urls) {\n        _transferOwnership(msg.sender);\n        setUrls(_urls);\n    }\n\n    function _offchainLookupCalldata(\n        bytes calldata /*_message*/\n    ) internal pure override returns (bytes memory) {\n        return bytes(\"\");\n    }\n\n    function verify(\n        bytes calldata /*_metadata*/,\n        bytes calldata /*_message*/\n    ) external override returns (bool) {\n        receivedMessages++;\n\n        return true;\n    }\n\n    /**\n     * @dev no-op handle\n     */\n    function handle(\n        uint32 _origin,\n        bytes32 _sender,\n        bytes calldata _messageBody\n    ) external payable {\n        emit ReceivedMessage(_origin, _sender, msg.value, _messageBody);\n    }\n}\n"},"contracts/test/TestGasRouter.sol":{"content":"// SPDX-License-Identifier: MIT OR Apache-2.0\npragma solidity >=0.6.11;\n\nimport \"../client/GasRouter.sol\";\n\ncontract TestGasRouter is GasRouter {\n    constructor(address _mailbox) GasRouter(_mailbox) {}\n\n    function dispatch(uint32 _destination, bytes memory _msg) external payable {\n        _GasRouter_dispatch(_destination, msg.value, _msg, address(hook));\n    }\n\n    function _handle(uint32, bytes32, bytes calldata) internal pure override {}\n}\n"},"contracts/test/TestInterchainGasPaymaster.sol":{"content":"// SPDX-License-Identifier: MIT OR Apache-2.0\npragma solidity >=0.8.0;\n\n// ============ Internal Imports ============\nimport {InterchainGasPaymaster} from \"../hooks/igp/InterchainGasPaymaster.sol\";\n\ncontract TestInterchainGasPaymaster is InterchainGasPaymaster {\n    uint256 public constant gasPrice = 10;\n\n    constructor() {\n        initialize(msg.sender, msg.sender);\n    }\n\n    function quoteGasPayment(\n        uint32,\n        uint256 gasAmount\n    ) public pure override returns (uint256) {\n        return gasPrice * gasAmount;\n    }\n\n    function getDefaultGasUsage() public pure returns (uint256) {\n        return DEFAULT_GAS_USAGE;\n    }\n}\n"},"contracts/test/TestIsm.sol":{"content":"// SPDX-License-Identifier: MIT OR Apache-2.0\npragma solidity >=0.6.11;\n\nimport {IInterchainSecurityModule} from \"../interfaces/IInterchainSecurityModule.sol\";\n\ncontract TestIsm is IInterchainSecurityModule {\n    uint8 public moduleType = uint8(Types.NULL);\n\n    bool verifyResult = true;\n\n    function setVerify(bool _verify) public {\n        verifyResult = _verify;\n    }\n\n    function verify(bytes calldata, bytes calldata) public view returns (bool) {\n        return verifyResult;\n    }\n}\n"},"contracts/test/TestMailbox.sol":{"content":"// SPDX-License-Identifier: MIT OR Apache-2.0\npragma solidity >=0.8.0;\n\nimport {Mailbox} from \"../Mailbox.sol\";\nimport {TypeCasts} from \"../libs/TypeCasts.sol\";\nimport {Message} from \"../libs/Message.sol\";\nimport {MerkleLib} from \"../libs/Merkle.sol\";\nimport {IMessageRecipient} from \"../interfaces/IMessageRecipient.sol\";\n\ncontract TestMailbox is Mailbox {\n    using TypeCasts for bytes32;\n\n    constructor(uint32 _localDomain) Mailbox(_localDomain) {\n        _transferOwnership(msg.sender);\n    }\n\n    function testHandle(\n        uint32 _origin,\n        bytes32 _sender,\n        bytes32 _recipient,\n        bytes calldata _body\n    ) external {\n        IMessageRecipient(_recipient.bytes32ToAddress()).handle(\n            _origin,\n            _sender,\n            _body\n        );\n    }\n\n    function buildOutboundMessage(\n        uint32 destinationDomain,\n        bytes32 recipientAddress,\n        bytes calldata body\n    ) external view returns (bytes memory) {\n        return _buildMessage(destinationDomain, recipientAddress, body);\n    }\n\n    function buildInboundMessage(\n        uint32 originDomain,\n        bytes32 recipientAddress,\n        bytes32 senderAddress,\n        bytes calldata body\n    ) external view returns (bytes memory) {\n        return\n            Message.formatMessage(\n                VERSION,\n                nonce,\n                originDomain,\n                senderAddress,\n                localDomain,\n                recipientAddress,\n                body\n            );\n    }\n\n    function updateLatestDispatchedId(bytes32 _id) external {\n        latestDispatchedId = _id;\n    }\n}\n"},"contracts/test/TestMerkle.sol":{"content":"// SPDX-License-Identifier: MIT OR Apache-2.0\npragma solidity >=0.8.0;\nimport {MerkleLib} from \"../libs/Merkle.sol\";\n\ncontract TestMerkle {\n    using MerkleLib for MerkleLib.Tree;\n\n    MerkleLib.Tree public tree;\n\n    // solhint-disable-next-line no-empty-blocks\n    constructor() {}\n\n    function insert(bytes32 _node) external {\n        tree.insert(_node);\n    }\n\n    function branchRoot(\n        bytes32 _leaf,\n        bytes32[32] calldata _proof,\n        uint256 _index\n    ) external pure returns (bytes32 _node) {\n        return MerkleLib.branchRoot(_leaf, _proof, _index);\n    }\n\n    /**\n     * @notice Returns the number of inserted leaves in the tree\n     */\n    function count() public view returns (uint256) {\n        return tree.count;\n    }\n\n    function root() public view returns (bytes32) {\n        return tree.root();\n    }\n}\n"},"contracts/test/TestMerkleTreeHook.sol":{"content":"// SPDX-License-Identifier: MIT OR Apache-2.0\npragma solidity >=0.8.0;\n\nimport {MerkleLib} from \"../libs/Merkle.sol\";\nimport {MerkleTreeHook} from \"../hooks/MerkleTreeHook.sol\";\n\ncontract TestMerkleTreeHook is MerkleTreeHook {\n    using MerkleLib for MerkleLib.Tree;\n\n    constructor(address _mailbox) MerkleTreeHook(_mailbox) {}\n\n    function proof() external view returns (bytes32[32] memory) {\n        bytes32[32] memory _zeroes = MerkleLib.zeroHashes();\n        uint256 _index = _tree.count - 1;\n        bytes32[32] memory _proof;\n\n        for (uint256 i = 0; i < 32; i++) {\n            uint256 _ithBit = (_index >> i) & 0x01;\n            if (_ithBit == 1) {\n                _proof[i] = _tree.branch[i];\n            } else {\n                _proof[i] = _zeroes[i];\n            }\n        }\n        return _proof;\n    }\n\n    function insert(bytes32 _id) external {\n        _tree.insert(_id);\n    }\n}\n"},"contracts/test/TestMessage.sol":{"content":"// SPDX-License-Identifier: MIT OR Apache-2.0\npragma solidity >=0.6.11;\n\nimport {Message} from \"../libs/Message.sol\";\n\ncontract TestMessage {\n    using Message for bytes;\n\n    function version(\n        bytes calldata _message\n    ) external pure returns (uint32 _version) {\n        return _message.version();\n    }\n\n    function nonce(\n        bytes calldata _message\n    ) external pure returns (uint256 _nonce) {\n        return _message.nonce();\n    }\n\n    function body(\n        bytes calldata _message\n    ) external pure returns (bytes calldata _body) {\n        return _message.body();\n    }\n\n    function origin(\n        bytes calldata _message\n    ) external pure returns (uint32 _origin) {\n        return _message.origin();\n    }\n\n    function sender(\n        bytes calldata _message\n    ) external pure returns (bytes32 _sender) {\n        return _message.sender();\n    }\n\n    function destination(\n        bytes calldata _message\n    ) external pure returns (uint32 _destination) {\n        return _message.destination();\n    }\n\n    function recipient(\n        bytes calldata _message\n    ) external pure returns (bytes32 _recipient) {\n        return _message.recipient();\n    }\n\n    function recipientAddress(\n        bytes calldata _message\n    ) external pure returns (address _recipient) {\n        return _message.recipientAddress();\n    }\n\n    function id(bytes calldata _message) external pure returns (bytes32) {\n        return _message.id();\n    }\n}\n"},"contracts/test/TestPostDispatchHook.sol":{"content":"// SPDX-License-Identifier: MIT OR Apache-2.0\npragma solidity >=0.8.0;\n\nimport {Message} from \"../libs/Message.sol\";\n\nimport {IPostDispatchHook} from \"../interfaces/hooks/IPostDispatchHook.sol\";\nimport {AbstractPostDispatchHook} from \"../hooks/libs/AbstractPostDispatchHook.sol\";\n\ncontract TestPostDispatchHook is AbstractPostDispatchHook {\n    using Message for bytes;\n\n    // ============ Public Storage ============\n\n    // test fees for quoteDispatch\n    uint256 public fee = 0;\n\n    // used to keep track of dispatched message\n    mapping(bytes32 messageId => bool dispatched) public messageDispatched;\n\n    // ============ External Functions ============\n\n    /// @inheritdoc IPostDispatchHook\n    function hookType() external pure override returns (uint8) {\n        return uint8(IPostDispatchHook.Types.UNUSED);\n    }\n\n    function supportsMetadata(\n        bytes calldata\n    ) public pure override returns (bool) {\n        return true;\n    }\n\n    function setFee(uint256 _fee) external {\n        fee = _fee;\n    }\n\n    // ============ Internal functions ============\n    function _postDispatch(\n        bytes calldata,\n        /*metadata*/ bytes calldata message\n    ) internal override {\n        messageDispatched[message.id()] = true;\n    }\n\n    function _quoteDispatch(\n        bytes calldata /*metadata*/,\n        bytes calldata /*message*/\n    ) internal view override returns (uint256) {\n        return fee;\n    }\n}\n"},"contracts/test/TestQuery.sol":{"content":"// SPDX-License-Identifier: Apache-2.0\npragma solidity ^0.8.13;\n\nimport {InterchainQueryRouter} from \"../middleware/InterchainQueryRouter.sol\";\nimport {TypeCasts} from \"../libs/TypeCasts.sol\";\nimport {CallLib} from \"../middleware/libs/Call.sol\";\n\nimport {Ownable} from \"@openzeppelin/contracts/access/Ownable.sol\";\n\ncontract TestQuery {\n    InterchainQueryRouter public router;\n\n    event Owner(uint256, address);\n\n    constructor(address _router) {\n        router = InterchainQueryRouter(_router);\n    }\n\n    /**\n     * @dev Fetches owner of InterchainQueryRouter on provided domain and passes along with provided secret to `this.receiveRouterOwner`\n     */\n    function queryRouterOwner(uint32 domain, uint256 secret) external {\n        address target = TypeCasts.bytes32ToAddress(router.routers(domain));\n        CallLib.StaticCallWithCallback[]\n            memory calls = new CallLib.StaticCallWithCallback[](1);\n        calls[0] = CallLib.build(\n            target,\n            abi.encodeWithSelector(Ownable.owner.selector),\n            abi.encodeWithSelector(this.receiveRouterOwner.selector, secret)\n        );\n        router.query(domain, calls);\n    }\n\n    /**\n     * @dev `msg.sender` must be restricted to `this.router` to prevent any local account from spoofing query data.\n     */\n    function receiveRouterOwner(uint256 secret, address owner) external {\n        require(msg.sender == address(router), \"TestQuery: not from router\");\n        emit Owner(secret, owner);\n    }\n}\n"},"contracts/test/TestQuerySender.sol":{"content":"// SPDX-License-Identifier: MIT OR Apache-2.0\npragma solidity >=0.8.0;\n\nimport {InterchainQueryRouter} from \"../middleware/InterchainQueryRouter.sol\";\nimport {CallLib} from \"../middleware/libs/Call.sol\";\n\ncontract TestQuerySender {\n    InterchainQueryRouter queryRouter;\n\n    address public lastAddressResult;\n    uint256 public lastUint256Result;\n    bytes32 public lastBytes32Result;\n\n    event ReceivedAddressResult(address result);\n    event ReceivedUint256Result(uint256 result);\n    event ReceivedBytes32Result(bytes32 result);\n\n    function initialize(address _queryRouterAddress) external {\n        queryRouter = InterchainQueryRouter(_queryRouterAddress);\n    }\n\n    function queryAddress(\n        uint32 _destinationDomain,\n        address _target,\n        bytes calldata _targetData,\n        uint256 _gasAmount\n    ) external payable {\n        queryAndPayFor(\n            _destinationDomain,\n            _target,\n            _targetData,\n            this.handleQueryAddressResult.selector,\n            _gasAmount\n        );\n    }\n\n    function handleQueryAddressResult(address _result) external {\n        emit ReceivedAddressResult(_result);\n        lastAddressResult = _result;\n    }\n\n    function queryUint256(\n        uint32 _destinationDomain,\n        address _target,\n        bytes calldata _targetData,\n        uint256 _gasAmount\n    ) external payable {\n        queryAndPayFor(\n            _destinationDomain,\n            _target,\n            _targetData,\n            this.handleQueryUint256Result.selector,\n            _gasAmount\n        );\n    }\n\n    function handleQueryUint256Result(uint256 _result) external {\n        emit ReceivedUint256Result(_result);\n        lastUint256Result = _result;\n    }\n\n    function queryBytes32(\n        uint32 _destinationDomain,\n        address _target,\n        bytes calldata _targetData,\n        uint256 _gasAmount\n    ) external payable {\n        queryAndPayFor(\n            _destinationDomain,\n            _target,\n            _targetData,\n            this.handleQueryBytes32Result.selector,\n            _gasAmount\n        );\n    }\n\n    function handleQueryBytes32Result(bytes32 _result) external {\n        emit ReceivedBytes32Result(_result);\n        lastBytes32Result = _result;\n    }\n\n    function queryAndPayFor(\n        uint32 _destinationDomain,\n        address _target,\n        bytes calldata _targetData,\n        bytes4 _callbackSelector,\n        uint256 /*_gasAmount*/\n    ) internal {\n        queryRouter.query(\n            _destinationDomain,\n            _target,\n            _targetData,\n            abi.encodePacked(_callbackSelector)\n        );\n    }\n}\n"},"contracts/test/TestRecipient.sol":{"content":"// SPDX-License-Identifier: MIT OR Apache-2.0\npragma solidity >=0.8.0;\n\nimport {Ownable} from \"@openzeppelin/contracts/access/Ownable.sol\";\n\nimport {IMessageRecipient} from \"../interfaces/IMessageRecipient.sol\";\nimport {IInterchainSecurityModule, ISpecifiesInterchainSecurityModule} from \"../interfaces/IInterchainSecurityModule.sol\";\n\ncontract TestRecipient is\n    Ownable,\n    IMessageRecipient,\n    ISpecifiesInterchainSecurityModule\n{\n    IInterchainSecurityModule public interchainSecurityModule;\n    bytes32 public lastSender;\n    bytes public lastData;\n\n    address public lastCaller;\n    string public lastCallMessage;\n\n    event ReceivedMessage(\n        uint32 indexed origin,\n        bytes32 indexed sender,\n        uint256 indexed value,\n        string message\n    );\n\n    event ReceivedCall(address indexed caller, uint256 amount, string message);\n\n    function handle(\n        uint32 _origin,\n        bytes32 _sender,\n        bytes calldata _data\n    ) external payable virtual override {\n        emit ReceivedMessage(_origin, _sender, msg.value, string(_data));\n        lastSender = _sender;\n        lastData = _data;\n    }\n\n    function fooBar(uint256 amount, string calldata message) external {\n        emit ReceivedCall(msg.sender, amount, message);\n        lastCaller = msg.sender;\n        lastCallMessage = message;\n    }\n\n    function setInterchainSecurityModule(address _ism) external onlyOwner {\n        interchainSecurityModule = IInterchainSecurityModule(_ism);\n    }\n\n    receive() external payable {}\n}\n"},"contracts/test/TestRemoteChallenger.sol":{"content":"// SPDX-License-Identifier: MIT OR Apache-2.0\npragma solidity >=0.8.0;\n\nimport {IRemoteChallenger} from \"../interfaces/avs/IRemoteChallenger.sol\";\nimport {HyperlaneServiceManager} from \"../avs/HyperlaneServiceManager.sol\";\n\ncontract TestRemoteChallenger is IRemoteChallenger {\n    HyperlaneServiceManager internal immutable hsm;\n\n    constructor(HyperlaneServiceManager _hsm) {\n        hsm = _hsm;\n    }\n\n    function challengeDelayBlocks() external pure returns (uint256) {\n        return 50400; // one week of eth L1 blocks\n    }\n\n    function handleChallenge(address operator) external {\n        hsm.freezeOperator(operator);\n    }\n}\n"},"contracts/test/TestRouter.sol":{"content":"// SPDX-License-Identifier: MIT OR Apache-2.0\npragma solidity >=0.6.11;\n\nimport \"../client/Router.sol\";\n\ncontract TestRouter is Router {\n    event InitializeOverload();\n\n    constructor(address _mailbox) Router(_mailbox) {}\n\n    function initialize(\n        address _hook,\n        address _interchainSecurityModule\n    ) public initializer {\n        _MailboxClient_initialize(_hook, _interchainSecurityModule, msg.sender);\n    }\n\n    function _handle(uint32, bytes32, bytes calldata) internal pure override {}\n\n    function isRemoteRouter(\n        uint32 _domain,\n        bytes32 _potentialRemoteRouter\n    ) external view returns (bool) {\n        return _isRemoteRouter(_domain, _potentialRemoteRouter);\n    }\n\n    function mustHaveRemoteRouter(\n        uint32 _domain\n    ) external view returns (bytes32) {\n        return _mustHaveRemoteRouter(_domain);\n    }\n\n    function dispatch(uint32 _destination, bytes memory _msg) external payable {\n        _dispatch(_destination, _msg);\n    }\n}\n"},"contracts/test/TestSendReceiver.sol":{"content":"// SPDX-License-Identifier: MIT OR Apache-2.0\npragma solidity >=0.8.0;\n\nimport {TypeCasts} from \"../libs/TypeCasts.sol\";\n\nimport {IInterchainGasPaymaster} from \"../interfaces/IInterchainGasPaymaster.sol\";\nimport {IMessageRecipient} from \"../interfaces/IMessageRecipient.sol\";\nimport {IMailbox} from \"../interfaces/IMailbox.sol\";\nimport {IPostDispatchHook} from \"../interfaces/hooks/IPostDispatchHook.sol\";\nimport {IInterchainSecurityModule, ISpecifiesInterchainSecurityModule} from \"../interfaces/IInterchainSecurityModule.sol\";\n\nimport {MailboxClient} from \"../client/MailboxClient.sol\";\n\ncontract TestSendReceiver is IMessageRecipient {\n    using TypeCasts for address;\n\n    uint256 public constant HANDLE_GAS_AMOUNT = 50_000;\n\n    event Handled(bytes32 blockHash);\n\n    function dispatchToSelf(\n        IMailbox _mailbox,\n        uint32 _destinationDomain,\n        bytes calldata _messageBody\n    ) external payable {\n        // TODO: handle topping up?\n        _mailbox.dispatch{value: msg.value}(\n            _destinationDomain,\n            address(this).addressToBytes32(),\n            _messageBody\n        );\n    }\n\n    function dispatchToSelf(\n        IMailbox _mailbox,\n        uint32 _destinationDomain,\n        bytes calldata _messageBody,\n        IPostDispatchHook hook\n    ) external payable {\n        // TODO: handle topping up?\n        _mailbox.dispatch{value: msg.value}(\n            _destinationDomain,\n            address(this).addressToBytes32(),\n            _messageBody,\n            bytes(\"\"),\n            hook\n        );\n    }\n\n    function handle(\n        uint32,\n        bytes32,\n        bytes calldata _messageBody\n    ) external payable override {\n        bytes memory hardcodedFail = \"failMessageBody\";\n        require(\n            keccak256(_messageBody) != keccak256(hardcodedFail),\n            \"failMessageBody\"\n        );\n\n        bytes32 blockHash = previousBlockHash();\n        bool isBlockHashEndIn0 = uint256(blockHash) % 16 == 0;\n        require(!isBlockHashEndIn0, \"block hash ends in 0\");\n\n        emit Handled(blockHash);\n    }\n\n    function previousBlockHash() internal view returns (bytes32) {\n        return blockhash(block.number - 1);\n    }\n}\n"},"contracts/token/extensions/HypERC4626.sol":{"content":"// SPDX-License-Identifier: MIT OR Apache-2.0\npragma solidity >=0.8.0;\n\n/*@@@@@@@       @@@@@@@@@\n @@@@@@@@@       @@@@@@@@@\n  @@@@@@@@@       @@@@@@@@@\n   @@@@@@@@@       @@@@@@@@@\n    @@@@@@@@@@@@@@@@@@@@@@@@@\n     @@@@@  HYPERLANE  @@@@@@@\n    @@@@@@@@@@@@@@@@@@@@@@@@@\n   @@@@@@@@@       @@@@@@@@@\n  @@@@@@@@@       @@@@@@@@@\n @@@@@@@@@       @@@@@@@@@\n@@@@@@@@@       @@@@@@@@*/\n\n// ============ Internal Imports ============\nimport {HypERC20} from \"../HypERC20.sol\";\nimport {Message} from \"../../libs/Message.sol\";\nimport {TokenMessage} from \"../libs/TokenMessage.sol\";\nimport {TokenRouter} from \"../libs/TokenRouter.sol\";\nimport {Router} from \"../../client/Router.sol\";\nimport {FungibleTokenRouter} from \"../libs/FungibleTokenRouter.sol\";\n\n// ============ External Imports ============\nimport {Math} from \"@openzeppelin/contracts/utils/math/Math.sol\";\nimport {ERC20Upgradeable} from \"@openzeppelin/contracts-upgradeable/token/ERC20/ERC20Upgradeable.sol\";\n\n/**\n * @title Hyperlane ERC20 Rebasing Token\n * @author Abacus Works\n * @notice This contract implements a rebasing token that reflects yields from the origin chain\n * @dev Messages contain amounts as shares of ERC4626 and exchange rate of assets per share.\n * @dev internal ERC20 balances storage mapping is in share units\n * @dev internal ERC20 allowances storage mapping is in asset units\n * @dev public ERC20 interface is in asset units\n */\ncontract HypERC4626 is HypERC20 {\n    using Math for uint256;\n    using Message for bytes;\n    using TokenMessage for bytes;\n\n    event ExchangeRateUpdated(uint256 newExchangeRate, uint32 rateUpdateNonce);\n\n    uint256 public constant PRECISION = 1e10;\n    uint32 public immutable collateralDomain;\n    uint256 public exchangeRate; // 1e10\n    uint32 public previousNonce;\n\n    constructor(\n        uint8 _decimals,\n        uint256 _scale,\n        address _mailbox,\n        uint32 _collateralDomain\n    ) HypERC20(_decimals, _scale, _mailbox) {\n        collateralDomain = _collateralDomain;\n        exchangeRate = 1e10;\n        _disableInitializers();\n    }\n\n    // ============ Public Functions ============\n\n    /// Override totalSupply to return the total assets instead of shares. This reflects the actual circulating supply in terms of assets, accounting for rebasing\n    /// @inheritdoc ERC20Upgradeable\n    function totalSupply() public view virtual override returns (uint256) {\n        return sharesToAssets(totalShares());\n    }\n\n    /// This returns the balance of the account in terms of assets, accounting for rebasing\n    /// @inheritdoc ERC20Upgradeable\n    function balanceOf(\n        address account\n    ) public view virtual override returns (uint256) {\n        return sharesToAssets(shareBalanceOf(account));\n    }\n\n    /// This function provides the total supply in terms of shares\n    function totalShares() public view returns (uint256) {\n        return super.totalSupply();\n    }\n\n    ///  This returns the balance of the account in terms of shares\n    function shareBalanceOf(address account) public view returns (uint256) {\n        return super.balanceOf(account);\n    }\n\n    function assetsToShares(uint256 _amount) public view returns (uint256) {\n        return _amount.mulDiv(PRECISION, exchangeRate);\n    }\n\n    function sharesToAssets(uint256 _shares) public view returns (uint256) {\n        return _shares.mulDiv(exchangeRate, PRECISION);\n    }\n\n    // @inheritdoc HypERC20\n    // @dev Amount specified by the user is in assets, but the internal accounting is in shares\n    function _transferFromSender(\n        uint256 _amount\n    ) internal virtual override returns (bytes memory) {\n        return HypERC20._transferFromSender(assetsToShares(_amount));\n    }\n\n    // @inheritdoc FungibleTokenRouter\n    // @dev Amount specified by user is in assets, but the message accounting is in shares\n    function _outboundAmount(\n        uint256 _localAmount\n    ) internal view virtual override returns (uint256) {\n        return\n            FungibleTokenRouter._outboundAmount(assetsToShares(_localAmount));\n    }\n\n    // @inheritdoc ERC20Upgradeable\n    // @dev Amount specified by user is in assets, but the internal accounting is in shares\n    function _transfer(\n        address _from,\n        address _to,\n        uint256 _amount\n    ) internal virtual override {\n        super._transfer(_from, _to, assetsToShares(_amount));\n    }\n\n    // `_inboundAmount` implementation reused from `FungibleTokenRouter` unchanged because message\n    // accounting is in shares\n\n    // ========== TokenRouter extensions ============\n    /// @inheritdoc TokenRouter\n    function _handle(\n        uint32 _origin,\n        bytes32 _sender,\n        bytes calldata _message\n    ) internal virtual override {\n        if (_origin == collateralDomain) {\n            (uint256 newExchangeRate, uint32 rateUpdateNonce) = abi.decode(\n                _message.metadata(),\n                (uint256, uint32)\n            );\n            // only update if the nonce is greater than the previous nonce\n            if (rateUpdateNonce > previousNonce) {\n                exchangeRate = newExchangeRate;\n                previousNonce = rateUpdateNonce;\n                emit ExchangeRateUpdated(exchangeRate, rateUpdateNonce);\n            }\n        }\n        super._handle(_origin, _sender, _message);\n    }\n}\n"},"contracts/token/extensions/HypERC4626Collateral.sol":{"content":"// SPDX-License-Identifier: Apache-2.0\npragma solidity >=0.8.0;\n\n/*@@@@@@@       @@@@@@@@@\n @@@@@@@@@       @@@@@@@@@\n  @@@@@@@@@       @@@@@@@@@\n   @@@@@@@@@       @@@@@@@@@\n    @@@@@@@@@@@@@@@@@@@@@@@@@\n     @@@@@  HYPERLANE  @@@@@@@\n    @@@@@@@@@@@@@@@@@@@@@@@@@\n   @@@@@@@@@       @@@@@@@@@\n  @@@@@@@@@       @@@@@@@@@\n @@@@@@@@@       @@@@@@@@@\n@@@@@@@@@       @@@@@@@@*/\n\n// ============ Internal Imports ============\nimport {TokenMessage} from \"../libs/TokenMessage.sol\";\nimport {HypERC20Collateral} from \"../HypERC20Collateral.sol\";\nimport {TypeCasts} from \"../../libs/TypeCasts.sol\";\nimport {TokenRouter} from \"../libs/TokenRouter.sol\";\n\n// ============ External Imports ============\nimport \"@openzeppelin/contracts/token/ERC20/extensions/ERC4626.sol\";\n\n/**\n * @title Hyperlane ERC4626 Token Collateral with deposits collateral to a vault\n * @author Abacus Works\n */\ncontract HypERC4626Collateral is HypERC20Collateral {\n    using TypeCasts for address;\n    using TokenMessage for bytes;\n    using Math for uint256;\n\n    // Address of the ERC4626 compatible vault\n    ERC4626 public immutable vault;\n    // Precision for the exchange rate\n    uint256 public constant PRECISION = 1e10;\n    // Null recipient for rebase transfer\n    bytes32 public constant NULL_RECIPIENT =\n        0x0000000000000000000000000000000000000000000000000000000000000001;\n    // Nonce for the rate update, to ensure sequential updates\n    uint32 public rateUpdateNonce;\n\n    constructor(\n        ERC4626 _vault,\n        uint256 _scale,\n        address _mailbox\n    ) HypERC20Collateral(_vault.asset(), _scale, _mailbox) {\n        vault = _vault;\n    }\n\n    function initialize(\n        address _hook,\n        address _interchainSecurityModule,\n        address _owner\n    ) public override initializer {\n        _MailboxClient_initialize(_hook, _interchainSecurityModule, _owner);\n    }\n\n    /**\n     * @inheritdoc TokenRouter\n     * @dev Override `_transferRemote` to send shares as amount and append {exchange rate, nonce} in the message.\n     *      This is preferred for readability and to avoid confusion with the amount of shares. The scaling factor\n     *      is applied to the shares returned by the deposit before sending the message.\n     */\n    function _transferRemote(\n        uint32 _destination,\n        bytes32 _recipient,\n        uint256 _amount,\n        uint256 _value,\n        bytes memory _hookMetadata,\n        address _hook\n    ) internal virtual override returns (bytes32 messageId) {\n        // Can't override _transferFromSender only because we need to pass shares in the token message\n        _transferFromSender(_amount);\n        uint256 _shares = _depositIntoVault(_amount);\n\n        uint256 _exchangeRate = vault.convertToAssets(PRECISION);\n\n        rateUpdateNonce++;\n        bytes memory _tokenMetadata = abi.encode(\n            _exchangeRate,\n            rateUpdateNonce\n        );\n\n        uint256 _outboundAmount = _outboundAmount(_shares);\n        bytes memory _tokenMessage = TokenMessage.format(\n            _recipient,\n            _outboundAmount,\n            _tokenMetadata\n        );\n\n        messageId = _Router_dispatch(\n            _destination,\n            _value,\n            _tokenMessage,\n            _hookMetadata,\n            _hook\n        );\n\n        emit SentTransferRemote(_destination, _recipient, _outboundAmount);\n    }\n\n    /**\n     * @dev Deposits into the vault and increment assetDeposited\n     * @param _amount amount to deposit into vault\n     */\n    function _depositIntoVault(uint256 _amount) internal returns (uint256) {\n        wrappedToken.approve(address(vault), _amount);\n        return vault.deposit(_amount, address(this));\n    }\n\n    /**\n     * @dev Withdraws `_shares` of `wrappedToken` from this contract to `_recipient`\n     * @inheritdoc HypERC20Collateral\n     */\n    function _transferTo(\n        address _recipient,\n        uint256 _shares,\n        bytes calldata\n    ) internal virtual override {\n        vault.redeem(_shares, _recipient, address(this));\n    }\n\n    /**\n     * @dev Update the exchange rate on the synthetic token by accounting for additional yield accrued to the underlying vault\n     * @param _destinationDomain domain of the vault\n     */\n    function rebase(\n        uint32 _destinationDomain,\n        bytes calldata _hookMetadata,\n        address _hook\n    ) public payable {\n        // force a rebase with an empty transfer to 0x1\n        _transferRemote(\n            _destinationDomain,\n            NULL_RECIPIENT,\n            0,\n            msg.value,\n            _hookMetadata,\n            _hook\n        );\n    }\n}\n"},"contracts/token/extensions/HypERC4626OwnerCollateral.sol":{"content":"// SPDX-License-Identifier: Apache-2.0\npragma solidity >=0.8.0;\n\n/*@@@@@@@       @@@@@@@@@\n @@@@@@@@@       @@@@@@@@@\n  @@@@@@@@@       @@@@@@@@@\n   @@@@@@@@@       @@@@@@@@@\n    @@@@@@@@@@@@@@@@@@@@@@@@@\n     @@@@@  HYPERLANE  @@@@@@@\n    @@@@@@@@@@@@@@@@@@@@@@@@@\n   @@@@@@@@@       @@@@@@@@@\n  @@@@@@@@@       @@@@@@@@@\n @@@@@@@@@       @@@@@@@@@\n@@@@@@@@@       @@@@@@@@*/\n\n// ============ Internal Imports ============\nimport {HypERC20Collateral} from \"../HypERC20Collateral.sol\";\n\n// ============ External Imports ============\nimport {ERC4626} from \"@openzeppelin/contracts/token/ERC20/extensions/ERC4626.sol\";\n\n/**\n * @title Hyperlane ERC20 Token Collateral with deposits collateral to a vault, the yield goes to the owner\n * @author ltyu\n */\ncontract HypERC4626OwnerCollateral is HypERC20Collateral {\n    // Address of the ERC4626 compatible vault\n    ERC4626 public immutable vault;\n    // standby precision for exchange rate\n    uint256 public constant PRECISION = 1e10;\n    // Internal balance of total asset deposited\n    uint256 public assetDeposited;\n    // Nonce for the rate update, to ensure sequential updates (not necessary for Owner variant but for compatibility with HypERC4626)\n    uint32 public rateUpdateNonce;\n\n    event ExcessSharesSwept(uint256 amount, uint256 assetsRedeemed);\n\n    constructor(\n        ERC4626 _vault,\n        uint256 _scale,\n        address _mailbox\n    ) HypERC20Collateral(_vault.asset(), _scale, _mailbox) {\n        vault = _vault;\n    }\n\n    function initialize(\n        address _hook,\n        address _interchainSecurityModule,\n        address _owner\n    ) public override initializer {\n        wrappedToken.approve(address(vault), type(uint256).max);\n        _MailboxClient_initialize(_hook, _interchainSecurityModule, _owner);\n    }\n\n    /**\n     * @dev Transfers `_amount` of `wrappedToken` from `msg.sender` to this contract, and deposit into vault\n     * @inheritdoc HypERC20Collateral\n     */\n    function _transferFromSender(\n        uint256 _amount\n    ) internal override returns (bytes memory metadata) {\n        super._transferFromSender(_amount);\n        _depositIntoVault(_amount);\n        rateUpdateNonce++;\n\n        return abi.encode(PRECISION, rateUpdateNonce);\n    }\n\n    /**\n     * @dev Deposits into the vault and increment assetDeposited\n     * @param _amount amount to deposit into vault\n     */\n    function _depositIntoVault(uint256 _amount) internal {\n        assetDeposited += _amount;\n        vault.deposit(_amount, address(this));\n    }\n\n    /**\n     * @dev Transfers `_amount` of `wrappedToken` from this contract to `_recipient`, and withdraws from vault\n     * @inheritdoc HypERC20Collateral\n     */\n    function _transferTo(\n        address _recipient,\n        uint256 _amount,\n        bytes calldata\n    ) internal virtual override {\n        _withdrawFromVault(_amount, _recipient);\n    }\n\n    /**\n     * @dev Withdraws from the vault and decrement assetDeposited\n     * @param _amount amount to withdraw from vault\n     * @param _recipient address to deposit withdrawn underlying to\n     */\n    function _withdrawFromVault(uint256 _amount, address _recipient) internal {\n        assetDeposited -= _amount;\n        vault.withdraw(_amount, _recipient, address(this));\n    }\n\n    /**\n     * @notice Allows the owner to redeem excess shares\n     */\n    function sweep() external onlyOwner {\n        uint256 excessShares = vault.maxRedeem(address(this)) -\n            vault.convertToShares(assetDeposited);\n        uint256 assetsRedeemed = vault.redeem(\n            excessShares,\n            owner(),\n            address(this)\n        );\n        emit ExcessSharesSwept(excessShares, assetsRedeemed);\n    }\n}\n"},"contracts/token/extensions/HypERC721URICollateral.sol":{"content":"// SPDX-License-Identifier: Apache-2.0\npragma solidity >=0.8.0;\n\nimport {HypERC721Collateral} from \"../HypERC721Collateral.sol\";\n\nimport {IERC721MetadataUpgradeable} from \"@openzeppelin/contracts-upgradeable/token/ERC721/extensions/IERC721MetadataUpgradeable.sol\";\n\n/**\n * @title Hyperlane ERC721 Token Collateral that wraps an existing ERC721 with remote transfer and URI relay functionality.\n * @author Abacus Works\n */\ncontract HypERC721URICollateral is HypERC721Collateral {\n    // solhint-disable-next-line no-empty-blocks\n    constructor(\n        address erc721,\n        address _mailbox\n    ) HypERC721Collateral(erc721, _mailbox) {}\n\n    /**\n     * @dev Transfers `_tokenId` of `wrappedToken` from `msg.sender` to this contract.\n     * @return The URI of `_tokenId` on `wrappedToken`.\n     * @inheritdoc HypERC721Collateral\n     */\n    function _transferFromSender(\n        uint256 _tokenId\n    ) internal override returns (bytes memory) {\n        HypERC721Collateral._transferFromSender(_tokenId);\n        return\n            bytes(\n                IERC721MetadataUpgradeable(address(wrappedToken)).tokenURI(\n                    _tokenId\n                )\n            );\n    }\n}\n"},"contracts/token/extensions/HypERC721URIStorage.sol":{"content":"// SPDX-License-Identifier: Apache-2.0\npragma solidity >=0.8.0;\n\nimport {HypERC721} from \"../HypERC721.sol\";\n\nimport {ERC721URIStorageUpgradeable} from \"@openzeppelin/contracts-upgradeable/token/ERC721/extensions/ERC721URIStorageUpgradeable.sol\";\nimport {ERC721EnumerableUpgradeable} from \"@openzeppelin/contracts-upgradeable/token/ERC721/extensions/ERC721EnumerableUpgradeable.sol\";\nimport {ERC721Upgradeable} from \"@openzeppelin/contracts-upgradeable/token/ERC721/ERC721Upgradeable.sol\";\nimport {IERC721Upgradeable} from \"@openzeppelin/contracts-upgradeable/token/ERC721/IERC721Upgradeable.sol\";\n\n/**\n * @title Hyperlane ERC721 Token that extends ERC721URIStorage with remote transfer and URI relay functionality.\n * @author Abacus Works\n */\ncontract HypERC721URIStorage is HypERC721, ERC721URIStorageUpgradeable {\n    constructor(address _mailbox) HypERC721(_mailbox) {}\n\n    function balanceOf(\n        address account\n    )\n        public\n        view\n        override(HypERC721, ERC721Upgradeable, IERC721Upgradeable)\n        returns (uint256)\n    {\n        return HypERC721.balanceOf(account);\n    }\n\n    /**\n     * @return _tokenURI The URI of `_tokenId`.\n     * @inheritdoc HypERC721\n     */\n    function _transferFromSender(\n        uint256 _tokenId\n    ) internal override returns (bytes memory _tokenURI) {\n        _tokenURI = bytes(tokenURI(_tokenId)); // requires minted\n        HypERC721._transferFromSender(_tokenId);\n    }\n\n    /**\n     * @dev Sets the URI for `_tokenId` to `_tokenURI`.\n     * @inheritdoc HypERC721\n     */\n    function _transferTo(\n        address _recipient,\n        uint256 _tokenId,\n        bytes calldata _tokenURI\n    ) internal override {\n        HypERC721._transferTo(_recipient, _tokenId, _tokenURI);\n        _setTokenURI(_tokenId, string(_tokenURI)); // requires minted\n    }\n\n    function tokenURI(\n        uint256 tokenId\n    )\n        public\n        view\n        override(ERC721Upgradeable, ERC721URIStorageUpgradeable)\n        returns (string memory)\n    {\n        return ERC721URIStorageUpgradeable.tokenURI(tokenId);\n    }\n\n    function _beforeTokenTransfer(\n        address from,\n        address to,\n        uint256 tokenId,\n        uint256 batchSize\n    ) internal override(ERC721EnumerableUpgradeable, ERC721Upgradeable) {\n        ERC721EnumerableUpgradeable._beforeTokenTransfer(\n            from,\n            to,\n            tokenId,\n            batchSize\n        );\n    }\n\n    function supportsInterface(\n        bytes4 interfaceId\n    )\n        public\n        view\n        override(ERC721EnumerableUpgradeable, ERC721URIStorageUpgradeable)\n        returns (bool)\n    {\n        return ERC721EnumerableUpgradeable.supportsInterface(interfaceId);\n    }\n\n    function _burn(\n        uint256 tokenId\n    ) internal override(ERC721URIStorageUpgradeable, ERC721Upgradeable) {\n        ERC721URIStorageUpgradeable._burn(tokenId);\n    }\n}\n"},"contracts/token/extensions/HypFiatToken.sol":{"content":"// SPDX-License-Identifier: MIT OR Apache-2.0\npragma solidity >=0.8.0;\n\nimport {IFiatToken} from \"../interfaces/IFiatToken.sol\";\nimport {HypERC20Collateral} from \"../HypERC20Collateral.sol\";\n\n// see https://github.com/circlefin/stablecoin-evm/blob/master/doc/tokendesign.md#issuing-and-destroying-tokens\ncontract HypFiatToken is HypERC20Collateral {\n    constructor(\n        address _fiatToken,\n        uint256 _scale,\n        address _mailbox\n    ) HypERC20Collateral(_fiatToken, _scale, _mailbox) {}\n\n    function _transferFromSender(\n        uint256 _amount\n    ) internal override returns (bytes memory metadata) {\n        // transfer amount to address(this)\n        metadata = super._transferFromSender(_amount);\n        // burn amount of address(this) balance\n        IFiatToken(address(wrappedToken)).burn(_amount);\n    }\n\n    function _transferTo(\n        address _recipient,\n        uint256 _amount,\n        bytes calldata /*metadata*/\n    ) internal override {\n        require(\n            IFiatToken(address(wrappedToken)).mint(_recipient, _amount),\n            \"FiatToken mint failed\"\n        );\n    }\n}\n"},"contracts/token/extensions/HypXERC20.sol":{"content":"// SPDX-License-Identifier: MIT OR Apache-2.0\npragma solidity >=0.8.0;\n\nimport {IXERC20} from \"../interfaces/IXERC20.sol\";\nimport {HypERC20Collateral} from \"../HypERC20Collateral.sol\";\n\ncontract HypXERC20 is HypERC20Collateral {\n    constructor(\n        address _xerc20,\n        uint256 _scale,\n        address _mailbox\n    ) HypERC20Collateral(_xerc20, _scale, _mailbox) {\n        _disableInitializers();\n    }\n\n    function _transferFromSender(\n        uint256 _amountOrId\n    ) internal override returns (bytes memory metadata) {\n        IXERC20(address(wrappedToken)).burn(msg.sender, _amountOrId);\n        return \"\";\n    }\n\n    function _transferTo(\n        address _recipient,\n        uint256 _amountOrId,\n        bytes calldata /*metadata*/\n    ) internal override {\n        IXERC20(address(wrappedToken)).mint(_recipient, _amountOrId);\n    }\n}\n"},"contracts/token/extensions/HypXERC20Lockbox.sol":{"content":"// SPDX-License-Identifier: MIT OR Apache-2.0\npragma solidity >=0.8.0;\n\nimport {IXERC20Lockbox} from \"../interfaces/IXERC20Lockbox.sol\";\nimport {IXERC20, IERC20} from \"../interfaces/IXERC20.sol\";\nimport {HypERC20Collateral} from \"../HypERC20Collateral.sol\";\nimport {SafeERC20} from \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\n\ncontract HypXERC20Lockbox is HypERC20Collateral {\n    uint256 constant MAX_INT = 2 ** 256 - 1;\n\n    IXERC20Lockbox public immutable lockbox;\n    IXERC20 public immutable xERC20;\n\n    using SafeERC20 for IERC20;\n\n    constructor(\n        address _lockbox,\n        uint256 _scale,\n        address _mailbox\n    )\n        HypERC20Collateral(\n            address(IXERC20Lockbox(_lockbox).ERC20()),\n            _scale,\n            _mailbox\n        )\n    {\n        lockbox = IXERC20Lockbox(_lockbox);\n        xERC20 = lockbox.XERC20();\n        approveLockbox();\n        _disableInitializers();\n    }\n\n    /**\n     * @notice Approve the lockbox to spend the wrapped token and xERC20\n     * @dev This function is idempotent and need not be access controlled\n     */\n    function approveLockbox() public {\n        IERC20(wrappedToken).safeApprove(address(lockbox), MAX_INT);\n        IERC20(xERC20).safeApprove(address(lockbox), MAX_INT);\n    }\n\n    /**\n     * @notice Initialize the contract\n     * @param _hook The address of the hook contract\n     * @param _ism The address of the interchain security module\n     * @param _owner The address of the owner\n     */\n    function initialize(\n        address _hook,\n        address _ism,\n        address _owner\n    ) public override initializer {\n        approveLockbox();\n        _MailboxClient_initialize(_hook, _ism, _owner);\n    }\n\n    function _transferFromSender(\n        uint256 _amount\n    ) internal override returns (bytes memory) {\n        // transfer erc20 from sender\n        super._transferFromSender(_amount);\n        // convert erc20 to xERC20\n        lockbox.deposit(_amount);\n        // burn xERC20\n        xERC20.burn(address(this), _amount);\n        return bytes(\"\");\n    }\n\n    function _transferTo(\n        address _recipient,\n        uint256 _amount,\n        bytes calldata /*metadata*/\n    ) internal override {\n        // mint xERC20\n        xERC20.mint(address(this), _amount);\n        // convert xERC20 to erc20\n        lockbox.withdrawTo(_recipient, _amount);\n    }\n}\n"},"contracts/token/extensions/OPL2ToL1TokenBridgeNative.sol":{"content":"// SPDX-License-Identifier: MIT OR Apache-2.0\npragma solidity >=0.8.0;\n\nimport {HypNative} from \"../../token/HypNative.sol\";\nimport {TypeCasts} from \"../../libs/TypeCasts.sol\";\nimport {TokenRouter} from \"../../token/libs/TokenRouter.sol\";\nimport {IStandardBridge} from \"../../interfaces/optimism/IStandardBridge.sol\";\nimport {Quote, ITokenBridge} from \"../../interfaces/ITokenBridge.sol\";\nimport {StandardHookMetadata} from \"../../hooks/libs/StandardHookMetadata.sol\";\nimport {OPL2ToL1CcipReadIsm, OPL2ToL1V1CcipReadIsm, OPL2ToL1V2CcipReadIsm} from \"../../isms/hook/OPL2ToL1CcipReadIsm.sol\";\nimport {OPL2ToL1Withdrawal} from \"../../libs/OPL2ToL1Withdrawal.sol\";\nimport {TokenMessage} from \"../../token/libs/TokenMessage.sol\";\nimport {Message} from \"../../libs/Message.sol\";\nimport {IInterchainSecurityModule} from \"../../interfaces/IInterchainSecurityModule.sol\";\nimport {Address} from \"@openzeppelin/contracts/utils/Address.sol\";\n\nuint256 constant SCALE = 1;\n\ncontract OpL2NativeTokenBridge is HypNative {\n    using TypeCasts for bytes32;\n    using StandardHookMetadata for bytes;\n    using Address for address payable;\n    using Address for address;\n\n    uint256 internal constant PROVE_WITHDRAWAL_GAS_LIMIT = 500_000;\n    uint256 internal constant FINALIZE_WITHDRAWAL_GAS_LIMIT = 300_000;\n    uint32 internal constant OP_MIN_GAS_LIMIT_ON_L1 = 50_000;\n\n    // L2 bridge used to initiate the withdrawal\n    IStandardBridge public immutable l2Bridge;\n\n    constructor(\n        address _mailbox,\n        address _l2Bridge\n    ) HypNative(SCALE, _mailbox) {\n        require(_l2Bridge.isContract(), \"L2 bridge must be a contract\");\n        l2Bridge = IStandardBridge(payable(_l2Bridge));\n    }\n\n    function initialize(\n        address _hook,\n        address _owner\n    ) public virtual initializer {\n        // ISM should not be set (contract does not receive messages currently)\n        _MailboxClient_initialize(_hook, address(0), _owner);\n    }\n\n    function quoteTransferRemote(\n        uint32 _destination,\n        bytes32 _recipient,\n        uint256 _amount\n    ) external view virtual override returns (Quote[] memory quotes) {\n        bytes memory message = TokenMessage.format(_recipient, _amount);\n        uint256 proveQuote = _Router_quoteDispatch(\n            _destination,\n            message,\n            _proveHookMetadata(),\n            address(hook)\n        );\n        uint256 finalizeQuote = _Router_quoteDispatch(\n            _destination,\n            message,\n            _finalizeHookMetadata(),\n            address(hook)\n        );\n        quotes = new Quote[](1);\n        quotes[0] = Quote({\n            token: address(0),\n            amount: proveQuote + finalizeQuote + _amount\n        });\n    }\n\n    function _proveHookMetadata() internal view virtual returns (bytes memory) {\n        return\n            StandardHookMetadata.format({\n                _msgValue: 0,\n                _gasLimit: PROVE_WITHDRAWAL_GAS_LIMIT,\n                _refundAddress: address(this)\n            });\n    }\n\n    function _finalizeHookMetadata()\n        internal\n        view\n        virtual\n        returns (bytes memory)\n    {\n        return\n            StandardHookMetadata.format({\n                _msgValue: 0,\n                _gasLimit: FINALIZE_WITHDRAWAL_GAS_LIMIT,\n                _refundAddress: address(this)\n            });\n    }\n\n    function _transferRemote(\n        uint32 _destination,\n        bytes32 _recipient,\n        uint256 _amount,\n        uint256 _value,\n        bytes memory _hookMetadata,\n        address _hook\n    ) internal virtual override returns (bytes32) {\n        require(\n            _amount > 0,\n            \"OP L2 token bridge: amount must be greater than 0\"\n        );\n\n        // refund first message fees to address(this) to cover second message\n        bytes32 proveMessageId = super._transferRemote(\n            _destination,\n            _recipient,\n            0,\n            _value,\n            _proveHookMetadata(),\n            _hook\n        );\n\n        bytes32 withdrawMessageId = super._transferRemote(\n            _destination,\n            _recipient,\n            _amount,\n            address(this).balance,\n            _finalizeHookMetadata(),\n            _hook\n        );\n\n        // include for legible error message\n        _transferFromSender(_amount);\n\n        // used for mapping withdrawal to hyperlane prove and finalize messages\n        bytes memory extraData = OPL2ToL1Withdrawal.encodeData(\n            proveMessageId,\n            withdrawMessageId\n        );\n        l2Bridge.bridgeETHTo{value: _amount}(\n            _recipient.bytes32ToAddress(),\n            OP_MIN_GAS_LIMIT_ON_L1,\n            extraData\n        );\n\n        if (address(this).balance > 0) {\n            address refundAddress = _hookMetadata.getRefundAddress(msg.sender);\n            require(\n                refundAddress != address(0),\n                \"OP L2 token bridge: refund address is 0\"\n            );\n            payable(refundAddress).sendValue(address(this).balance);\n        }\n\n        return withdrawMessageId;\n    }\n\n    function handle(uint32, bytes32, bytes calldata) external payable override {\n        revert(\"OP L2 token bridge should not receive messages\");\n    }\n}\n\nabstract contract OpL1NativeTokenBridge is HypNative, OPL2ToL1CcipReadIsm {\n    using Message for bytes;\n    using TokenMessage for bytes;\n\n    function initialize(\n        address _owner,\n        string[] memory _urls\n    ) public virtual initializer {\n        __Ownable_init();\n        setUrls(_urls);\n        // ISM should not be set (this contract uses itself as ISM)\n        // hook should not be set (this contract does not send messages)\n        _MailboxClient_initialize(address(0), address(0), _owner);\n    }\n\n    function _transferRemote(\n        uint32,\n        bytes32,\n        uint256,\n        uint256,\n        bytes memory,\n        address\n    ) internal override returns (bytes32) {\n        revert(\"OP L1 token bridge should not send messages\");\n    }\n\n    // see OpL2NativeTokenBridge._transferRemote prove message amount := 0\n    function _isProve(\n        bytes calldata _message\n    ) internal pure override returns (bool) {\n        return _message.body().amount() == 0;\n    }\n\n    function _transferTo(\n        address _recipient,\n        uint256 _amount,\n        bytes calldata metadata\n    ) internal override {\n        // do not transfer to recipient as the OP L1 bridge will do it\n    }\n\n    function interchainSecurityModule()\n        external\n        view\n        override\n        returns (IInterchainSecurityModule)\n    {\n        return IInterchainSecurityModule(address(this));\n    }\n}\n\ncontract OpL1V1NativeTokenBridge is\n    OpL1NativeTokenBridge,\n    OPL2ToL1V1CcipReadIsm\n{\n    constructor(\n        address _mailbox,\n        address _opPortal\n    ) HypNative(SCALE, _mailbox) OPL2ToL1CcipReadIsm(_opPortal) {}\n}\n\ncontract OpL1V2NativeTokenBridge is\n    OpL1NativeTokenBridge,\n    OPL2ToL1V2CcipReadIsm\n{\n    constructor(\n        address _mailbox,\n        address _opPortal\n    ) HypNative(SCALE, _mailbox) OPL2ToL1CcipReadIsm(_opPortal) {}\n}\n"},"contracts/token/extensions/WHypERC4626.sol":{"content":"// SPDX-License-Identifier: MIT OR Apache-2.0\npragma solidity >=0.8.0;\n\nimport {ERC20} from \"@openzeppelin/contracts/token/ERC20/ERC20.sol\";\nimport {HypERC4626} from \"./HypERC4626.sol\";\nimport {PackageVersioned} from \"../../PackageVersioned.sol\";\n\n/*@@@@@@@       @@@@@@@@@\n @@@@@@@@@       @@@@@@@@@\n  @@@@@@@@@       @@@@@@@@@\n   @@@@@@@@@       @@@@@@@@@\n    @@@@@@@@@@@@@@@@@@@@@@@@@\n     @@@@@  HYPERLANE  @@@@@@@\n    @@@@@@@@@@@@@@@@@@@@@@@@@\n   @@@@@@@@@       @@@@@@@@@\n  @@@@@@@@@       @@@@@@@@@\n @@@@@@@@@       @@@@@@@@@\n@@@@@@@@@       @@@@@@@@*/\n\n/**\n * @title WHypERC4626\n * @author Abacus Works\n * @notice A wrapper for HypERC4626 that allows for wrapping and unwrapping of underlying rebasing tokens\n */\ncontract WHypERC4626 is ERC20, PackageVersioned {\n    HypERC4626 public immutable underlying;\n\n    constructor(\n        HypERC4626 _underlying,\n        string memory name,\n        string memory symbol\n    ) ERC20(name, symbol) {\n        underlying = _underlying;\n    }\n\n    /*\n     * @notice Wraps an amount of underlying tokens into wrapped tokens\n     * @param _underlyingAmount The amount of underlying tokens to wrap\n     * @return The amount of wrapped tokens\n     */\n    function wrap(uint256 _underlyingAmount) external returns (uint256) {\n        require(\n            _underlyingAmount > 0,\n            \"WHypERC4626: wrap amount must be greater than 0\"\n        );\n        uint256 wrappedAmount = underlying.assetsToShares(_underlyingAmount);\n        _mint(msg.sender, wrappedAmount);\n        underlying.transferFrom(msg.sender, address(this), _underlyingAmount);\n        return wrappedAmount;\n    }\n\n    /*\n     * @notice Unwraps an amount of wrapped tokens into underlying tokens\n     * @param _wrappedAmount The amount of wrapped tokens to unwrap\n     * @return The amount of underlying tokens\n     */\n    function unwrap(uint256 _wrappedAmount) external returns (uint256) {\n        require(\n            _wrappedAmount > 0,\n            \"WHypERC4626: unwrap amount must be greater than 0\"\n        );\n        uint256 underlyingAmount = underlying.sharesToAssets(_wrappedAmount);\n        _burn(msg.sender, _wrappedAmount);\n        underlying.transfer(msg.sender, underlyingAmount);\n        return underlyingAmount;\n    }\n\n    /*\n     * @notice Gets the amount of wrapped tokens for a given amount of underlying tokens\n     * @param _underlyingAmount The amount of underlying tokens\n     * @return The amount of wrapped tokens\n     */\n    function getWrappedAmount(\n        uint256 _underlyingAmount\n    ) external view returns (uint256) {\n        return underlying.assetsToShares(_underlyingAmount);\n    }\n\n    /*\n     * @notice Gets the amount of underlying tokens for a given amount of wrapped tokens\n     * @param _wrappedAmount The amount of wrapped tokens\n     * @return The amount of underlying tokens\n     */\n    function getUnderlyingAmount(\n        uint256 _wrappedAmount\n    ) external view returns (uint256) {\n        return underlying.sharesToAssets(_wrappedAmount);\n    }\n\n    /*\n     * @notice Gets the amount of wrapped tokens for 1 unit of underlying tokens\n     * @return The amount of wrapped tokens\n     */\n    function wrappedPerUnderlying() external view returns (uint256) {\n        return underlying.assetsToShares(1 * 10 ** underlying.decimals());\n    }\n\n    /*\n     * @notice Gets the amount of underlying tokens for 1 unit of wrapped tokens\n     * @return The amount of underlying tokens\n     */\n    function underlyingPerWrapped() external view returns (uint256) {\n        return underlying.sharesToAssets(1 * 10 ** decimals());\n    }\n\n    /*\n     * @notice Gets the decimals of the wrapped token\n     * @return The decimals of the wrapped token\n     */\n    function decimals() public view override returns (uint8) {\n        return underlying.decimals();\n    }\n}\n"},"contracts/token/HypERC20.sol":{"content":"// SPDX-License-Identifier: Apache-2.0\npragma solidity >=0.8.0;\n\nimport {TokenRouter} from \"./libs/TokenRouter.sol\";\nimport {Quote} from \"../interfaces/ITokenBridge.sol\";\nimport {FungibleTokenRouter} from \"./libs/FungibleTokenRouter.sol\";\n\nimport {ERC20Upgradeable} from \"@openzeppelin/contracts-upgradeable/token/ERC20/ERC20Upgradeable.sol\";\n\n/**\n * @title Hyperlane ERC20 Token Router that extends ERC20 with remote transfer functionality.\n * @author Abacus Works\n * @dev Supply on each chain is not constant but the aggregate supply across all chains is.\n */\ncontract HypERC20 is ERC20Upgradeable, FungibleTokenRouter {\n    uint8 private immutable _decimals;\n\n    constructor(\n        uint8 __decimals,\n        uint256 _scale,\n        address _mailbox\n    ) FungibleTokenRouter(_scale, _mailbox) {\n        _decimals = __decimals;\n    }\n\n    /**\n     * @notice Initializes the Hyperlane router, ERC20 metadata, and mints initial supply to deployer.\n     * @param _totalSupply The initial supply of the token.\n     * @param _name The name of the token.\n     * @param _symbol The symbol of the token.\n     */\n    function initialize(\n        uint256 _totalSupply,\n        string memory _name,\n        string memory _symbol,\n        address _hook,\n        address _interchainSecurityModule,\n        address _owner\n    ) public virtual initializer {\n        // Initialize ERC20 metadata\n        __ERC20_init(_name, _symbol);\n        _mint(msg.sender, _totalSupply);\n        _MailboxClient_initialize(_hook, _interchainSecurityModule, _owner);\n    }\n\n    function decimals() public view virtual override returns (uint8) {\n        return _decimals;\n    }\n\n    function balanceOf(\n        address _account\n    )\n        public\n        view\n        virtual\n        override(TokenRouter, ERC20Upgradeable)\n        returns (uint256)\n    {\n        return ERC20Upgradeable.balanceOf(_account);\n    }\n\n    /**\n     * @dev Burns `_amount` of token from `msg.sender` balance.\n     * @inheritdoc TokenRouter\n     */\n    function _transferFromSender(\n        uint256 _amount\n    ) internal virtual override returns (bytes memory) {\n        _burn(msg.sender, _amount);\n        return bytes(\"\"); // no metadata\n    }\n\n    /**\n     * @dev Mints `_amount` of token to `_recipient` balance.\n     * @inheritdoc TokenRouter\n     */\n    function _transferTo(\n        address _recipient,\n        uint256 _amount,\n        bytes calldata // no metadata\n    ) internal virtual override {\n        _mint(_recipient, _amount);\n    }\n}\n"},"contracts/token/HypERC20Collateral.sol":{"content":"// SPDX-License-Identifier: MIT OR Apache-2.0\npragma solidity >=0.8.0;\n\n/*@@@@@@@       @@@@@@@@@\n @@@@@@@@@       @@@@@@@@@\n  @@@@@@@@@       @@@@@@@@@\n   @@@@@@@@@       @@@@@@@@@\n    @@@@@@@@@@@@@@@@@@@@@@@@@\n     @@@@@  HYPERLANE  @@@@@@@\n    @@@@@@@@@@@@@@@@@@@@@@@@@\n   @@@@@@@@@       @@@@@@@@@\n  @@@@@@@@@       @@@@@@@@@\n @@@@@@@@@       @@@@@@@@@\n@@@@@@@@@       @@@@@@@@*/\n\n// ============ Internal Imports ============\nimport {TokenMessage} from \"./libs/TokenMessage.sol\";\nimport {TokenRouter} from \"./libs/TokenRouter.sol\";\nimport {FungibleTokenRouter} from \"./libs/FungibleTokenRouter.sol\";\nimport {MovableCollateralRouter} from \"./libs/MovableCollateralRouter.sol\";\nimport {ValueTransferBridge} from \"./interfaces/ValueTransferBridge.sol\";\n\n// ============ External Imports ============\nimport {IERC20} from \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport {Address} from \"@openzeppelin/contracts/utils/Address.sol\";\nimport {SafeERC20} from \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\nimport {Context} from \"@openzeppelin/contracts/utils/Context.sol\";\nimport {ContextUpgradeable} from \"@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol\";\nimport {Quote} from \"../interfaces/ITokenBridge.sol\";\n\n/**\n * @title Hyperlane ERC20 Token Collateral that wraps an existing ERC20 with remote transfer functionality.\n * @author Abacus Works\n */\ncontract HypERC20Collateral is MovableCollateralRouter {\n    using SafeERC20 for IERC20;\n\n    IERC20 public immutable wrappedToken;\n\n    /**\n     * @notice Constructor\n     * @param erc20 Address of the token to keep as collateral\n     */\n    constructor(\n        address erc20,\n        uint256 _scale,\n        address _mailbox\n    ) FungibleTokenRouter(_scale, _mailbox) {\n        require(Address.isContract(erc20), \"HypERC20Collateral: invalid token\");\n        wrappedToken = IERC20(erc20);\n    }\n\n    function initialize(\n        address _hook,\n        address _interchainSecurityModule,\n        address _owner\n    ) public virtual initializer {\n        _MailboxClient_initialize(_hook, _interchainSecurityModule, _owner);\n    }\n\n    function balanceOf(\n        address _account\n    ) external view override returns (uint256) {\n        return wrappedToken.balanceOf(_account);\n    }\n\n    function quoteTransferRemote(\n        uint32 _destinationDomain,\n        bytes32 _recipient,\n        uint256 _amount\n    ) external view virtual override returns (Quote[] memory quotes) {\n        quotes = new Quote[](2);\n        quotes[0] = Quote({\n            token: address(0),\n            amount: _quoteGasPayment(_destinationDomain, _recipient, _amount)\n        });\n        quotes[1] = Quote({token: address(wrappedToken), amount: _amount});\n    }\n\n    /**\n     * @dev Transfers `_amount` of `wrappedToken` from `msg.sender` to this contract.\n     * @inheritdoc TokenRouter\n     */\n    function _transferFromSender(\n        uint256 _amount\n    ) internal virtual override returns (bytes memory) {\n        wrappedToken.safeTransferFrom(msg.sender, address(this), _amount);\n        return bytes(\"\"); // no metadata\n    }\n\n    /**\n     * @dev Transfers `_amount` of `wrappedToken` from this contract to `_recipient`.\n     * @inheritdoc TokenRouter\n     */\n    function _transferTo(\n        address _recipient,\n        uint256 _amount,\n        bytes calldata // no metadata\n    ) internal virtual override {\n        wrappedToken.safeTransfer(_recipient, _amount);\n    }\n\n    function _rebalance(\n        uint32 domain,\n        bytes32 recipient,\n        uint256 amount,\n        ValueTransferBridge bridge\n    ) internal override {\n        wrappedToken.safeApprove({spender: address(bridge), value: amount});\n        MovableCollateralRouter._rebalance({\n            domain: domain,\n            recipient: recipient,\n            amount: amount,\n            bridge: bridge\n        });\n    }\n}\n"},"contracts/token/HypERC721.sol":{"content":"// SPDX-License-Identifier: Apache-2.0\npragma solidity >=0.8.0;\n\nimport {TokenRouter} from \"./libs/TokenRouter.sol\";\n\nimport {IERC721Upgradeable} from \"@openzeppelin/contracts-upgradeable/token/ERC721/IERC721Upgradeable.sol\";\nimport {ERC721Upgradeable} from \"@openzeppelin/contracts-upgradeable/token/ERC721/ERC721Upgradeable.sol\";\nimport {ERC721EnumerableUpgradeable} from \"@openzeppelin/contracts-upgradeable/token/ERC721/extensions/ERC721EnumerableUpgradeable.sol\";\n\n/**\n * @title Hyperlane ERC721 Token Router that extends ERC721 with remote transfer functionality.\n * @author Abacus Works\n */\ncontract HypERC721 is ERC721EnumerableUpgradeable, TokenRouter {\n    constructor(address _mailbox) TokenRouter(_mailbox) {}\n\n    /**\n     * @notice Initializes the Hyperlane router, ERC721 metadata, and mints initial supply to deployer.\n     * @param _mintAmount The amount of NFTs to mint to `msg.sender`.\n     * @param _name The name of the token.\n     * @param _symbol The symbol of the token.\n     * @param _hook The post-dispatch hook contract.\n       @param _interchainSecurityModule The interchain security module contract.\n       @param _owner The this contract.\n     */\n    function initialize(\n        uint256 _mintAmount,\n        string memory _name,\n        string memory _symbol,\n        address _hook,\n        address _interchainSecurityModule,\n        address _owner\n    ) external initializer {\n        _MailboxClient_initialize(_hook, _interchainSecurityModule, _owner);\n        __ERC721_init(_name, _symbol);\n        for (uint256 i = 0; i < _mintAmount; i++) {\n            _safeMint(msg.sender, i);\n        }\n    }\n\n    function balanceOf(\n        address _account\n    )\n        public\n        view\n        virtual\n        override(TokenRouter, ERC721Upgradeable, IERC721Upgradeable)\n        returns (uint256)\n    {\n        return ERC721Upgradeable.balanceOf(_account);\n    }\n\n    /**\n     * @dev Asserts `msg.sender` is owner and burns `_tokenId`.\n     * @inheritdoc TokenRouter\n     */\n    function _transferFromSender(\n        uint256 _tokenId\n    ) internal virtual override returns (bytes memory) {\n        require(ownerOf(_tokenId) == msg.sender, \"!owner\");\n        _burn(_tokenId);\n        return bytes(\"\"); // no metadata\n    }\n\n    /**\n     * @dev Mints `_tokenId` to `_recipient`.\n     * @inheritdoc TokenRouter\n     */\n    function _transferTo(\n        address _recipient,\n        uint256 _tokenId,\n        bytes calldata // no metadata\n    ) internal virtual override {\n        _safeMint(_recipient, _tokenId);\n    }\n}\n"},"contracts/token/HypERC721Collateral.sol":{"content":"// SPDX-License-Identifier: MIT OR Apache-2.0\npragma solidity >=0.8.0;\n\n// ============ Internal Imports ============\nimport {IERC721} from \"@openzeppelin/contracts/token/ERC721/IERC721.sol\";\nimport {TokenRouter} from \"./libs/TokenRouter.sol\";\n\n/**\n * @title Hyperlane ERC721 Token Collateral that wraps an existing ERC721 with remote transfer functionality.\n * @author Abacus Works\n */\ncontract HypERC721Collateral is TokenRouter {\n    IERC721 public immutable wrappedToken;\n\n    /**\n     * @notice Constructor\n     * @param erc721 Address of the token to keep as collateral\n     */\n    constructor(address erc721, address _mailbox) TokenRouter(_mailbox) {\n        wrappedToken = IERC721(erc721);\n    }\n\n    /**\n     * @notice Initializes the Hyperlane router\n     * @param _hook The post-dispatch hook contract.\n       @param _interchainSecurityModule The interchain security module contract.\n       @param _owner The this contract.\n     */\n    function initialize(\n        address _hook,\n        address _interchainSecurityModule,\n        address _owner\n    ) public virtual initializer {\n        _MailboxClient_initialize(_hook, _interchainSecurityModule, _owner);\n    }\n\n    function ownerOf(uint256 _tokenId) external view returns (address) {\n        return IERC721(wrappedToken).ownerOf(_tokenId);\n    }\n\n    /**\n     * @dev Returns the balance of `_account` for `wrappedToken`.\n     * @inheritdoc TokenRouter\n     */\n    function balanceOf(\n        address _account\n    ) external view override returns (uint256) {\n        return IERC721(wrappedToken).balanceOf(_account);\n    }\n\n    /**\n     * @dev Transfers `_tokenId` of `wrappedToken` from `msg.sender` to this contract.\n     * @inheritdoc TokenRouter\n     */\n    function _transferFromSender(\n        uint256 _tokenId\n    ) internal virtual override returns (bytes memory) {\n        // safeTransferFrom not used here because recipient is this contract\n        wrappedToken.transferFrom(msg.sender, address(this), _tokenId);\n        return bytes(\"\"); // no metadata\n    }\n\n    /**\n     * @dev Transfers `_tokenId` of `wrappedToken` from this contract to `_recipient`.\n     * @inheritdoc TokenRouter\n     */\n    function _transferTo(\n        address _recipient,\n        uint256 _tokenId,\n        bytes calldata // no metadata\n    ) internal override {\n        wrappedToken.safeTransferFrom(address(this), _recipient, _tokenId);\n    }\n}\n"},"contracts/token/HypNative.sol":{"content":"// SPDX-License-Identifier: Apache-2.0\npragma solidity >=0.8.0;\n\nimport {TokenRouter} from \"./libs/TokenRouter.sol\";\nimport {FungibleTokenRouter} from \"./libs/FungibleTokenRouter.sol\";\nimport {MovableCollateralRouter} from \"./libs/MovableCollateralRouter.sol\";\nimport {ValueTransferBridge} from \"./interfaces/ValueTransferBridge.sol\";\nimport {Quote} from \"../interfaces/ITokenBridge.sol\";\n\nimport {Address} from \"@openzeppelin/contracts/utils/Address.sol\";\n\n/**\n * @title Hyperlane Native Token Router that extends ERC20 with remote transfer functionality.\n * @author Abacus Works\n * @dev Supply on each chain is not constant but the aggregate supply across all chains is.\n */\ncontract HypNative is MovableCollateralRouter {\n    string internal constant INSUFFICIENT_NATIVE_AMOUNT =\n        \"Native: amount exceeds msg.value\";\n\n    /**\n     * @dev Emitted when native tokens are donated to the contract.\n     * @param sender The address of the sender.\n     * @param amount The amount of native tokens donated.\n     */\n    event Donation(address indexed sender, uint256 amount);\n\n    constructor(\n        uint256 _scale,\n        address _mailbox\n    ) FungibleTokenRouter(_scale, _mailbox) {}\n\n    /**\n     * @notice Initializes the Hyperlane router\n     * @param _hook The post-dispatch hook contract.\n     * @param _interchainSecurityModule The interchain security module contract.\n     * @param _owner The this contract.\n     */\n    function initialize(\n        address _hook,\n        address _interchainSecurityModule,\n        address _owner\n    ) public virtual initializer {\n        _MailboxClient_initialize(_hook, _interchainSecurityModule, _owner);\n    }\n\n    function quoteTransferRemote(\n        uint32 _destination,\n        bytes32 _recipient,\n        uint256 _amount\n    ) external view virtual override returns (Quote[] memory quotes) {\n        quotes = new Quote[](1);\n        quotes[0] = Quote({\n            token: address(0),\n            amount: _quoteGasPayment(_destination, _recipient, _amount) +\n                _amount\n        });\n    }\n\n    function _transferRemote(\n        uint32 _destination,\n        bytes32 _recipient,\n        uint256 _amount,\n        uint256 _value,\n        bytes memory _hookMetadata,\n        address _hook\n    ) internal virtual override returns (bytes32 messageId) {\n        // include for legible error instead of underflow\n        _transferFromSender(_amount);\n\n        return\n            super._transferRemote(\n                _destination,\n                _recipient,\n                _amount,\n                msg.value - _amount,\n                _hookMetadata,\n                _hook\n            );\n    }\n\n    function balanceOf(\n        address _account\n    ) external view override returns (uint256) {\n        return _account.balance;\n    }\n\n    /**\n     * @inheritdoc TokenRouter\n     */\n    function _transferFromSender(\n        uint256 _amount\n    ) internal virtual override returns (bytes memory) {\n        require(msg.value >= _amount, \"Native: amount exceeds msg.value\");\n        return bytes(\"\"); // no metadata\n    }\n\n    /**\n     * @dev Sends `_amount` of native token to `_recipient` balance.\n     * @inheritdoc TokenRouter\n     */\n    function _transferTo(\n        address _recipient,\n        uint256 _amount,\n        bytes calldata // no metadata\n    ) internal virtual override {\n        Address.sendValue(payable(_recipient), _amount);\n    }\n\n    receive() external payable {\n        emit Donation(msg.sender, msg.value);\n    }\n\n    /**\n     * @dev This function uses `msg.value` as payment for the bridge.\n     * User collateral is never used to make bridge payments!\n     * The rebalancer is to pay all fees for the bridge.\n     */\n    function _rebalance(\n        uint32 domain,\n        bytes32 recipient,\n        uint256 amount,\n        ValueTransferBridge bridge\n    ) internal override {\n        uint fee = msg.value + amount;\n        require(\n            address(this).balance >= fee,\n            \"Native: rebalance amount exceeds balance\"\n        );\n        bridge.transferRemote{value: fee}({\n            destinationDomain: domain,\n            recipient: recipient,\n            amountOut: amount\n        });\n    }\n}\n"},"contracts/token/interfaces/IFiatToken.sol":{"content":"// SPDX-License-Identifier: UNLICENSED\npragma solidity >=0.8.0;\n\n// adapted from https://github.com/circlefin/stablecoin-evm\nimport {IERC20} from \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\n\ninterface IFiatToken is IERC20 {\n    /**\n     * @notice Allows a minter to burn some of its own tokens.\n     * @dev The caller must be a minter, must not be blacklisted, and the amount to burn\n     * should be less than or equal to the account's balance.\n     * @param _amount the amount of tokens to be burned.\n     */\n    function burn(uint256 _amount) external;\n\n    /**\n     * @notice Mints fiat tokens to an address.\n     * @param _to The address that will receive the minted tokens.\n     * @param _amount The amount of tokens to mint. Must be less than or equal\n     * to the minterAllowance of the caller.\n     * @return True if the operation was successful.\n     */\n    function mint(address _to, uint256 _amount) external returns (bool);\n\n    /**\n     * @notice Gets the minter allowance for an account.\n     * @param _minter The address to check.\n     * @return The remaining minter allowance for the account.\n     */\n    function minterAllowance(address _minter) external view returns (uint256);\n}\n"},"contracts/token/interfaces/IXERC20.sol":{"content":"// SPDX-License-Identifier: UNLICENSED\npragma solidity >=0.8.0;\n\n// adapted from https://github.com/defi-wonderland/xERC20\n\nimport {IERC20} from \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\n\ninterface IXERC20 is IERC20 {\n    /**\n     * @notice Mints tokens for a user\n     * @dev Can only be called by a minter\n     * @param _user The address of the user who needs tokens minted\n     * @param _amount The amount of tokens being minted\n     */\n    function mint(address _user, uint256 _amount) external;\n\n    /**\n     * @notice Burns tokens for a user\n     * @dev Can only be called by a minter\n     * @param _user The address of the user who needs tokens burned\n     * @param _amount The amount of tokens being burned\n     */\n    function burn(address _user, uint256 _amount) external;\n\n    /**\n     * @notice Updates the limits of any bridge\n     * @dev Can only be called by the owner\n     * @param _mintingLimit The updated minting limit we are setting to the bridge\n     * @param _burningLimit The updated burning limit we are setting to the bridge\n     * @param _bridge The address of the bridge we are setting the limits too\n     */\n    function setLimits(\n        address _bridge,\n        uint256 _mintingLimit,\n        uint256 _burningLimit\n    ) external;\n\n    function owner() external returns (address);\n\n    /**\n     * @notice Returns the current limit of a bridge\n     * @param _bridge the bridge we are viewing the limits of\n     * @return _limit The limit the bridge has\n     */\n    function burningCurrentLimitOf(\n        address _bridge\n    ) external view returns (uint256 _limit);\n\n    /**\n     * @notice Returns the current limit of a bridge\n     * @param _bridge the bridge we are viewing the limits of\n     * @return _limit The limit the bridge has\n     */\n    function mintingCurrentLimitOf(\n        address _bridge\n    ) external view returns (uint256 _limit);\n\n    /**\n     * @notice Returns the max limit of a minter\n     *\n     * @param _minter The minter we are viewing the limits of\n     *  @return _limit The limit the minter has\n     */\n    function mintingMaxLimitOf(\n        address _minter\n    ) external view returns (uint256 _limit);\n\n    /**\n     * @notice Returns the max limit of a bridge\n     *\n     * @param _bridge the bridge we are viewing the limits of\n     * @return _limit The limit the bridge has\n     */\n\n    function burningMaxLimitOf(\n        address _bridge\n    ) external view returns (uint256 _limit);\n}\n"},"contracts/token/interfaces/IXERC20Lockbox.sol":{"content":"// SPDX-License-Identifier: UNLICENSED\npragma solidity >=0.8.4 <0.9.0;\n\n// adapted from https://github.com/defi-wonderland/xERC20\n\nimport {IXERC20} from \"./IXERC20.sol\";\nimport {IERC20} from \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\n\ninterface IXERC20Lockbox {\n    /**\n     * @notice The XERC20 token of this contract\n     */\n    function XERC20() external returns (IXERC20);\n\n    /**\n     * @notice The ERC20 token of this contract\n     */\n    function ERC20() external returns (IERC20);\n\n    /**\n     * @notice Deposit ERC20 tokens into the lockbox\n     *\n     * @param _amount The amount of tokens to deposit\n     */\n\n    function deposit(uint256 _amount) external;\n\n    /**\n     * @notice Deposit ERC20 tokens into the lockbox, and send the XERC20 to a user\n     *\n     * @param _user The user to send the XERC20 to\n     * @param _amount The amount of tokens to deposit\n     */\n\n    function depositTo(address _user, uint256 _amount) external;\n\n    /**\n     * @notice Deposit the native asset into the lockbox, and send the XERC20 to a user\n     *\n     * @param _user The user to send the XERC20 to\n     */\n\n    function depositNativeTo(address _user) external payable;\n\n    /**\n     * @notice Withdraw ERC20 tokens from the lockbox\n     *\n     * @param _amount The amount of tokens to withdraw\n     */\n\n    function withdraw(uint256 _amount) external;\n\n    /**\n     * @notice Withdraw ERC20 tokens from the lockbox\n     *\n     * @param _user The user to withdraw to\n     * @param _amount The amount of tokens to withdraw\n     */\n\n    function withdrawTo(address _user, uint256 _amount) external;\n}\n"},"contracts/token/interfaces/IXERC20VS.sol":{"content":"// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport {RateLimitMidPoint} from \"../../libs/RateLimitMidpointCommonLibrary.sol\";\nimport {IERC20} from \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\n\ninterface IXERC20VS is IERC20 {\n    /// @notice Emits when a limit is set\n    /// @param _bridge The address of the bridge we are setting the limit to\n    /// @param _bufferCap The updated buffer cap for the bridge\n    event BridgeLimitsSet(address indexed _bridge, uint256 _bufferCap);\n\n    struct RateLimitMidPointInfo {\n        /// @notice the buffer cap for this bridge\n        uint112 bufferCap;\n        /// @notice the rate limit per second for this bridge\n        uint128 rateLimitPerSecond;\n        /// @notice the bridge address\n        address bridge;\n    }\n\n    /// @notice The address of the lockbox contract\n    function lockbox() external view returns (address);\n\n    /// @notice Maps bridge address to bridge rate limits\n    /// @param _bridge The bridge we are viewing the limits of\n    /// @return _rateLimit The limits of the bridge\n    function rateLimits(\n        address _bridge\n    ) external view returns (RateLimitMidPoint memory _rateLimit);\n\n    /// @notice Returns the max limit of a bridge\n    /// @param _bridge The bridge we are viewing the limits of\n    /// @return _limit The limit the bridge has\n    function mintingMaxLimitOf(\n        address _bridge\n    ) external view returns (uint256 _limit);\n\n    /// @notice Returns the max limit of a bridge\n    /// @param _bridge the bridge we are viewing the limits of\n    /// @return _limit The limit the bridge has\n    function burningMaxLimitOf(\n        address _bridge\n    ) external view returns (uint256 _limit);\n\n    /// @notice Returns the current limit of a bridge\n    /// @param _bridge The bridge we are viewing the limits of\n    /// @return _limit The limit the bridge has\n    function mintingCurrentLimitOf(\n        address _bridge\n    ) external view returns (uint256 _limit);\n\n    /// @notice Returns the current limit of a bridge\n    /// @param _bridge the bridge we are viewing the limits of\n    /// @return _limit The limit the bridge has\n    function burningCurrentLimitOf(\n        address _bridge\n    ) external view returns (uint256 _limit);\n\n    /// @notice Mints tokens for a user\n    /// @dev Can only be called by a bridge\n    /// @param _user The address of the user who needs tokens minted\n    /// @param _amount The amount of tokens being minted\n    function mint(address _user, uint256 _amount) external;\n\n    /// @notice Burns tokens for a user\n    /// @dev Can only be called by a bridge\n    /// @param _user The address of the user who needs tokens burned\n    /// @param _amount The amount of tokens being burned\n    function burn(address _user, uint256 _amount) external;\n\n    /// @notice Conform to the xERC20 setLimits interface\n    /// @dev Can only be called if the bridge already has a buffer cap\n    /// @param _bridge The bridge we are setting the limits of\n    /// @param _newBufferCap The new buffer cap, uint112 max for unlimited\n    function setBufferCap(address _bridge, uint256 _newBufferCap) external;\n\n    /// @notice Sets rate limit per second for a bridge\n    /// @dev Can only be called if the bridge already has a buffer cap\n    /// @param _bridge The bridge we are setting the limits of\n    /// @param _newRateLimitPerSecond The new rate limit per second\n    function setRateLimitPerSecond(\n        address _bridge,\n        uint128 _newRateLimitPerSecond\n    ) external;\n\n    /// @notice Adds a new bridge to the currently active bridges\n    /// @param _newBridge The bridge to add\n    function addBridge(RateLimitMidPointInfo memory _newBridge) external;\n\n    /// @notice Removes a bridge from the currently active bridges\n    /// deleting its buffer stored, buffer cap, mid point and last\n    /// buffer used time\n    /// @param _bridge The bridge to remove\n    function removeBridge(address _bridge) external;\n}\n"},"contracts/token/interfaces/ValueTransferBridge.sol":{"content":"// SPDX-License-Identifier: MIT OR Apache-2.0\npragma solidity >=0.8.0;\n\nstruct Quote {\n    address token;\n    uint256 amount;\n}\n\ninterface ValueTransferBridge {\n    function quoteTransferRemote(\n        uint32 destinationDomain,\n        bytes32 recipient,\n        uint amountOut\n    ) external view returns (Quote[] memory);\n\n    function transferRemote(\n        uint32 destinationDomain,\n        bytes32 recipient,\n        uint256 amountOut\n    ) external payable returns (bytes32 transferId);\n}\n"},"contracts/token/libs/AmountPartition.sol":{"content":"// SPDX-License-Identifier: MIT OR Apache-2.0\npragma solidity >=0.8.0;\n\n// ============ External Imports ============\nimport {Address} from \"@openzeppelin/contracts/utils/Address.sol\";\n\n// ============ Internal Imports ============\nimport {Message} from \"../../libs/Message.sol\";\nimport {PackageVersioned} from \"../../PackageVersioned.sol\";\nimport {TokenMessage} from \"../../token/libs/TokenMessage.sol\";\n\n/**\n * @title AmountPartition\n */\nabstract contract AmountPartition is PackageVersioned {\n    using Message for bytes;\n    using TokenMessage for bytes;\n    using Address for address;\n\n    address public immutable lower;\n    address public immutable upper;\n    uint256 public immutable threshold;\n\n    constructor(address _lower, address _upper, uint256 _threshold) {\n        require(\n            _lower.isContract() && _upper.isContract(),\n            \"AmountPartition: lower and upper must be contracts\"\n        );\n        lower = _lower;\n        upper = _upper;\n        threshold = _threshold;\n    }\n\n    function _partition(\n        bytes calldata _message\n    ) internal view returns (address) {\n        uint256 amount = _message.body().amount();\n        if (amount >= threshold) {\n            return upper;\n        } else {\n            return lower;\n        }\n    }\n}\n"},"contracts/token/libs/FungibleTokenRouter.sol":{"content":"// SPDX-License-Identifier: Apache-2.0\npragma solidity >=0.8.0;\n\nimport {TokenRouter} from \"./TokenRouter.sol\";\n\n/**\n * @title Hyperlane Fungible Token Router that extends TokenRouter with scaling logic for fungible tokens with different decimals.\n * @author Abacus Works\n */\nabstract contract FungibleTokenRouter is TokenRouter {\n    uint256 public immutable scale;\n\n    constructor(uint256 _scale, address _mailbox) TokenRouter(_mailbox) {\n        scale = _scale;\n    }\n\n    /**\n     * @dev Scales local amount to message amount (up by scale factor).\n     * @inheritdoc TokenRouter\n     */\n    function _outboundAmount(\n        uint256 _localAmount\n    ) internal view virtual override returns (uint256 _messageAmount) {\n        _messageAmount = _localAmount * scale;\n    }\n\n    /**\n     * @dev Scales message amount to local amount (down by scale factor).\n     * @inheritdoc TokenRouter\n     */\n    function _inboundAmount(\n        uint256 _messageAmount\n    ) internal view virtual override returns (uint256 _localAmount) {\n        _localAmount = _messageAmount / scale;\n    }\n}\n"},"contracts/token/libs/MovableCollateralRouter.sol":{"content":"// SPDX-License-Identifier: Apache-2.0\npragma solidity >=0.8.0;\n\nimport {Router} from \"../../client/Router.sol\";\nimport {FungibleTokenRouter} from \"./FungibleTokenRouter.sol\";\nimport {ValueTransferBridge} from \"../interfaces/ValueTransferBridge.sol\";\nimport {EnumerableSet} from \"@openzeppelin/contracts/utils/structs/EnumerableSet.sol\";\n\nimport {IERC20} from \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport {SafeERC20} from \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\n\nabstract contract MovableCollateralRouter is FungibleTokenRouter {\n    using SafeERC20 for IERC20;\n    using EnumerableSet for EnumerableSet.AddressSet;\n\n    /// @notice Mapping of domain to allowed rebalance recipient.\n    /// @dev Keys constrained to a subset of Router.domains()\n    mapping(uint32 routerDomain => bytes32 recipient) public allowedRecipient;\n\n    /// @notice Mapping of domain to allowed rebalance bridges.\n    /// @dev Keys constrained to a subset of Router.domains()\n    mapping(uint32 routerDomain => EnumerableSet.AddressSet bridges)\n        internal _allowedBridges;\n\n    /// @notice Set of addresses that are allowed to rebalance.\n    EnumerableSet.AddressSet internal _allowedRebalancers;\n\n    event CollateralMoved(\n        uint32 indexed domain,\n        bytes32 recipient,\n        uint256 amount,\n        address indexed rebalancer\n    );\n\n    modifier onlyRebalancer() {\n        require(\n            _allowedRebalancers.contains(_msgSender()),\n            \"MCR: Only Rebalancer\"\n        );\n        _;\n    }\n\n    modifier onlyAllowedBridge(uint32 domain, ValueTransferBridge bridge) {\n        EnumerableSet.AddressSet storage bridges = _allowedBridges[domain];\n        require(bridges.contains(address(bridge)), \"MCR: Not allowed bridge\");\n        _;\n    }\n\n    function allowedRebalancers() external view returns (address[] memory) {\n        return _allowedRebalancers.values();\n    }\n\n    function allowedBridges(\n        uint32 domain\n    ) external view returns (address[] memory) {\n        return _allowedBridges[domain].values();\n    }\n\n    function setRecipient(uint32 domain, bytes32 recipient) external onlyOwner {\n        // constrain to a subset of Router.domains()\n        _mustHaveRemoteRouter(domain);\n        allowedRecipient[domain] = recipient;\n    }\n\n    function removeRecipient(uint32 domain) external onlyOwner {\n        delete allowedRecipient[domain];\n    }\n\n    function addBridge(\n        uint32 domain,\n        ValueTransferBridge bridge\n    ) external onlyOwner {\n        // constrain to a subset of Router.domains()\n        _mustHaveRemoteRouter(domain);\n        _allowedBridges[domain].add(address(bridge));\n    }\n\n    function removeBridge(\n        uint32 domain,\n        ValueTransferBridge bridge\n    ) external onlyOwner {\n        _allowedBridges[domain].remove(address(bridge));\n    }\n\n    /**\n     * @notice Approves the token for the bridge.\n     * @param token The token to approve.\n     * @param bridge The bridge to approve the token for.\n     * @dev We need this to support bridges that charge fees in ERC20 tokens.\n     */\n    function approveTokenForBridge(\n        IERC20 token,\n        ValueTransferBridge bridge\n    ) external onlyOwner {\n        token.safeApprove(address(bridge), type(uint256).max);\n    }\n\n    function addRebalancer(address rebalancer) external onlyOwner {\n        _allowedRebalancers.add(rebalancer);\n    }\n\n    function removeRebalancer(address rebalancer) external onlyOwner {\n        _allowedRebalancers.remove(rebalancer);\n    }\n\n    /**\n     * @notice Rebalances the collateral between router domains.\n     * @param domain The domain to rebalance to.\n     * @param amount The amount of collateral to rebalance.\n     * @param bridge The bridge to use for the rebalance.\n     * @dev The caller must be an allowed rebalancer and the bridge must be an allowed bridge for the domain.\n     * @dev The recipient is the enrolled router if no recipient is set for the domain.\n     */\n    function rebalance(\n        uint32 domain,\n        uint256 amount,\n        ValueTransferBridge bridge\n    ) external payable onlyRebalancer onlyAllowedBridge(domain, bridge) {\n        address rebalancer = _msgSender();\n\n        bytes32 recipient = allowedRecipient[domain];\n        if (recipient == bytes32(0)) {\n            recipient = _mustHaveRemoteRouter(domain);\n        }\n\n        _rebalance(domain, recipient, amount, bridge);\n        emit CollateralMoved({\n            domain: domain,\n            recipient: recipient,\n            amount: amount,\n            rebalancer: rebalancer\n        });\n    }\n\n    /// @dev This function in `EnumerableSet` was introduced in OpenZeppelin v5. We are using 4.9\n    /// See https://github.com/OpenZeppelin/openzeppelin-contracts/blob/v5.3.0-rc.0/contracts/utils/structs/EnumerableSet.sol#L126\n    function _clear(EnumerableSet.Set storage set) private {\n        uint256 len = set._values.length;\n        for (uint256 i = 0; i < len; ++i) {\n            delete set._indexes[set._values[i]];\n        }\n        _unsafeSetLength(set._values, 0);\n    }\n    /// @dev A helper for `_clear`. See https://github.com/OpenZeppelin/openzeppelin-contracts/blob/39f5a0284e7eb539354e44b76fcbb69033b22b56/contracts/utils/Arrays.sol#L466\n    function _unsafeSetLength(bytes32[] storage array, uint256 len) internal {\n        assembly (\"memory-safe\") {\n            sstore(array.slot, len)\n        }\n    }\n\n    /// @dev Constrains keys of rebalance mappings to Router.domains()\n    function _unenrollRemoteRouter(uint32 domain) internal override {\n        delete allowedRecipient[domain];\n        _clear(_allowedBridges[domain]._inner);\n        Router._unenrollRemoteRouter(domain);\n    }\n\n    function _rebalance(\n        uint32 domain,\n        bytes32 recipient,\n        uint256 amount,\n        ValueTransferBridge bridge\n    ) internal virtual {\n        bridge.transferRemote{value: msg.value}({\n            destinationDomain: domain,\n            recipient: recipient,\n            amountOut: amount\n        });\n    }\n}\n"},"contracts/token/libs/TokenMessage.sol":{"content":"// SPDX-License-Identifier: MIT OR Apache-2.0\npragma solidity >=0.8.0;\n\nlibrary TokenMessage {\n    uint8 internal constant RECIPIENT_OFFSET = 0;\n    uint8 internal constant AMOUNT_OFFSET = 32;\n    uint8 internal constant METADATA_OFFSET = 64;\n\n    function format(\n        bytes32 _recipient,\n        uint256 _amount,\n        bytes memory _metadata\n    ) internal pure returns (bytes memory) {\n        return abi.encodePacked(_recipient, _amount, _metadata);\n    }\n\n    function format(\n        bytes32 _recipient,\n        uint256 _amount\n    ) internal pure returns (bytes memory) {\n        return abi.encodePacked(_recipient, _amount);\n    }\n\n    function recipient(bytes calldata message) internal pure returns (bytes32) {\n        return bytes32(message[RECIPIENT_OFFSET:RECIPIENT_OFFSET + 32]);\n    }\n\n    function amount(bytes calldata message) internal pure returns (uint256) {\n        return uint256(bytes32(message[AMOUNT_OFFSET:AMOUNT_OFFSET + 32]));\n    }\n\n    // alias for ERC721\n    function tokenId(bytes calldata message) internal pure returns (uint256) {\n        return amount(message);\n    }\n\n    function metadata(\n        bytes calldata message\n    ) internal pure returns (bytes calldata) {\n        return message[METADATA_OFFSET:];\n    }\n}\n"},"contracts/token/libs/TokenRouter.sol":{"content":"// SPDX-License-Identifier: MIT OR Apache-2.0\npragma solidity >=0.8.0;\n\n// ============ Internal Imports ============\nimport {TypeCasts} from \"../../libs/TypeCasts.sol\";\nimport {GasRouter} from \"../../client/GasRouter.sol\";\nimport {TokenMessage} from \"./TokenMessage.sol\";\nimport {Quote, ITokenBridge} from \"../../interfaces/ITokenBridge.sol\";\n\n/**\n * @title Hyperlane Token Router that extends Router with abstract token (ERC20/ERC721) remote transfer functionality.\n * @author Abacus Works\n */\nabstract contract TokenRouter is GasRouter, ITokenBridge {\n    using TypeCasts for bytes32;\n    using TypeCasts for address;\n    using TokenMessage for bytes;\n\n    /**\n     * @dev Emitted on `transferRemote` when a transfer message is dispatched.\n     * @param destination The identifier of the destination chain.\n     * @param recipient The address of the recipient on the destination chain.\n     * @param amount The amount of tokens sent in to the remote recipient.\n     */\n    event SentTransferRemote(\n        uint32 indexed destination,\n        bytes32 indexed recipient,\n        uint256 amount\n    );\n\n    /**\n     * @dev Emitted on `_handle` when a transfer message is processed.\n     * @param origin The identifier of the origin chain.\n     * @param recipient The address of the recipient on the destination chain.\n     * @param amount The amount of tokens received from the remote sender.\n     */\n    event ReceivedTransferRemote(\n        uint32 indexed origin,\n        bytes32 indexed recipient,\n        uint256 amount\n    );\n\n    constructor(address _mailbox) GasRouter(_mailbox) {}\n\n    /**\n     * @notice Transfers `_amountOrId` token to `_recipient` on `_destination` domain.\n     * @dev Delegates transfer logic to `_transferFromSender` implementation.\n     * @dev Emits `SentTransferRemote` event on the origin chain.\n     * @param _destination The identifier of the destination chain.\n     * @param _recipient The address of the recipient on the destination chain.\n     * @param _amountOrId The amount or identifier of tokens to be sent to the remote recipient.\n     * @return messageId The identifier of the dispatched message.\n     */\n    function transferRemote(\n        uint32 _destination,\n        bytes32 _recipient,\n        uint256 _amountOrId\n    ) external payable virtual returns (bytes32 messageId) {\n        return\n            _transferRemote(_destination, _recipient, _amountOrId, msg.value);\n    }\n\n    /**\n     * @notice Transfers `_amountOrId` token to `_recipient` on `_destination` domain with a specified hook\n     * @dev Delegates transfer logic to `_transferFromSender` implementation.\n     * @dev The metadata is the token metadata, and is DIFFERENT than the hook metadata.\n     * @dev Emits `SentTransferRemote` event on the origin chain.\n     * @param _destination The identifier of the destination chain.\n     * @param _recipient The address of the recipient on the destination chain.\n     * @param _amountOrId The amount or identifier of tokens to be sent to the remote recipient.\n     * @param _hookMetadata The metadata passed into the hook\n     * @param _hook The post dispatch hook to be called by the Mailbox\n     * @return messageId The identifier of the dispatched message.\n     */\n    function transferRemote(\n        uint32 _destination,\n        bytes32 _recipient,\n        uint256 _amountOrId,\n        bytes calldata _hookMetadata,\n        address _hook\n    ) external payable virtual returns (bytes32 messageId) {\n        return\n            _transferRemote(\n                _destination,\n                _recipient,\n                _amountOrId,\n                msg.value,\n                _hookMetadata,\n                _hook\n            );\n    }\n\n    function _transferRemote(\n        uint32 _destination,\n        bytes32 _recipient,\n        uint256 _amountOrId,\n        uint256 _value\n    ) internal returns (bytes32 messageId) {\n        return\n            _transferRemote(\n                _destination,\n                _recipient,\n                _amountOrId,\n                _value,\n                _GasRouter_hookMetadata(_destination),\n                address(hook)\n            );\n    }\n\n    function _transferRemote(\n        uint32 _destination,\n        bytes32 _recipient,\n        uint256 _amountOrId,\n        uint256 _value,\n        bytes memory _hookMetadata,\n        address _hook\n    ) internal virtual returns (bytes32 messageId) {\n        bytes memory _tokenMetadata = _transferFromSender(_amountOrId);\n\n        uint256 outboundAmount = _outboundAmount(_amountOrId);\n        bytes memory _tokenMessage = TokenMessage.format(\n            _recipient,\n            outboundAmount,\n            _tokenMetadata\n        );\n\n        messageId = _Router_dispatch(\n            _destination,\n            _value,\n            _tokenMessage,\n            _hookMetadata,\n            _hook\n        );\n\n        emit SentTransferRemote(_destination, _recipient, outboundAmount);\n    }\n\n    /**\n     * @dev Should return the amount of tokens to be encoded in the message amount (eg for scaling `_localAmount`).\n     * @param _localAmount The amount of tokens transferred on this chain in local denomination.\n     * @return _messageAmount The amount of tokens to be encoded in the message body.\n     */\n    function _outboundAmount(\n        uint256 _localAmount\n    ) internal view virtual returns (uint256 _messageAmount) {\n        _messageAmount = _localAmount;\n    }\n\n    /**\n     * @dev Should return the amount of tokens to be decoded from the message amount.\n     * @param _messageAmount The amount of tokens received in the message body.\n     * @return _localAmount The amount of tokens to be transferred on this chain in local denomination.\n     */\n    function _inboundAmount(\n        uint256 _messageAmount\n    ) internal view virtual returns (uint256 _localAmount) {\n        _localAmount = _messageAmount;\n    }\n\n    /**\n     * @dev Should transfer `_amountOrId` of tokens from `msg.sender` to this token router.\n     * @dev Called by `transferRemote` before message dispatch.\n     * @dev Optionally returns `metadata` associated with the transfer to be passed in message.\n     */\n    function _transferFromSender(\n        uint256 _amountOrId\n    ) internal virtual returns (bytes memory metadata);\n\n    /**\n     * @notice Returns the balance of `account` on this token router.\n     * @param account The address to query the balance of.\n     * @return The balance of `account`.\n     */\n    function balanceOf(address account) external virtual returns (uint256);\n\n    /**\n     * @notice Returns the gas payment required to dispatch a message to the given domain's router.\n     * @param _destination The domain of the router.\n     * @param _recipient The address of the recipient on the destination chain.\n     * @param _amount The amount of tokens to be sent to the remote recipient.\n     * @dev This should be overridden for warp routes that require additional fees/approvals.\n     * @return quotes Indicate how much of each token to approve and/or send.\n     */\n    function quoteTransferRemote(\n        uint32 _destination,\n        bytes32 _recipient,\n        uint256 _amount\n    ) external view virtual override returns (Quote[] memory quotes) {\n        quotes = new Quote[](1);\n        quotes[0] = Quote({\n            token: address(0),\n            amount: _quoteGasPayment(_destination, _recipient, _amount)\n        });\n    }\n\n    /**\n     * DEPRECATED: Use `quoteTransferRemote` instead.\n     * @notice Returns the gas payment required to dispatch a message to the given domain's router.\n     * @param _destinationDomain The domain of the router.\n     * @dev Assumes bytes32(0) recipient and max amount of tokens for quoting.\n     * @return payment How much native value to send in transferRemote call.\n     */\n    function quoteGasPayment(\n        uint32 _destinationDomain\n    ) public view virtual override returns (uint256) {\n        return\n            _quoteGasPayment(_destinationDomain, bytes32(0), type(uint256).max);\n    }\n\n    function _quoteGasPayment(\n        uint32 _destinationDomain,\n        bytes32 _recipient,\n        uint256 _amount\n    ) internal view returns (uint256) {\n        return\n            _GasRouter_quoteDispatch(\n                _destinationDomain,\n                TokenMessage.format(_recipient, _amount),\n                address(hook)\n            );\n    }\n\n    /**\n     * @dev Mints tokens to recipient when router receives transfer message.\n     * @dev Emits `ReceivedTransferRemote` event on the destination chain.\n     * @param _origin The identifier of the origin chain.\n     * @param _message The encoded remote transfer message containing the recipient address and amount.\n     */\n    function _handle(\n        uint32 _origin,\n        bytes32,\n        bytes calldata _message\n    ) internal virtual override {\n        bytes32 recipient = _message.recipient();\n        uint256 amount = _message.amount();\n        bytes calldata metadata = _message.metadata();\n        _transferTo(\n            recipient.bytes32ToAddress(),\n            _inboundAmount(amount),\n            metadata\n        );\n        emit ReceivedTransferRemote(_origin, recipient, amount);\n    }\n\n    /**\n     * @dev Should transfer `_amountOrId` of tokens from this token router to `_recipient`.\n     * @dev Called by `handle` after message decoding.\n     * @dev Optionally handles `metadata` associated with transfer passed in message.\n     */\n    function _transferTo(\n        address _recipient,\n        uint256 _amountOrId,\n        bytes calldata metadata\n    ) internal virtual;\n}\n"},"contracts/token/TokenBridgeCctp.sol":{"content":"// SPDX-License-Identifier: MIT OR Apache-2.0\npragma solidity >=0.8.0;\n\nimport {TokenRouter} from \"./libs/TokenRouter.sol\";\nimport {HypERC20Collateral} from \"./HypERC20Collateral.sol\";\nimport {IMessageTransmitter} from \"./../interfaces/cctp/IMessageTransmitter.sol\";\nimport {IInterchainSecurityModule} from \"./../interfaces/IInterchainSecurityModule.sol\";\nimport {AbstractCcipReadIsm} from \"./../isms/ccip-read/AbstractCcipReadIsm.sol\";\nimport {TypedMemView} from \"./../libs/TypedMemView.sol\";\nimport {ITokenMessenger} from \"./../interfaces/cctp/ITokenMessenger.sol\";\nimport {Message} from \"./../libs/Message.sol\";\nimport {TokenMessage} from \"./libs/TokenMessage.sol\";\nimport {CctpMessage, BurnMessage} from \"../libs/CctpMessage.sol\";\n\ninterface CctpService {\n    function getCCTPAttestation(\n        bytes calldata _message\n    )\n        external\n        view\n        returns (bytes memory cctpMessage, bytes memory attestation);\n}\n\n// TokenMessage.metadata := uint8 cctpNonce\nuint256 constant CCTP_TOKEN_BRIDGE_MESSAGE_LEN = TokenMessage.METADATA_OFFSET +\n    8;\n\n// @dev Supports only CCTP V1\ncontract TokenBridgeCctp is HypERC20Collateral, AbstractCcipReadIsm {\n    using CctpMessage for bytes29;\n    using BurnMessage for bytes29;\n\n    using Message for bytes;\n\n    uint32 internal constant CCTP_VERSION = 0;\n\n    // @notice CCTP message transmitter contract\n    IMessageTransmitter public immutable messageTransmitter;\n\n    // @notice CCTP token messenger contract\n    ITokenMessenger public immutable tokenMessenger;\n\n    struct Domain {\n        uint32 hyperlane;\n        uint32 circle;\n    }\n\n    /// @notice Hyperlane domain => Circle domain.\n    /// We use a struct to avoid ambiguity with domain 0 being unknown.\n    mapping(uint32 hypDomain => Domain circleDomain) internal _domainMap;\n\n    /**\n     * @notice Emitted when the Hyperlane domain to Circle domain mapping is updated.\n     * @param hyperlaneDomain The Hyperlane domain.\n     * @param circleDomain The Circle domain.\n     */\n    event DomainAdded(uint32 indexed hyperlaneDomain, uint32 circleDomain);\n\n    constructor(\n        address _erc20,\n        uint256 _scale,\n        address _mailbox,\n        IMessageTransmitter _messageTransmitter,\n        ITokenMessenger _tokenMessenger\n    ) HypERC20Collateral(_erc20, _scale, _mailbox) {\n        require(\n            _messageTransmitter.version() == CCTP_VERSION,\n            \"Invalid messageTransmitter CCTP version\"\n        );\n        messageTransmitter = _messageTransmitter;\n\n        require(\n            _tokenMessenger.messageBodyVersion() == CCTP_VERSION,\n            \"Invalid TokenMessenger CCTP version\"\n        );\n        tokenMessenger = _tokenMessenger;\n\n        _disableInitializers();\n    }\n\n    function initialize(\n        address _hook,\n        address _owner,\n        string[] memory __urls\n    ) external virtual initializer {\n        __Ownable_init();\n        setUrls(__urls);\n        // ISM should not be set\n        _MailboxClient_initialize(_hook, address(0), _owner);\n        wrappedToken.approve(address(tokenMessenger), type(uint256).max);\n    }\n\n    function initialize(\n        address _hook,\n        address _interchainSecurityModule,\n        address _owner\n    ) public override {\n        revert(\"Only TokenBridgeCctp.initialize() may be called\");\n    }\n\n    function interchainSecurityModule()\n        external\n        view\n        override\n        returns (IInterchainSecurityModule)\n    {\n        return IInterchainSecurityModule(address(this));\n    }\n\n    /**\n     * @notice Adds a new mapping between a Hyperlane domain and a Circle domain.\n     * @param _hyperlaneDomain The Hyperlane domain.\n     * @param _circleDomain The Circle domain.\n     */\n    function addDomain(\n        uint32 _hyperlaneDomain,\n        uint32 _circleDomain\n    ) public onlyOwner {\n        _domainMap[_hyperlaneDomain] = Domain(_hyperlaneDomain, _circleDomain);\n\n        emit DomainAdded(_hyperlaneDomain, _circleDomain);\n    }\n\n    function addDomains(Domain[] memory domains) external onlyOwner {\n        for (uint32 i = 0; i < domains.length; i++) {\n            addDomain(domains[i].hyperlane, domains[i].circle);\n        }\n    }\n\n    function hyperlaneDomainToCircleDomain(\n        uint32 _hyperlaneDomain\n    ) public view returns (uint32) {\n        Domain memory domain = _domainMap[_hyperlaneDomain];\n        require(\n            domain.hyperlane == _hyperlaneDomain,\n            \"Circle domain not configured\"\n        );\n\n        return domain.circle;\n    }\n\n    // @dev Enforces that the CCTP message source domain and nonce matches the Hyperlane message origin and nonce.\n    function verify(\n        bytes calldata _metadata,\n        bytes calldata _hyperlaneMessage\n    ) external returns (bool) {\n        // decode return type of CctpService.getCCTPAttestation\n        (bytes memory cctpMessage, bytes memory attestation) = abi.decode(\n            _metadata,\n            (bytes, bytes)\n        );\n\n        bytes calldata tokenMessage = _hyperlaneMessage.body();\n        _validateMessageLength(tokenMessage);\n\n        bytes29 originalMsg = TypedMemView.ref(cctpMessage, 0);\n\n        bytes29 burnMessage = originalMsg._messageBody();\n        require(\n            TokenMessage.amount(tokenMessage) == burnMessage._getAmount(),\n            \"Invalid amount\"\n        );\n        require(\n            TokenMessage.recipient(tokenMessage) ==\n                burnMessage._getMintRecipient(),\n            \"Invalid recipient\"\n        );\n\n        bytes32 sourceSender = burnMessage._getMessageSender();\n        require(sourceSender == _hyperlaneMessage.sender(), \"Invalid sender\");\n\n        uint32 sourceDomain = originalMsg._sourceDomain();\n        require(\n            sourceDomain ==\n                hyperlaneDomainToCircleDomain(_hyperlaneMessage.origin()),\n            \"Invalid source domain\"\n        );\n\n        uint64 sourceNonce = originalMsg._nonce();\n        require(\n            sourceNonce == uint64(bytes8(TokenMessage.metadata(tokenMessage))),\n            \"Invalid nonce\"\n        );\n\n        // Receive only if the nonce hasn't been used before\n        bytes32 sourceAndNonceHash = keccak256(\n            abi.encodePacked(sourceDomain, sourceNonce)\n        );\n        if (messageTransmitter.usedNonces(sourceAndNonceHash) == 0) {\n            messageTransmitter.receiveMessage(cctpMessage, attestation);\n        }\n\n        return true;\n    }\n\n    function _transferRemote(\n        uint32 _destination,\n        bytes32 _recipient,\n        uint256 _amount,\n        uint256 _value,\n        bytes memory _hookMetadata,\n        address _hook\n    ) internal virtual override returns (bytes32 messageId) {\n        HypERC20Collateral._transferFromSender(_amount);\n\n        uint32 circleDomain = hyperlaneDomainToCircleDomain(_destination);\n        uint64 nonce = tokenMessenger.depositForBurn(\n            _amount,\n            circleDomain,\n            _recipient,\n            address(wrappedToken)\n        );\n\n        uint256 outboundAmount = _outboundAmount(_amount);\n        bytes memory _tokenMessage = TokenMessage.format(\n            _recipient,\n            outboundAmount,\n            abi.encodePacked(nonce)\n        );\n        _validateMessageLength(_tokenMessage);\n\n        messageId = _Router_dispatch(\n            _destination,\n            _value,\n            _tokenMessage,\n            _hookMetadata,\n            _hook\n        );\n\n        emit SentTransferRemote(_destination, _recipient, outboundAmount);\n    }\n\n    function _offchainLookupCalldata(\n        bytes calldata _message\n    ) internal pure override returns (bytes memory) {\n        return abi.encodeCall(CctpService.getCCTPAttestation, (_message));\n    }\n\n    function _transferTo(\n        address _recipient,\n        uint256 _amount,\n        bytes calldata metadata\n    ) internal override {\n        // do not transfer to recipient as the CCTP transfer will do it\n    }\n\n    function _validateMessageLength(bytes memory _tokenMessage) internal pure {\n        require(\n            _tokenMessage.length == CCTP_TOKEN_BRIDGE_MESSAGE_LEN,\n            \"Invalid message body length\"\n        );\n    }\n}\n"},"contracts/upgrade/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 \"@openzeppelin/contracts/proxy/transparent/ProxyAdmin.sol\";\n"},"contracts/upgrade/TimelockController.sol":{"content":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (governance/TimelockController.sol)\n\npragma solidity ^0.8.0;\n\nimport \"@openzeppelin/contracts/governance/TimelockController.sol\";\n"},"contracts/upgrade/TransparentUpgradeableProxy.sol":{"content":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (proxy/transparent/TransparentUpgradeableProxy.sol)\n\npragma solidity ^0.8.0;\n\nimport \"@openzeppelin/contracts/proxy/transparent/TransparentUpgradeableProxy.sol\";\n"},"contracts/upgrade/Versioned.sol":{"content":"// SPDX-License-Identifier: MIT OR Apache-2.0\npragma solidity >=0.6.11;\n\n/**\n * @title Versioned\n * @notice Version getter for contracts\n **/\ncontract Versioned {\n    uint8 public constant VERSION = 3;\n}\n"}},"settings":{"optimizer":{"enabled":true,"mode":"3"},"evmVersion":"paris","outputSelection":{"*":{"*":["abi","evm.methodIdentifiers","metadata"],"":["ast"]}},"detectMissingLibraries":false,"forceEVMLA":false,"enableEraVMExtensions":false,"libraries":{}}},"solcLongVersion":"zkVM-0.8.22-1.0.2","zk_version":"1.5.12"}