{"file_path":"lib/native-token-transfers/evm/src/NttManager/NttManager.sol","creation_status":"success","source_code":"// SPDX-License-Identifier: Apache 2\npragma solidity >=0.8.8 <0.9.0;\n\nimport \"openzeppelin-contracts/contracts/token/ERC20/IERC20.sol\";\nimport \"openzeppelin-contracts/contracts/token/ERC20/utils/SafeERC20.sol\";\nimport \"openzeppelin-contracts/contracts/token/ERC20/extensions/ERC20Burnable.sol\";\nimport \"wormhole-solidity-sdk/Utils.sol\";\nimport \"wormhole-solidity-sdk/libraries/BytesParsing.sol\";\n\nimport \"../libraries/RateLimiter.sol\";\n\nimport \"../interfaces/INttManager.sol\";\nimport \"../interfaces/INttToken.sol\";\nimport \"../interfaces/ITransceiver.sol\";\n\nimport {ManagerBase} from \"./ManagerBase.sol\";\n\n/// @title NttManager\n/// @author Wormhole Project Contributors.\n/// @notice The NttManager contract is responsible for managing the token\n///         and associated transceivers.\n///\n/// @dev Each NttManager contract is associated with a single token but\n///      can be responsible for multiple transceivers.\n///\n/// @dev When transferring tokens, the NttManager contract will either\n///      lock the tokens or burn them, depending on the mode.\n///\n/// @dev To initiate a transfer, the user calls the transfer function with:\n///  - the amount\n///  - the recipient chain\n///  - the recipient address\n///  - the refund address: the address to which refunds are issued for any unused gas\n///    for attestations on a given transfer. If the gas limit is configured\n///    to be too high, users will be refunded the difference.\n///  - (optional) a flag to indicate whether the transfer should be queued\n///    if the rate limit is exceeded\ncontract NttManager is INttManager, RateLimiter, ManagerBase {\n    using BytesParsing for bytes;\n    using SafeERC20 for IERC20;\n    using TrimmedAmountLib for uint256;\n    using TrimmedAmountLib for TrimmedAmount;\n\n    string public constant NTT_MANAGER_VERSION = \"1.1.0\";\n\n    // =============== Setup =================================================================\n\n    constructor(\n        address _token,\n        Mode _mode,\n        uint16 _chainId,\n        uint64 _rateLimitDuration,\n        bool _skipRateLimiting\n    ) RateLimiter(_rateLimitDuration, _skipRateLimiting) ManagerBase(_token, _mode, _chainId) {}\n\n    function __NttManager_init() internal onlyInitializing {\n        // check if the owner is the deployer of this contract\n        if (msg.sender != deployer) {\n            revert UnexpectedDeployer(deployer, msg.sender);\n        }\n        if (msg.value != 0) {\n            revert UnexpectedMsgValue();\n        }\n        __PausedOwnable_init(msg.sender, msg.sender);\n        __ReentrancyGuard_init();\n        _setOutboundLimit(TrimmedAmountLib.max(tokenDecimals()));\n    }\n\n    function _initialize() internal virtual override {\n        __NttManager_init();\n        _checkThresholdInvariants();\n        _checkTransceiversInvariants();\n    }\n\n    // =============== Storage ==============================================================\n\n    bytes32 private constant PEERS_SLOT = bytes32(uint256(keccak256(\"ntt.peers\")) - 1);\n\n    // =============== Storage Getters/Setters ==============================================\n\n    function _getPeersStorage()\n        internal\n        pure\n        returns (mapping(uint16 => NttManagerPeer) storage $)\n    {\n        uint256 slot = uint256(PEERS_SLOT);\n        assembly (\"memory-safe\") {\n            $.slot := slot\n        }\n    }\n\n    // =============== Public Getters ========================================================\n\n    /// @inheritdoc INttManager\n    function getPeer(\n        uint16 chainId_\n    ) external view returns (NttManagerPeer memory) {\n        return _getPeersStorage()[chainId_];\n    }\n\n    // =============== Admin ==============================================================\n\n    /// @inheritdoc INttManager\n    function setPeer(\n        uint16 peerChainId,\n        bytes32 peerContract,\n        uint8 decimals,\n        uint256 inboundLimit\n    ) public onlyOwner {\n        if (peerChainId == 0) {\n            revert InvalidPeerChainIdZero();\n        }\n        if (peerContract == bytes32(0)) {\n            revert InvalidPeerZeroAddress();\n        }\n        if (decimals == 0) {\n            revert InvalidPeerDecimals();\n        }\n        if (peerChainId == chainId) {\n            revert InvalidPeerSameChainId();\n        }\n\n        NttManagerPeer memory oldPeer = _getPeersStorage()[peerChainId];\n\n        _getPeersStorage()[peerChainId].peerAddress = peerContract;\n        _getPeersStorage()[peerChainId].tokenDecimals = decimals;\n\n        uint8 toDecimals = tokenDecimals();\n        _setInboundLimit(inboundLimit.trim(toDecimals, toDecimals), peerChainId);\n\n        emit PeerUpdated(\n            peerChainId, oldPeer.peerAddress, oldPeer.tokenDecimals, peerContract, decimals\n        );\n    }\n\n    /// @inheritdoc INttManager\n    function setOutboundLimit(\n        uint256 limit\n    ) external onlyOwner {\n        uint8 toDecimals = tokenDecimals();\n        _setOutboundLimit(limit.trim(toDecimals, toDecimals));\n    }\n\n    /// @inheritdoc INttManager\n    function setInboundLimit(uint256 limit, uint16 chainId_) external onlyOwner {\n        uint8 toDecimals = tokenDecimals();\n        _setInboundLimit(limit.trim(toDecimals, toDecimals), chainId_);\n    }\n\n    /// ============== Invariants =============================================\n\n    /// @dev When we add new immutables, this function should be updated\n    function _checkImmutables() internal view override {\n        super._checkImmutables();\n        assert(this.rateLimitDuration() == rateLimitDuration);\n    }\n\n    // ==================== External Interface ===============================================\n\n    /// @inheritdoc INttManager\n    function transfer(\n        uint256 amount,\n        uint16 recipientChain,\n        bytes32 recipient\n    ) external payable nonReentrant whenNotPaused returns (uint64) {\n        return\n            _transferEntryPoint(amount, recipientChain, recipient, recipient, false, new bytes(1));\n    }\n\n    /// @inheritdoc INttManager\n    function transfer(\n        uint256 amount,\n        uint16 recipientChain,\n        bytes32 recipient,\n        bytes32 refundAddress,\n        bool shouldQueue,\n        bytes memory transceiverInstructions\n    ) external payable nonReentrant whenNotPaused returns (uint64) {\n        return _transferEntryPoint(\n            amount, recipientChain, recipient, refundAddress, shouldQueue, transceiverInstructions\n        );\n    }\n\n    /// @inheritdoc INttManager\n    function attestationReceived(\n        uint16 sourceChainId,\n        bytes32 sourceNttManagerAddress,\n        TransceiverStructs.NttManagerMessage memory payload\n    ) external onlyTransceiver whenNotPaused {\n        _verifyPeer(sourceChainId, sourceNttManagerAddress);\n\n        // Compute manager message digest and record transceiver attestation.\n        bytes32 nttManagerMessageHash = _recordTransceiverAttestation(sourceChainId, payload);\n\n        if (isMessageApproved(nttManagerMessageHash)) {\n            executeMsg(sourceChainId, sourceNttManagerAddress, payload);\n        }\n    }\n\n    /// @inheritdoc INttManager\n    function executeMsg(\n        uint16 sourceChainId,\n        bytes32 sourceNttManagerAddress,\n        TransceiverStructs.NttManagerMessage memory message\n    ) public whenNotPaused {\n        (bytes32 digest, bool alreadyExecuted) =\n            _isMessageExecuted(sourceChainId, sourceNttManagerAddress, message);\n\n        if (alreadyExecuted) {\n            return;\n        }\n\n        _handleMsg(sourceChainId, sourceNttManagerAddress, message, digest);\n    }\n\n    /// @dev Override this function to handle custom NttManager payloads.\n    /// This can also be used to customize transfer logic by using your own\n    /// _handleTransfer implementation.\n    function _handleMsg(\n        uint16 sourceChainId,\n        bytes32 sourceNttManagerAddress,\n        TransceiverStructs.NttManagerMessage memory message,\n        bytes32 digest\n    ) internal virtual {\n        _handleTransfer(sourceChainId, sourceNttManagerAddress, message, digest);\n    }\n\n    function _handleTransfer(\n        uint16 sourceChainId,\n        bytes32 sourceNttManagerAddress,\n        TransceiverStructs.NttManagerMessage memory message,\n        bytes32 digest\n    ) internal {\n        TransceiverStructs.NativeTokenTransfer memory nativeTokenTransfer =\n            TransceiverStructs.parseNativeTokenTransfer(message.payload);\n\n        // verify that the destination chain is valid\n        if (nativeTokenTransfer.toChain != chainId) {\n            revert InvalidTargetChain(nativeTokenTransfer.toChain, chainId);\n        }\n        uint8 toDecimals = tokenDecimals();\n        TrimmedAmount nativeTransferAmount =\n            (nativeTokenTransfer.amount.untrim(toDecimals)).trim(toDecimals, toDecimals);\n\n        address transferRecipient = fromWormholeFormat(nativeTokenTransfer.to);\n\n        bool enqueued = _enqueueOrConsumeInboundRateLimit(\n            digest, sourceChainId, nativeTransferAmount, transferRecipient\n        );\n\n        if (enqueued) {\n            return;\n        }\n\n        _handleAdditionalPayload(\n            sourceChainId, sourceNttManagerAddress, message.id, message.sender, nativeTokenTransfer\n        );\n\n        _mintOrUnlockToRecipient(digest, transferRecipient, nativeTransferAmount, false);\n    }\n\n    /// @dev Override this function to process an additional payload on the NativeTokenTransfer\n    /// For integrator flexibility, this function is *not* marked pure or view\n    /// @param - The Wormhole chain id of the sender\n    /// @param - The address of the sender's NTT Manager contract.\n    /// @param - The message id from the NttManagerMessage.\n    /// @param - The original message sender address from the NttManagerMessage.\n    /// @param - The parsed NativeTokenTransfer, which includes the additionalPayload field\n    function _handleAdditionalPayload(\n        uint16, // sourceChainId\n        bytes32, // sourceNttManagerAddress\n        bytes32, // id\n        bytes32, // sender\n        TransceiverStructs.NativeTokenTransfer memory // nativeTokenTransfer\n    ) internal virtual {}\n\n    function _enqueueOrConsumeInboundRateLimit(\n        bytes32 digest,\n        uint16 sourceChainId,\n        TrimmedAmount nativeTransferAmount,\n        address transferRecipient\n    ) internal virtual returns (bool) {\n        // Check inbound rate limits\n        bool isRateLimited = _isInboundAmountRateLimited(nativeTransferAmount, sourceChainId);\n        if (isRateLimited) {\n            // queue up the transfer\n            _enqueueInboundTransfer(digest, nativeTransferAmount, transferRecipient);\n\n            // end execution early\n            return true;\n        }\n\n        // consume the amount for the inbound rate limit\n        _consumeInboundAmount(nativeTransferAmount, sourceChainId);\n        // When receiving a transfer, we refill the outbound rate limit\n        // by the same amount (we call this \"backflow\")\n        _backfillOutboundAmount(nativeTransferAmount);\n        return false;\n    }\n\n    /// @inheritdoc INttManager\n    function completeInboundQueuedTransfer(\n        bytes32 digest\n    ) external virtual nonReentrant whenNotPaused {\n        // find the message in the queue\n        InboundQueuedTransfer memory queuedTransfer = RateLimiter.getInboundQueuedTransfer(digest);\n        if (queuedTransfer.txTimestamp == 0) {\n            revert InboundQueuedTransferNotFound(digest);\n        }\n\n        // check that > RATE_LIMIT_DURATION has elapsed\n        if (block.timestamp - queuedTransfer.txTimestamp < rateLimitDuration) {\n            revert InboundQueuedTransferStillQueued(digest, queuedTransfer.txTimestamp);\n        }\n\n        // remove transfer from the queue\n        delete _getInboundQueueStorage()[digest];\n\n        // run it through the mint/unlock logic\n        _mintOrUnlockToRecipient(digest, queuedTransfer.recipient, queuedTransfer.amount, false);\n    }\n\n    /// @inheritdoc INttManager\n    function completeOutboundQueuedTransfer(\n        uint64 messageSequence\n    ) external payable virtual nonReentrant whenNotPaused returns (uint64) {\n        // find the message in the queue\n        OutboundQueuedTransfer memory queuedTransfer = _getOutboundQueueStorage()[messageSequence];\n        if (queuedTransfer.txTimestamp == 0) {\n            revert OutboundQueuedTransferNotFound(messageSequence);\n        }\n\n        // check that > RATE_LIMIT_DURATION has elapsed\n        if (block.timestamp - queuedTransfer.txTimestamp < rateLimitDuration) {\n            revert OutboundQueuedTransferStillQueued(messageSequence, queuedTransfer.txTimestamp);\n        }\n\n        // remove transfer from the queue\n        delete _getOutboundQueueStorage()[messageSequence];\n\n        // run it through the transfer logic and skip the rate limit\n        return _transfer(\n            messageSequence,\n            queuedTransfer.amount,\n            queuedTransfer.recipientChain,\n            queuedTransfer.recipient,\n            queuedTransfer.refundAddress,\n            queuedTransfer.sender,\n            queuedTransfer.transceiverInstructions\n        );\n    }\n\n    /// @inheritdoc INttManager\n    function cancelOutboundQueuedTransfer(\n        uint64 messageSequence\n    ) external virtual nonReentrant whenNotPaused {\n        // find the message in the queue\n        OutboundQueuedTransfer memory queuedTransfer = _getOutboundQueueStorage()[messageSequence];\n        if (queuedTransfer.txTimestamp == 0) {\n            revert OutboundQueuedTransferNotFound(messageSequence);\n        }\n\n        // check msg.sender initiated the transfer\n        if (queuedTransfer.sender != msg.sender) {\n            revert CancellerNotSender(msg.sender, queuedTransfer.sender);\n        }\n\n        // remove transfer from the queue\n        delete _getOutboundQueueStorage()[messageSequence];\n\n        // return the queued funds to the sender\n        _mintOrUnlockToRecipient(\n            bytes32(uint256(messageSequence)), msg.sender, queuedTransfer.amount, true\n        );\n    }\n\n    // ==================== Internal Business Logic =========================================\n\n    function _transferEntryPoint(\n        uint256 amount,\n        uint16 recipientChain,\n        bytes32 recipient,\n        bytes32 refundAddress,\n        bool shouldQueue,\n        bytes memory transceiverInstructions\n    ) internal returns (uint64) {\n        if (amount == 0) {\n            revert ZeroAmount();\n        }\n\n        if (recipient == bytes32(0)) {\n            revert InvalidRecipient();\n        }\n\n        if (refundAddress == bytes32(0)) {\n            revert InvalidRefundAddress();\n        }\n\n        {\n            // Lock/burn tokens before checking rate limits\n            // use transferFrom to pull tokens from the user and lock them\n            // query own token balance before transfer\n            uint256 balanceBefore = _getTokenBalanceOf(token, address(this));\n\n            // transfer tokens\n            IERC20(token).safeTransferFrom(msg.sender, address(this), amount);\n\n            // query own token balance after transfer\n            uint256 balanceAfter = _getTokenBalanceOf(token, address(this));\n\n            // correct amount for potential transfer fees\n            amount = balanceAfter - balanceBefore;\n            if (mode == Mode.BURNING) {\n                {\n                    // NOTE: We don't account for burn fees in this code path.\n                    // We verify that the user's change in balance is equal to the amount that's burned.\n                    // Accounting for burn fees can be non-trivial, since there\n                    // is no standard way to account for the fee if the fee amount\n                    // is taken out of the burn amount.\n                    // For example, if there's a fee of 1 which is taken out of the\n                    // amount, then burning 20 tokens would result in a transfer of only 19 tokens.\n                    // However, the difference in the user's balance would only show 20.\n                    // Since there is no standard way to query for burn fee amounts with burnable tokens,\n                    // and NTT would be used on a per-token basis, implementing this functionality\n                    // is left to integrating projects who may need to account for burn fees on their tokens.\n                    ERC20Burnable(token).burn(amount);\n\n                    // tokens held by the contract after the operation should be the same as before\n                    uint256 balanceAfterBurn = _getTokenBalanceOf(token, address(this));\n                    if (balanceBefore != balanceAfterBurn) {\n                        revert BurnAmountDifferentThanBalanceDiff(balanceBefore, balanceAfterBurn);\n                    }\n                }\n            }\n        }\n\n        // trim amount after burning to ensure transfer amount matches (amount - fee)\n        TrimmedAmount trimmedAmount = _trimTransferAmount(amount, recipientChain);\n\n        // get the sequence for this transfer\n        uint64 sequence = _useMessageSequence();\n\n        bool enqueued = _enqueueOrConsumeOutboundRateLimit(\n            amount,\n            recipientChain,\n            recipient,\n            refundAddress,\n            shouldQueue,\n            transceiverInstructions,\n            trimmedAmount,\n            sequence\n        );\n\n        if (enqueued) {\n            return sequence;\n        }\n\n        return _transfer(\n            sequence,\n            trimmedAmount,\n            recipientChain,\n            recipient,\n            refundAddress,\n            msg.sender,\n            transceiverInstructions\n        );\n    }\n\n    function _enqueueOrConsumeOutboundRateLimit(\n        uint256 amount,\n        uint16 recipientChain,\n        bytes32 recipient,\n        bytes32 refundAddress,\n        bool shouldQueue,\n        bytes memory transceiverInstructions,\n        TrimmedAmount trimmedAmount,\n        uint64 sequence\n    ) internal virtual returns (bool enqueued) {\n        TrimmedAmount internalAmount = trimmedAmount.shift(tokenDecimals());\n\n        // now check rate limits\n        bool isAmountRateLimited = _isOutboundAmountRateLimited(internalAmount);\n        if (!shouldQueue && isAmountRateLimited) {\n            revert NotEnoughCapacity(getCurrentOutboundCapacity(), amount);\n        }\n        if (shouldQueue && isAmountRateLimited) {\n            // verify chain has not forked\n            checkFork(evmChainId);\n\n            // emit an event to notify the user that the transfer is rate limited\n            emit OutboundTransferRateLimited(\n                msg.sender, sequence, amount, getCurrentOutboundCapacity()\n            );\n\n            // queue up and return\n            _enqueueOutboundTransfer(\n                sequence,\n                trimmedAmount,\n                recipientChain,\n                recipient,\n                refundAddress,\n                msg.sender,\n                transceiverInstructions\n            );\n\n            // refund price quote back to sender\n            _refundToSender(msg.value);\n\n            // return that the transfer has been enqued\n            return true;\n        }\n\n        // otherwise, consume the outbound amount\n        _consumeOutboundAmount(internalAmount);\n        // When sending a transfer, we refill the inbound rate limit for\n        // that chain by the same amount (we call this \"backflow\")\n        _backfillInboundAmount(internalAmount, recipientChain);\n        return false;\n    }\n\n    function _transfer(\n        uint64 sequence,\n        TrimmedAmount amount,\n        uint16 recipientChain,\n        bytes32 recipient,\n        bytes32 refundAddress,\n        address sender,\n        bytes memory transceiverInstructions\n    ) internal returns (uint64 msgSequence) {\n        // verify chain has not forked\n        checkFork(evmChainId);\n\n        (\n            address[] memory enabledTransceivers,\n            TransceiverStructs.TransceiverInstruction[] memory instructions,\n            uint256[] memory priceQuotes,\n            uint256 totalPriceQuote\n        ) = _prepareForTransfer(recipientChain, transceiverInstructions);\n\n        // push it on the stack again to avoid a stack too deep error\n        uint64 seq = sequence;\n\n        TransceiverStructs.NativeTokenTransfer memory ntt = _prepareNativeTokenTransfer(\n            amount, recipient, recipientChain, seq, sender, refundAddress\n        );\n\n        // construct the NttManagerMessage payload\n        bytes memory encodedNttManagerPayload = TransceiverStructs.encodeNttManagerMessage(\n            TransceiverStructs.NttManagerMessage(\n                bytes32(uint256(seq)),\n                toWormholeFormat(sender),\n                TransceiverStructs.encodeNativeTokenTransfer(ntt)\n            )\n        );\n\n        // push onto the stack again to avoid stack too deep error\n        uint16 destinationChain = recipientChain;\n\n        // send the message\n        _sendMessageToTransceivers(\n            recipientChain,\n            refundAddress,\n            _getPeersStorage()[destinationChain].peerAddress,\n            priceQuotes,\n            instructions,\n            enabledTransceivers,\n            encodedNttManagerPayload\n        );\n\n        // push it on the stack again to avoid a stack too deep error\n        TrimmedAmount amt = amount;\n\n        emit TransferSent(\n            recipient,\n            refundAddress,\n            amt.untrim(tokenDecimals()),\n            totalPriceQuote,\n            destinationChain,\n            seq\n        );\n\n        emit TransferSent(\n            TransceiverStructs._nttManagerMessageDigest(chainId, encodedNttManagerPayload)\n        );\n\n        // return the sequence number\n        return seq;\n    }\n\n    /// @dev Override this function to provide an additional payload on the NativeTokenTransfer\n    /// For integrator flexibility, this function is *not* marked pure or view\n    /// @param amount TrimmedAmount of the transfer\n    /// @param recipient The recipient address\n    /// @param recipientChain The Wormhole chain ID for the destination\n    /// @param - The sequence number for the manager message (unused, provided for overriding integrators)\n    /// @param - The sender of the funds (unused, provided for overriding integrators). If releasing\n    /// @param - The address on the destination chain to which the refund of unused gas will be paid\n    /// queued transfers, when rate limiting is used, then this value could be different from msg.sender.\n    /// @return - The TransceiverStructs.NativeTokenTransfer struct\n    function _prepareNativeTokenTransfer(\n        TrimmedAmount amount,\n        bytes32 recipient,\n        uint16 recipientChain,\n        uint64, // sequence\n        address, // sender\n        bytes32 // refundAddress\n    ) internal virtual returns (TransceiverStructs.NativeTokenTransfer memory) {\n        return TransceiverStructs.NativeTokenTransfer(\n            amount, toWormholeFormat(token), recipient, recipientChain, \"\"\n        );\n    }\n\n    function _mintOrUnlockToRecipient(\n        bytes32 digest,\n        address recipient,\n        TrimmedAmount amount,\n        bool cancelled\n    ) internal {\n        // verify chain has not forked\n        checkFork(evmChainId);\n\n        // calculate proper amount of tokens to unlock/mint to recipient\n        // untrim the amount\n        uint256 untrimmedAmount = amount.untrim(tokenDecimals());\n\n        if (cancelled) {\n            emit OutboundTransferCancelled(uint256(digest), recipient, untrimmedAmount);\n        } else {\n            emit TransferRedeemed(digest);\n        }\n\n        if (mode == Mode.LOCKING) {\n            // unlock tokens to the specified recipient\n            IERC20(token).safeTransfer(recipient, untrimmedAmount);\n        } else if (mode == Mode.BURNING) {\n            // mint tokens to the specified recipient\n            INttToken(token).mint(recipient, untrimmedAmount);\n        } else {\n            revert InvalidMode(uint8(mode));\n        }\n    }\n\n    function tokenDecimals() public view override(INttManager, RateLimiter) returns (uint8) {\n        (bool success, bytes memory queriedDecimals) =\n            token.staticcall(abi.encodeWithSignature(\"decimals()\"));\n\n        if (!success) {\n            revert StaticcallFailed();\n        }\n\n        return abi.decode(queriedDecimals, (uint8));\n    }\n\n    // ==================== Internal Helpers ===============================================\n\n    /// @dev Verify that the peer address saved for `sourceChainId` matches the `peerAddress`.\n    function _verifyPeer(uint16 sourceChainId, bytes32 peerAddress) internal view {\n        if (_getPeersStorage()[sourceChainId].peerAddress != peerAddress) {\n            revert InvalidPeer(sourceChainId, peerAddress);\n        }\n    }\n\n    function _trimTransferAmount(\n        uint256 amount,\n        uint16 toChain\n    ) internal view returns (TrimmedAmount) {\n        uint8 toDecimals = _getPeersStorage()[toChain].tokenDecimals;\n\n        if (toDecimals == 0) {\n            revert InvalidPeerDecimals();\n        }\n\n        TrimmedAmount trimmedAmount;\n        {\n            uint8 fromDecimals = tokenDecimals();\n            trimmedAmount = amount.trim(fromDecimals, toDecimals);\n            // don't deposit dust that can not be bridged due to the decimal shift\n            uint256 newAmount = trimmedAmount.untrim(fromDecimals);\n            if (amount != newAmount) {\n                revert TransferAmountHasDust(amount, amount - newAmount);\n            }\n        }\n\n        return trimmedAmount;\n    }\n\n    function _getTokenBalanceOf(\n        address tokenAddr,\n        address accountAddr\n    ) internal view returns (uint256) {\n        (bool success, bytes memory queriedBalance) =\n            tokenAddr.staticcall(abi.encodeWithSelector(IERC20.balanceOf.selector, accountAddr));\n\n        if (!success) {\n            revert StaticcallFailed();\n        }\n\n        return abi.decode(queriedBalance, (uint256));\n    }\n}\n","deployed_bytecode":"0x60806040526004361015610011575f80fd5b5f803560e01c80630271725014612bd0578063036de8af14612b495780630677df5414612b2b5780630900f010146126c4578063186ce61214612694578063190171751461265e5780631f97c9a81461246f578063203e4a9b1461218157806323d75e311461213b578063295a5212146120e1578063396c16b7146120a65780633b97e8561461208b5780633f4ba83a146120185780634b4fd03b14611fba578063689f90c314611f7857806374aa7bfc14611f345780637c91863414611dc35780638129fc1c14611b915780638413bcba14611a765780638456cb59146119fb57806386e11ffa146119d657806389c619dd146119785780638da5cb5b146119435780638e3ba8c91461190c5780638fd3ab80146117cf5780639057412d14611654578063961b94d0146115f757806397c351461461134a5780639a8a05921461130b5780639d782454146110de5780639f86029c14610de15780639fd0506d14610dac578063b150fc5514610c09578063b187bd2614610bdc578063b293f97f14610b48578063b4d591bb14610a89578063c0b07bde14610a43578063c128d170146109ca578063d788c14714610942578063da4856a114610910578063e5a9860314610865578063e75235b814610838578063f2fde38b146106fb578063f5cfec18146106d8578063f7514fbc146102bc578063fc0c546a146102775763fd96063c1461021f575f80fd5b3461027457602036600319011261027457606061023d600435613268565b6040805182516001600160481b031681526020808401516001600160401b031690820152918101516001600160a01b031690820152f35b80fd5b50346102745780600319360112610274576040517f0000000000000000000000008d58c0c60b8d6b88fa98b291a646db34d0f982586001600160a01b03168152602090f35b5034610274576020366003190112610274576004356001600160401b03811681036106d4576102e9613a00565b60025f80516020615b0c83398151915254146106c2576001600160401b0381165f525f80516020615bcc83398151915260205260405f206040519061032d82612c9d565b8054825260046001916001810154602085015261ffff60028201546001600160481b03811660408701526001600160401b038160481c16606087015260881c16608085015260018060a01b0360038201541660a0850152016040518092869083549361039885612e74565b808552946001811690811561069e575060011461065f575b50506103be92500382612d09565b60c08201526001600160401b036060820151161561063e5760a08101516001600160a01b03163381036106115750606061048760407ff80e572ae1b63e2449629b6c7d783add85c36473926f216077f17ee002bcfd07936001600160401b0386165f525f80516020615bcc83398151915260205261043d825f2061318c565b01516104687f0000000000000000000000000000000000000000000000000000000000002105614b63565b610470612ee9565b906001600160401b0360ff82169160081c166149f7565b926001600160401b0360405191168152336020820152836040820152a17f000000000000000000000000000000000000000000000000000000000000000160028110156105fd5780610550575060405163a9059cbb60e01b6020820152336024820152604481019190915261053c9061050d81606481015b03601f198101835282612d09565b7f0000000000000000000000008d58c0c60b8d6b88fa98b291a646db34d0f982586001600160a01b0316615328565b60015f80516020615bec8339815191525580f35b600181036105e157507f0000000000000000000000008d58c0c60b8d6b88fa98b291a646db34d0f982586001600160a01b0316803b156105dd576040516340c10f1960e01b815233600482015260248101929092525f908290604490829084905af180156105d2576105c3575b5061053c565b6105cc90612c8a565b5f6105bd565b6040513d5f823e3d90fd5b5f80fd5b6040516366001a8960e01b815260ff9091166004820152602490fd5b634e487b7160e01b5f52602160045260245ffd5b60405163ceb40a8560e01b81523360048201526001600160a01b03919091166024820152604490fd5b0390fd5b604051635feafa3160e11b81526001600160401b0383166004820152602490fd5b8852602088208892505b84831061068357506103be93505081016020015f806103b0565b81935090816020925483858901015201910190918492610669565b915050602092506103be94915060ff191682840152151560051b8201015f806103b0565b6040516309e3d0f360e11b8152600490fd5b5080fd5b503461027457806003193601126102745760206106f3613251565b604051908152f35b5034610274576020366003190112610274576001600160a01b03600435818116908181036108035761073c9061072f6133f6565b6107376133f6565b6148f9565b7f3031d39df71efbb605646fc51d7571499445af538fa6dd17ce8c07e8118ed97891825460ff5f80516020615b6c833981519152541680820361081a575050908391825b845481101561081657845f5281817f357eda4c1707ce60b55a439f3dc12fcacea5ca0fd863e2fc179a916cf05fccd1015416803b1561081257848091602460405180948193632c7b84dd60e11b83528960048401525af19081156108075785916107ef575b5050600101610780565b6107f890612c8a565b61080357835f6107e5565b8380fd5b6040513d87823e3d90fd5b8480fd5b8380f35b604492506040519163d2a13a2960e01b835260048301526024820152fd5b5034610274578060031936011261027457602060ff5f80516020615a8c8339815191525416604051908152f35b50346102745760203660031901126102745760043560ff8116908181036105dd5761088e6133f6565b81156108fe577f2a855b929b9a53c6fb5b5ed248b27e502b709c088e036a5aa17620c8fc5085a9916108f860ff925f80516020615a8c833981519152805493851985161790556108dc613946565b6040805160ff9490951684168552921660208401528291820190565b0390a180f35b60405163831761d760e01b8152600490fd5b50346102745761091f36612d8b565b9060025f80516020615b0c83398151915254146106c25761093f92613202565b80f35b50346102745760203660031901126102745761ffff61095f612c22565b610967612f78565b50165f525f80516020615b8c8339815191526020526109c661098b60405f20612fdd565b6040519182918291909160406001600160401b038160608401956001600160481b038082511686526020820151166020860152015116910152565b0390f35b50346102745760203660031901126102745761ffff906109e8612c22565b9060206040516109f781612cd3565b8281520152165f525f80516020615a6c8339815191526020526040805f2060ff8251610a2281612cd3565b60208260018554958685520154169101908152835192835251166020820152f35b50346102745780600319360112610274576109c6604051610a6381612cd3565b60058152640312e312e360dc1b6020820152604051918291602083526020830190612c65565b503461027457806003193601126102745760405180915f80516020615b4c833981519152908154808452602080940190819383525f80516020615aac83398151915290835b818110610b2b5750505084610ae4910385612d09565b60405193838594850191818652518092526040850193925b828110610b0b57505050500390f35b83516001600160a01b031685528695509381019392810192600101610afc565b82546001600160a01b031684529286019260019283019201610ace565b5060c036600319011261027457610b5d612c33565b906084359182151583036106d45760a4356001600160401b03928382116102745750610b8d903690600401612d45565b610b95613a00565b60025f80516020615b0c83398151915254146106c257602093610bc2926064359060443590600435613fda565b60015f80516020615bec8339815191525560405191168152f35b5034610274578060031936011261027457602060025f80516020615b0c8339815191525414604051908152f35b5034610274578060031936011261027457604051805f80516020615b4c833981519152805480845260208094019185525f80516020615aac83398151915290855b818110610d8f5750505081610c60910382612d09565b8051610c6b8161304a565b91610c796040519384612d09565b818352610c858261304a565b601f1901855b818110610d73575050845b828110610cf7575050506040519180830190808452825180925280604085019301945b828110610cc65784840385f35b85518051151585528083015115158584015260409081015160ff169085015294810194606090930192600101610cb9565b9294926001906001600160a01b03610d0f82856131ee565b51165f525f80516020615bac833981519152865260405f2060405190610d3482612cb8565b5460ff9081811615158352818160081c1615158984015260101c166040820152610d5e82896131ee565b52610d6981886131ee565b5001949294610c96565b8590610d80979597612f78565b82828a01015201959395610c8b565b82546001600160a01b031684529285019260019283019201610c4a565b50346102745780600319360112610274575f80516020615c0c833981519152546040516001600160a01b039091168152602090f35b5034610274576020806003193601126106d4576004356001600160a01b03818116929183810361081257610e136133f6565b83156110cc57835f525f80516020615bac8339815191529081845260ff928360405f205416156110b357855f528285528360405f205460081c161561109a57855f5282855260405f209261ff0019938481541690555f80516020615b6c833981519152938454868160081c169182156110865761ff005f1980940160081b1691161785555f80516020615b2c8339815191528054926001600160401b03908a5f528952600193610ed88260018b60405f205460101c161b19831616928216831061342e565b6001600160401b03191617905588925f80516020615b4c8339815191528054928b5b848110610f8e575b5050505050509260409492610f4a8293610f3d7f697a3853515b88013ad432f29f53d406debc9509ed6d9313dcfe115250fcd18f999761342e565b610f45614a8a565b614fa0565b5460081c165f80516020615a8c8339815191529081548381168210610f80575b50505416908351928352820152a161093f613946565b60ff19161781555f80610f6a565b838c610f9983613224565b929054600393841b1c1614610fb057508501610efa565b9596509091938281019081116110725790610fde84610fd1610ffc94613224565b905490891b1c1691613224565b90919060018060a01b038084549260031b9316831b921b1916179055565b8254801561105e57946040999794610f4a948a9894610f3d947f697a3853515b88013ad432f29f53d406debc9509ed6d9313dcfe115250fcd18f9e9c99019261104484613224565b81939154921b1b1916905555949799849799839750610f02565b634e487b7160e01b8c52603160045260248cfd5b634e487b7160e01b8d52601160045260248dfd5b634e487b7160e01b8b52601160045260248bfd5b6040516307d86e9160e21b815260048101879052602490fd5b604051630d583f4760e41b815260048101879052602490fd5b604051632f44bd7760e01b8152600490fd5b5034610274576110ed36612d8b565b90335f525f80516020615bac83398151915260209080825260ff60405f205460081c16156112f3575f80516020615b0c8339815191529160028354146106c25761ffff8616805f525f80516020615a6c83398151915282528460405f2054036112d5575060405163b3f07bbd60e01b815291818380611170898b600484016147fa565b038173b55f857fc9a9757ffe70a3988f4a0b4f04f9d2a05af49283156112ca57889361129b575b50335f528082526111b260ff60405f205460101c1684613017565b61128257606061126193927f35a2101eaac94b493e0dfca061f9a7f087913fde8678e7cde0aca9897edba0e592335f528082528a6001600160401b03610100600160481b03604082600160ff835f205460101c161b16938981525f80516020615acc833981519152875220928354928360081c161760081b1690610100600160481b031916179055335f52815260ff60405f205460101c166040519185835233908301526040820152a1612e0c565b611269578480f35b546002146106c25761127a92613202565b5f8080808480f35b604051631089c4a160e11b815260048101849052602490fd5b9092508181813d83116112c3575b6112b38183612d09565b810103126105dd5751915f611197565b503d6112a9565b6040513d8a823e3d90fd5b6044908560405191635788c0fd60e11b835260048301526024820152fd5b60405163a0ae911d60e01b8152336004820152602490fd5b5034610274578060031936011261027457602060405161ffff7f000000000000000000000000000000000000000000000000000000000000001e168152f35b506020366003190112610274576001600160401b03600435166004350361027457611373613a00565b60025f80516020615b0c83398151915254146106c2576001600160401b03600435165f525f80516020615bcc83398151915260205260405f2090604051916113ba83612c9d565b805483526001810154602084015261ffff60028201546001600160481b03811660408601526001600160401b038160481c16606086015260881c16608084015260018060a01b0360038201541660a08401526040518281939060048401549361142285612e74565b80855294600181169081156115d3575060011461158e575b505061144892500382612d09565b60c08201526001600160401b036060820151161561156c576114776001600160401b0360608301511642612f6b565b6001600160401b037f00000000000000000000000000000000000000000000000000000000000151801611611536576115146020916001600160401b03600435165f525f80516020615bcc83398151915283526114d660405f2061318c565b6040810151608082015182518584015160a085015160c090950151946001600160a01b031693909261ffff16906001600160481b0316600435614273565b60015f80516020615bec833981519152556001600160401b0360405191168152f35b6001600160401b0360606044920151166040519063c06cf05f60e01b82526001600160401b036004351660048301526024820152fd5b6024604051635feafa3160e11b81526001600160401b03600435166004820152fd5b60049193949250018252602082205b8183106115b7575050906020611448928201015f8061143a565b602091935080600191548385880101520191019091839261159d565b9150506020925061144894915060ff191682840152151560051b8201015f8061143a565b5060603660031901126102745761160c612c33565b604435611617613a00565b60025f80516020615b0c83398151915254146106c25760209181611514926040519261164284612cd3565b60018452853681860137600435613d24565b50346102745760403660031901126102745761166e612c22565b6024356001600160401b0381116117cb5761168d903690600401612d45565b916040519182905f80516020615b4c8339815191528281549182875260208097019086525f80516020615aac83398151915292865b888282106117ac575050506116d992500383612d09565b826117038351966040519788928392635b10743960e11b8452604060048501526044840190612c65565b906024830152038173b55f857fc9a9757ffe70a3988f4a0b4f04f9d2a05af49081156117a15783949561173c949261177d575b50613bd6565b604051926040840160408552835180915285606086019401915b8181106117695750505082938301520390f35b825185529386019391860191600101611756565b61179a9192503d8087833e6117928183612d09565b8101906130a3565b905f611736565b6040513d85823e3d90fd5b85546001600160a01b03168452600195860195889550930192016116c2565b8280fd5b50346102745780600319360112610274576117e86139bc565b7ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a0080546001600160401b038082169060018201918183116118f85760ff8460401c169081156118eb575b506118d957600160401b911680926001600160481b03191617179081835560ff7f7487ca88d037ca20519908b1ee7556206bef53bce0226a348750cb9d4f688e4e5416156118c7577fc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d2926020926118a7613946565b6118af614a8a565b68ff000000000000000019169055604051908152a180f35b604051632866815360e11b8152600490fd5b60405163f92ee8a960e01b8152600490fd5b905081831611155f611832565b634e487b7160e01b5f52601160045260245ffd5b50346102745760403660031901126102745760243560ff811681036105dd57611939602091600435613017565b6040519015158152f35b50346102745780600319360112610274575f80516020615aec833981519152546040516001600160a01b039091168152602090f35b5034610274576020366003190112610274576119cb6001600160401b0360209260405f80516020615b2c833981519152549160043581525f80516020615acc8339815191528652205460081c1616613b86565b60ff60405191168152f35b50346102745780600319360112610274576119ef612f78565b506109c661098b612f96565b50346102745780600319360112610274575f80516020615aec83398151915254611a2d906001600160a01b03166133a4565b5f80516020615b0c83398151915260028154146106c257600290557f0e2fb031ee032dc02d8011dc50b816eb450cf856abd8261680dac74f72165bd2602060405160018152a180f35b503461027457602036600319011261027457600435611a93613a00565b60025f80516020615b0c83398151915254146106c257611ab281613268565b602081016001600160401b03908181511615611b7857611ad58282511642612f6b565b827f00000000000000000000000000000000000000000000000000000000000151801611611b56578385527f4e8909a01183a67951f5a6147d6e76ed02ea890c72afea01a9edee91edc609b860205260408086208681556001018690558301518351869161053c916001600160481b0316906001600160a01b031687613a2f565b516040516301cb739d60e71b8152600481019490945216602483015250604490fd5b604051630301bcaf60e61b815260048101859052602490fd5b508060031936011261027457611ba56139bc565b7ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a00805460ff8160401c1615906001600160401b03811680159081611dbb575b6001149081611db1575b159081611da8575b506118d95767ffffffffffffffff198116600117835581611d89575b50611c1b6152e7565b7f0000000000000000000000009e2b47acaf61ad2ff26b2608b9d915325c484ff16001600160a01b0381163303611d60575034611d4e57611c5a6152e7565b611c626152e7565b611c6a6152e7565b60015f80516020615b0c833981519152555f80516020615c0c83398151915280546001600160a01b03191633179055611ca16152e7565b611ca96152e7565b611cb2336148f9565b611cba6152e7565b611cc26152e7565b60015f80516020615bec83398151915255611cf8610100600160481b0360ff611cf1611cec612ee9565b614a52565b161761370e565b611d00613946565b611d08614a8a565b611d10575080f35b68ff00000000000000001981541690557fc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d2602060405160018152a180f35b60405163bd28e88960e01b8152600490fd5b604051636345072160e11b81526001600160a01b03919091166004820152336024820152604490fd5b68ffffffffffffffffff1916680100000000000000011782555f611c12565b9050155f611bf6565b303b159150611bee565b839150611be4565b503461027457608036600319011261027457611ddd612c22565b6024356044359060ff82168092036105dd57611df76133f6565b61ffff92838116938415611f22578215611f10578315611efe577f000000000000000000000000000000000000000000000000000000000000001e168414611eec577f1456404e7f41f35c3daac941bb50bad417a66275c3040061b4287d787719599d92608092855f5260ff5f80516020615a6c8339815191529384602052611ecf60405f209183600160405194611e8e86612cd3565b8054865201541696602084019788528a5f52602052600160405f2086815501868519825416179055611eca611ec1612ee9565b80606435613461565b6134ae565b51935116604051938452602084015260408301526060820152a280f35b60405163101b8f9560e11b8152600490fd5b60405163ade64f0b60e01b8152600490fd5b60405163f839a0cb60e01b8152600490fd5b60405163100b0f2760e11b8152600490fd5b503461027457806003193601126102745760206040516001600160401b037f0000000000000000000000000000000000000000000000000000000000015180168152f35b5034610274578060031936011261027457602060ff7f5443fea4dc453d96b81ce55b62e11a4094cc4cbb8a360956a7253cfdb42506cb54166040519015158152f35b50346102745780600319360112610274577f00000000000000000000000000000000000000000000000000000000000000019060028210156120045760208260ff60405191168152f35b634e487b7160e01b81526021600452602490fd5b50346102745780600319360112610274576120316133f6565b5f80516020615b0c833981519152600281540361207957600190557fe11c2112add17fb763d3bd59f63b10429c3e11373da4fb8ef6725107a2fdc4b06020604051838152a180f35b604051637e38d1d360e11b8152600490fd5b503461027457806003193601126102745760206119cb612ee9565b50346102745760203660031901126102745760ff604060209260043581525f80516020615acc83398151915284522054166040519015158152f35b50346102745780600319360112610274576040517f0000000000000000000000000000000000000000000000000000000000000001600281101561212757602092508152f35b634e487b7160e01b83526021600452602483fd5b503461027457806003193601126102745760206001600160401b037fad78307a8b51804c575f26039dcb87c58925afb3b7c08732f3b21b942aed7a765416604051908152f35b5034610274576020806003193601126106d4576004356001600160a01b03811691828203610803576121b16133f6565b82156110cc57825f525f80516020615bac8339815191529182825260ff908160405f2054165f1461234b57845f5283835260405f2061010061ff00198254161790555b5f80516020615b4c83398151915290815491600160401b8310156123375782610fde91600161222595019055613224565b5f80516020615b6c83398151915292835461ff00612247848360081c16613935565b60081b169061ff001916178094555f80516020615b2c83398151915280546001600160401b039081811691885f5284875260018660405f205460101c161b16821791821461231e5767ffffffffffffffff19161790557ff05962b5774c658e85ed80c91a75af9d66d2af2253dda480f90bce78aff5eda5946060949093909290916122d0614a8a565b845f528252805f80516020615a8c83398151915280548281161561230f575b5054169260405194855260081c16908301526040820152a161093f613946565b60ff191660011781555f6122ef565b604051638d68f84d60e01b815260048101899052602490fd5b634e487b7160e01b5f52604160045260245ffd5b5f80516020615b6c83398151915282815416604081101561245d576040519061237382612cb8565b60018252858201906001825260408301908152885f5287875260405f2092511515918662ff000061ff0086549351151560081b16935160101b1693169062ffffff191617171790558054836123c9818316613935565b169060ff19161790557f3031d39df71efbb605646fc51d7571499445af538fa6dd17ce8c07e8118ed978805490600160401b8210156123375760018201808255821015612449575f527f357eda4c1707ce60b55a439f3dc12fcacea5ca0fd863e2fc179a916cf05fccd10180546001600160a01b031916861790556121f4565b634e487b7160e01b5f52603260045260245ffd5b60405163891684c360e01b8152600490fd5b5034610274576020366003190112610274576004356001600160401b0381168091036106d457606060c06040516124a581612c9d565b84815284602082015284604082015284838201528460808201528460a082015201525f525f80516020615bcc83398151915260205260405f20604051906124eb82612c9d565b805482526001810154602083015261ffff60028201546001600160481b03811660408501526001600160401b038160481c16606085015260881c16608083015260018060a01b0360038201541660a08301526040518381949060048401549361255385612e74565b808552946001811690811561263a57506001146125f5575b505061257992500383612d09565b60c081019182526109c66040519283926020845280516020850152602081015160408501526001600160481b0360408201511660608501526001600160401b03606082015116608085015261ffff60808201511660a085015260a0600180821b039101511660c08401525160e080840152610100830190612c65565b60049193949250018252602082205b81831061261e575050906020612579928201015f8061256b565b6020919350806001915483858901015201910190918492612604565b9150506020925061257994915060ff191682840152151560051b8201015f8061256b565b5034610274576020366003190112610274576126786133f6565b61093f61268f612686612ee9565b80600435613461565b61370e565b50346102745760403660031901126102745761093f6126b1612c33565b6126b96133f6565b611eca612686612ee9565b50346105dd576020806003193601126105dd576001600160a01b03600435818116908181036105dd576126f56133f6565b6126fd6139bc565b3b15612ad0577f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc80546001600160a01b031916821790557fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b5f80a27f7487ca88d037ca20519908b1ee7556206bef53bce0226a348750cb9d4f688e4e9182549161278a60ff84161561342e565b60ff199283166001178455303b156105dd5760405163011fa75760e71b81525f8160048183305af180156105d257612abd575b5060405163689f90c360e01b81528281600481305afa908115612a85578691612a90575b5015612819575b50507f5443fea4dc453d96b81ce55b62e11a4094cc4cbb8a360956a7253cfdb42506cb818154169055815416905580f35b604051637e062a3560e11b81528281600481305afa908115612a85578691612a47575b508161286c927f0000000000000000000000008d58c0c60b8d6b88fa98b291a646db34d0f982581691161461342e565b6040516314ad290960e11b81528181600481305afa908115610807578591612a11575b507f00000000000000000000000000000000000000000000000000000000000000019060028210156129fd5760028110156129fd576128ce911461342e565b604051634d4502c960e11b81528181600481305afa80156108075785906129c7575b612923915061ffff807f000000000000000000000000000000000000000000000000000000000000001e1691161461342e565b604051631d2a9eff60e21b8152908082600481305afa908115610807578591612987575b5061298091506001600160401b03807f00000000000000000000000000000000000000000000000000000000000151801691161461342e565b5f806127e8565b905081813d83116129c0575b61299d8183612d09565b8101031261080357516001600160401b038116810361080357612980905f612947565b503d612993565b508181813d83116129f6575b6129dd8183612d09565b81010312610812576129f161292391615111565b6128f0565b503d6129d3565b634e487b7160e01b86526021600452602486fd5b90508181813d8311612a40575b612a288183612d09565b8101031261081257516002811015610812575f61288f565b503d612a1e565b90508281813d8311612a7e575b612a5e8183612d09565b81010312612a7a5751908082168203612a7a579061286c61283c565b8580fd5b503d612a54565b6040513d88823e3d90fd5b612ab09150833d8511612ab6575b612aa88183612d09565b810190613449565b5f6127e1565b503d612a9e565b612ac8919550612c8a565b5f935f6127bd565b60405162461bcd60e51b815260048101849052602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201526c1bdd08184818dbdb9d1c9858dd609a1b6064820152608490fd5b346105dd5760203660031901126105dd576020611939600435612e0c565b346105dd5760203660031901126105dd576004356001600160a01b03818116918290036105dd57612b89815f80516020615aec83398151915254166133a4565b5f80516020615c0c83398151915280546001600160a01b031981168417909155167f51c4874e0f23f262e04a38c51751336dde72126d67f53eb672aaff02996b3ef65f80a3005b346105dd5760203660031901126105dd5761ffff612bec612c22565b612bf4612f78565b50165f525f80516020615b8c83398151915260205260206106f3610468612c1d60405f20612fdd565b6132fa565b6004359061ffff821682036105dd57565b6024359061ffff821682036105dd57565b5f5b838110612c555750505f910152565b8181015183820152602001612c46565b90602091612c7e81518092818552858086019101612c44565b601f01601f1916010190565b6001600160401b03811161233757604052565b60e081019081106001600160401b0382111761233757604052565b606081019081106001600160401b0382111761233757604052565b604081019081106001600160401b0382111761233757604052565b60a081019081106001600160401b0382111761233757604052565b90601f801991011681019081106001600160401b0382111761233757604052565b6001600160401b03811161233757601f01601f191660200190565b81601f820112156105dd57803590612d5c82612d2a565b92612d6a6040519485612d09565b828452602083830101116105dd57815f926020809301838601378301015290565b90600319906060828401126105dd5760043561ffff811681036105dd579260243592604435916001600160401b03918284116105dd5760609084830301126105dd5760405192612dda84612cb8565b806004013584526024810135602085015260448101359283116105dd57612e049201600401612d45565b604082015290565b6001600160401b039060ff612e60815f80516020615a8c83398151915254169384935f80516020615b2c83398151915254905f525f80516020615acc83398151915260205260405f205460081c1616613b86565b1610159081612e6d575090565b9050151590565b90600182811c92168015612ea2575b6020831014612e8e57565b634e487b7160e01b5f52602260045260245ffd5b91607f1691612e83565b3d15612ed6573d90612ebd82612d2a565b91612ecb6040519384612d09565b82523d5f602084013e565b606090565b519060ff821682036105dd57565b5f80604051602081019063313ce56760e01b825260048152612f0a81612cd3565b51907f0000000000000000000000008d58c0c60b8d6b88fa98b291a646db34d0f982585afa612f37612eac565b9015612f59576020818051810103126105dd576020612f569101612edb565b90565b604051631222cd8360e01b8152600490fd5b919082039182116118f857565b60405190612f8582612cb8565b5f6040838281528260208201520152565b60405190612fa382612cb8565b8160406001600160401b035f80516020615c2c833981519152546001600160481b0380821685528160481c16602085015260901c16910152565b90604051612fea81612cb8565b60406001600160401b038294546001600160481b0380821685528160481c16602085015260901c16910152565b906001600160401b03915f525f80516020615acc833981519152602052600160ff60405f205460081c92161b1616151590565b6001600160401b0381116123375760051b60200190565b81601f820112156105dd57805161307781612d2a565b926130856040519485612d09565b818452602082840101116105dd57612f569160208085019101612c44565b9060209081838203126105dd5782516001600160401b03938482116105dd57019080601f830112156105dd5781516130da8161304a565b946040906130eb6040519788612d09565b828752858088019360051b860101948486116105dd57868101935b86851061311857505050505050505090565b84518381116105dd5782019084601f1983890301126105dd5784519061313d82612cd3565b6131488a8401612edb565b825285830151918583116105dd57613167898c80969581960101613061565b83820152815201940193613106565b818110613181575050565b5f8155600101613176565b6004905f81555f60018201555f60028201555f6003820155016131af8154612e74565b90816131b9575050565b81601f5f93116001146131cb5750555b565b9080839182526131ea601f60208420940160051c840160018501613176565b5555565b80518210156124495760209160051b010190565b91908161320f9184614815565b91909161321f576131c992615120565b505050565b5f80516020615b4c8339815191528054821015612449575f525f80516020615aac83398151915201905f90565b613259612f78565b50612f56610468612c1d612f96565b613270612f78565b505f527f4e8909a01183a67951f5a6147d6e76ed02ea890c72afea01a9edee91edc609b860205260405f20604051906132a882612cb8565b80546001600160481b038116835260481c6001600160401b03166020830152600101546001600160a01b0316604082015290565b81156132e6570490565b634e487b7160e01b5f52601260045260245ffd5b6001600160401b0390817f00000000000000000000000000000000000000000000000000000000000151801691821561338d5761337a828260ff936040610100600160481b039601511642038161335f602085019889519383875160081c16026132dc565b9160081c1601915160081c168082105f14613386575061496a565b9251169160081b161790565b905061496a565b506020015160ff16610100600160481b0317919050565b5f80516020615c0c83398151915254336001600160a01b0391821614159190826133e9575b50506133d157565b60405163e2a08e5d60e01b8152336004820152602490fd5b1633141590505f806133c9565b5f80516020615aec833981519152546001600160a01b0316330361341657565b60405163118cdaa760e01b8152336004820152602490fd5b1561343557565b634e487b7160e01b5f52600160045260245ffd5b908160209103126105dd575180151581036105dd5790565b61349961349460ff92610100600160481b03949561347e87614a52565b9085811686831610156134a457509586916149f7565b61496a565b92169160081b161790565b90509586916149f7565b9061ffff1690815f525f80516020615b8c83398151915260205260405f2080546134d6612ee9565b916008916001600160401b039181841c831691906001600160481b03828116841580613703575b156135b35750866040979460ff8a989561359286613599966135447f739ed886fd81a3ddc9f4b327ab69152e513cd45b26fda0c73660eaca8e1193019f6135a69d9a614a64565b815467ffffffffffffffff60901b19918e169190911679ffffffffffffffff000000000000000000ffffffffffffffffff199091161742891660901b67ffffffffffffffff60901b16179055565b16906149f7565b9460ff8116921c166149f7565b82519182526020820152a2565b6135bf612c1d84612fdd565b90896135cb818361579a565b156136b2576135d99161599d565b6135e7868a891c1686613b6d565b86610100600160481b03918260ff8816918b1b1617613606818561579a565b156136a75760ff918161361c613629938761599d565b8b1c1689858c1c16613b6d565b921691881b16175b61363b898261579a565b6136855796809460ff7f739ed886fd81a3ddc9f4b327ab69152e513cd45b26fda0c73660eaca8e1193019a9895613592866135999661368060409e6135a69d9a614a64565b613544565b604051631e74e8fb60e31b815290821660048201529088166024820152604490fd5b50505060ff16613631565b906136bc9161599d565b6136ca85878b8a1c16613b6d565b60ff8a1691878084610100600160481b0380958d1b16176136eb818561599d565b8b1c16918a1c16018781116118f857881b1617613631565b5060ff8416156134fd565b5f80516020615c2c8339815191528054613726612ee9565b916008916001600160401b039181841c831691906001600160481b0382811684158061392a575b156137f65750866040979460ff7f7e3b0fc388be9d36273f66210aed83be975df3a9adfffa4c734033f498f362cd9a989585613599956137e99a9754600160481b600160901b038d60481b1690600160481b600160901b0319161782555b815479ffffffffffffffff000000000000000000ffffffffffffffffff1916908c16174260901b67ffffffffffffffff60901b1617905516906149f7565b82519182526020820152a1565b613801612c1d612f96565b908961380d818361579a565b156138d95761381b9161599d565b613829868a891c1686613b6d565b86610100600160481b03918260ff8816918b1b1617613848818561579a565b156138ce5760ff918161361c61385e938761599d565b921691881b16175b613870898261579a565b6136855796809460ff7f7e3b0fc388be9d36273f66210aed83be975df3a9adfffa4c734033f498f362cd9a98956137e9989561359995600160481b600160901b0360409d60481b16600160481b600160901b031984161782556137ab565b50505060ff16613866565b906138e39161599d565b6138f185878b8a1c16613b6d565b60ff8a1691878084610100600160481b0380958d1b1617613912818561599d565b8b1c16918a1c16018781116118f857881b1617613866565b5060ff84161561374d565b60ff1660ff81146118f85760010190565b60ff5f80516020615a8c833981519152541660405161396481612cd3565b60ff5f80516020615b6c83398151915254818116835260081c1680602083015280831161399e57505160ff166139975750565b156108fe57565b82604491604051916313c3d1b160e01b835260048301526024820152fd5b307f00000000000000000000000086c5ae628e2218c5597b3e6dce73048adc53fcc56001600160a01b0316146139ee57565b604051633c64f99360e21b8152600490fd5b5f80516020615bec8339815191526002815414613a1d5760029055565b604051633ee5aeb560e01b8152600490fd5b91613a5d906104687f0000000000000000000000000000000000000000000000000000000000002105614b63565b917f504e6efe18ab9eed10dc6501a417f5b12a2f7f2b1593aed9b89f9bce3cf29a915f80a27f000000000000000000000000000000000000000000000000000000000000000160028110156105fd5780613aeb575060405163a9059cbb60e01b60208201526001600160a01b03909116602482015260448101919091526131c99061050d81606481016104ff565b600181036105e157507f0000000000000000000000008d58c0c60b8d6b88fa98b291a646db34d0f982586001600160a01b031691823b156105dd576040516340c10f1960e01b81526001600160a01b039290921660048301526024820152905f908290604490829084905af180156105d257613b645750565b6131c990612c8a565b6001600160401b0391821690821603919082116118f857565b905f915b6001600160401b03808216801561321f575f19019081116118f857613bb0911692613935565b91613b8a565b9060406020612f569360ff81511684520151918160208201520190612c65565b909291805191613be58361304a565b92604091613bf66040519586612d09565b818552613c028261304a565b602090601f190136878301375f975f955b848710613c2557505050505050509190565b909192939495988685613c9b868d613c4460018060a01b0391886131ee565b5116805f525f80516020615bac8339815191528252613c6c60ff865f205460101c16896131ee565b51908551808095819463b5634c7360e01b835261ffff60049916898401526024998a8401526044830190613bb6565b03915afa908115613d1a578d905f92613ce8575b50613cbb82918d6131ee565b528301809311613cd75750506001909901959493929190613c13565b601190634e487b7160e01b5f52525ffd5b809250888092503d8311613d13575b613d018183612d09565b810103126105dd57518c613cbb613caf565b503d613cf7565b8a513d5f823e3d90fd5b91939290935f948315613fc8578115613fb6578215613fa4577f0000000000000000000000008d58c0c60b8d6b88fa98b291a646db34d0f9825895613d693088614b8b565b60018060a01b03881690604098613dae8a516323b872dd60e01b6020820152602499338b830152306044830152606482015260648152613da881612cee565b84615328565b613dc182613dbc3084614b8b565b612f6b565b927f00000000000000000000000000000000000000000000000000000000000000016002811015613f9157600114613f0f575b50505061ffff83165f525f80516020615a6c83398151915260205260ff6001895f200154168015613efe57613e32613e2a612ee9565b918284613461565b98613e4e6001600160401b039260ff8c16848d60081c166149f7565b808403613ed85750507fad78307a8b51804c575f26039dcb87c58925afb3b7c08732f3b21b942aed7a769081549080821698818a14613ec65750938787878b968e968e96613eae9a60018b0116906001600160401b031916179055614be7565b613ebd57612f56953394614273565b50505091505090565b634e487b7160e01b8652601160045285fd5b60449189613ee7869384612f6b565b9151926338f831a560e11b84526004840152820152fd5b885163ade64f0b60e01b8152600490fd5b803b156105dd575f80918a8d5180948193630852cd8d60e31b83528960048401525af18015613f8757613f72575b50613f49903090614b8b565b808203613f565780613df4565b60449250878a51926302156a8f60e01b84526004840152820152fd5b613f7d919450612c8a565b5f92613f49613f3d565b8b513d5f823e3d90fd5b89634e487b7160e01b5f5260216004525ffd5b60405163717f139360e11b8152600490fd5b604051634e46966960e11b8152600490fd5b604051631f2a200560e01b8152600490fd5b94939291905f938615613fc8578215613fb6578315613fa4577f0000000000000000000000008d58c0c60b8d6b88fa98b291a646db34d0f982589661401f3089614b8b565b9060018060a01b038916916040996140658b516323b872dd60e01b6020820152602494338683015230604483015260648201526064815261405f81612cee565b85615328565b61407382613dbc3084614b8b565b937f0000000000000000000000000000000000000000000000000000000000000001600281101561421457600114614194575b50505061ffff84165f525f80516020615a6c83398151915260205260ff60018a5f20015416908115614183576140e56140dd612ee9565b928385613461565b996141026001600160401b03938c8560ff82169160081c166149f7565b8085036141745750507fad78307a8b51804c575f26039dcb87c58925afb3b7c08732f3b21b942aed7a769182549181831699828b14614163575050938787878b968e968e96613eae9a60018b0116906001600160401b031916179055614be7565b634e487b7160e01b81526011600452fd5b90604492613ee7869384612f6b565b895163ade64f0b60e01b8152600490fd5b803b156105dd575f8091858e5180948193630852cd8d60e31b83528a60048401525af1801561420a576141f5575b506141ce903090614b8b565b8082036141db57806140a6565b6044928b51926302156a8f60e01b84526004840152820152fd5b614200919950612c8a565b5f976141ce6141c2565b8c513d5f823e3d90fd5b84634e487b7160e01b5f5260216004525ffd5b906020828203126105dd5781516001600160401b0381116105dd57612f569201613061565b9060606040612f569380518452602081015160208501520151918160408201520190612c65565b95919061429f7f0000000000000000000000000000000000000000000000000000000000002105614b63565b6040519283845f80516020615b4c833981519152602081549384815201905f525f80516020615aac833981519152925f5b8181106147d85750506142e592500385612d09565b7f3031d39df71efbb605646fc51d7571499445af538fa6dd17ce8c07e8118ed97854908451156147c6576143375f916040519384928392635b10743960e11b8452604060048501526044840190612c65565b906024830152038173b55f857fc9a9757ffe70a3988f4a0b4f04f9d2a05af49081156105d2575f916147ac575b50614370848285613bd6565b949085341061478d576143838634612f6b565b8061477e575b506060608060405161439a81612cee565b5f81525f60208201525f60408201525f838201520152604051986143bd8a612cee565b6001600160481b0385168a5260018060a01b037f0000000000000000000000008d58c0c60b8d6b88fa98b291a646db34d0f982581660208b01528760408b015261ffff861660608b0152604051998a60208101106001600160401b0360208d0111176123375760805f918c60206144979e01604052838152828201526040519c8d9283926315cfa3cb60e11b8452602060048501526001600160481b038151166024850152602081015160448501526040810151606485015261ffff6060820151166084850152015160a060a484015260c4830190612c65565b038173b55f857fc9a9757ffe70a3988f4a0b4f04f9d2a05af4998a156105d2576145139a5f928d928492614762575b506001600160401b03604051936144dc85612cb8565b16835260018060a01b031660208301526040820152604051809b81926311692f3760e31b835260206004840152602483019061424c565b038173b55f857fc9a9757ffe70a3988f4a0b4f04f9d2a05af49889156105d2575f9961473e575b5061ffff85165f525f80516020615a6c83398151915260205260405f2054928251928415614722575f5b84811061464f575050505050509161ffff6080926145a57fe54e51e42099622516fa3b48e9733581c9dbdcb771cafb093f745a0532a3598295610470612ee9565b9260405193845260208401521660408201526001600160401b0387166060820152a3604051614625602282602081019461ffff60f01b7f000000000000000000000000000000000000000000000000000000000000001e60f01b1686526146158151809260208686019101612c44565b8101036002810184520182612d09565b5190207f3e6ae56314c6da8b461d872f41c6d0bb69317b9d0232805aaccfa45df1a16fa05f80a290565b6001600160a01b0361466182846131ee565b51169061466e81866131ee565b51825f525f80516020615bac83398151915260205261469760ff60405f205460101c16866131ee565b51833b156105dd576146dc938f8f938d8c5f966146ee61ffff956040519b8c998a988997634b5b050560e01b895216600488015260a0602488015260a4870190613bb6565b85810360031901604487015290612c65565b916064840152608483015203925af19182156105d257600192614713575b5001614564565b61471c90612c8a565b5f61470c565b604051630ebc95af60e21b815261ffff88166004820152602490fd5b61475b9199503d805f833e6147538183612d09565b810190614227565b975f61453a565b6147779192503d8086833e6147538183612d09565b905f6144c6565b61478790615401565b5f614389565b6040516306a91e3760e51b815260048101879052346024820152604490fd5b6147c091503d805f833e6117928183612d09565b5f614364565b6040516334e7b19560e11b8152600490fd5b84546001600160a01b03168352600194850194899450602090930192016142d0565b60409061ffff612f569493168152816020820152019061424c565b60405163b3f07bbd60e01b81529193926020918391829161483a9190600484016147fa565b038173b55f857fc9a9757ffe70a3988f4a0b4f04f9d2a05af49081156105d2575f916148c7575b5061486b81612e0c565b156148af57614879816150dc565b9283614886575091505f90565b7f4069dff8c9df7e38d2867c0910bd96fd61787695e5380281148c04932d02bef25f80a35f9190565b60249060405190630451c4fb60e41b82526004820152fd5b90506020813d6020116148f1575b816148e260209383612d09565b810103126105dd57515f614861565b3d91506148d5565b6001600160a01b03908116908115614952575f80516020615aec83398151915280546001600160a01b031981168417909155167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e05f80a3565b604051631e4fbdf760e01b81525f6004820152602490fd5b6001600160401b039081811161497e571690565b60405162461bcd60e51b815260206004820152602660248201527f53616665436173743a2076616c756520646f65736e27742066697420696e203660448201526534206269747360d01b6064820152608490fd5b9060ff8091169116039060ff82116118f857565b60ff16604d81116118f857600a0a90565b919060ff821660ff8216818114614a4b571115614a2a57614a1f612f569392614a24926149d2565b6149e6565b906132dc565b614a1f90614a37926149d2565b908181029181830414901517156118f85790565b5050505090565b60ff811660081015612f565750600890565b90600160481b600160901b0382549160481b1690600160481b600160901b031916179055565b5f80516020615b6c8339815191525460ff8160081c16614ab95f80516020615b4c83398151915254821461342e565b5f5b818110614b3b57505f5b818110614ade575050604060ff6131c99216111561342e565b60018082018083116118f8575b838110614afc575050600101614ac5565b8190614b35614b0a85613224565b90546003916001600160a01b03919082614b2387613224565b905490861b1c16931b1c16141561342e565b01614aeb565b80614b5d614b4a600193613224565b848060a01b0391549060031b1c16614fa0565b01614abb565b468103614b6d5750565b604490604051906377d879fb60e01b82526004820152466024820152fd5b6040516370a0823160e01b602082019081526001600160a01b0390931660248083019190915281525f92839291614bc181612cb8565b51915afa614bcd612eac565b9015612f59576020818051810103126105dd576020015190565b9293949095979691614bfa611cec612ee9565b9889610100600160481b0360ff614c256134946001600160401b039e8f848816908860081c166149f7565b60081b91909116911617967f00000000000000000000000000000000000000000000000000000000000151808b1615614f9a57614c60612f78565b50614c6c612c1d612f96565b614c76898261599d565b8b808a60081c169160081c16105b811580614f93575b614f6d5781614f65575b50614cb957505050505050614cb5929350614cb081615432565b6154f1565b5f90565b60049293949650614cec9795977f0000000000000000000000000000000000000000000000000000000000002105614b63565b614cf4613251565b956040958b87519116978882526020998a830152878201527ff33512b84e24a49905c26c6991942fc5a9652411769fc1e448f967cdb049f08a60603392a2855192614d3e84612c9d565b8352878301988952858301906001600160481b038093168252614de28c60608601814216815261ffff608088019416845260a087019533875260c08801998a528b5f525f80516020615bcc8339815191528d528a5f20975188556001809e5190890155600288019551166001600160481b03198654161785555116839067ffffffffffffffff60481b82549160481b169067ffffffffffffffff60481b1916179055565b51815461ffff60881b191660889190911b61ffff60881b16179055516003820180546001600160a01b0319166001600160a01b0392909216919091179055915180519098919092019190811161233757614e3c8254612e74565b601f8111614f2c575b5084601f8211600114614eab5781907f69add1952a6a6b9cb86f04d05f0cb605cbb469a50ae916139d34495a9991481f9798995f92614ea0575b50505f19600383901b1c191690871b1790555b51908152a1612f5634615401565b015190505f80614e7f565b601f19821698835f52865f20995f5b818110614f1757509188999a91847f69add1952a6a6b9cb86f04d05f0cb605cbb469a50ae916139d34495a9991481f9a959410614eff575b505050811b019055614e92565b01515f1960f88460031b161c191690555f8080614ef2565b828401518c559a89019a928801928801614eba565b614f5590835f52865f20601f840160051c810191888510614f5b575b601f0160051c0190613176565b5f614e45565b9091508190614f48565b90505f614c96565b604487614f78613251565b90604051916326fb55dd60e01b835260048301526024820152fd5b5080614c8c565b5f614c84565b9060018060a01b0380921691825f525f80516020615bac83398151915260205260405f2060405190614fd182612cb8565b5460ff9161500d838316158015938484526020840193604087808460081c1615938415885260101c16910195818752926150c2575b505061342e565b5f80516020615b2c83398151915254956001600160401b036001976001868651161b1616151591511515915f915f905f80516020615b6c8339815191525497878960081c16925b83811061508a575b505050506131c99697509161508091615078828796951461342e565b15151461342e565b511691161161342e565b828261509583613224565b90549060031b1c16146150a9578b01615054565b5098998a9950935082915061507890508461508061505c565b909150816150d3575b505f80615006565b9050155f6150cb565b5f525f80516020615acc83398151915260205260405f20805460ff811661510a5760ff191660011790555f90565b5050600190565b519061ffff821682036105dd57565b61514c915f604080920151825180958192635399ded560e11b8352602060048401526024830190612c65565b038173b55f857fc9a9757ffe70a3988f4a0b4f04f9d2a05af49283156152dd575f9361523c575b5061ffff80606085015116907f000000000000000000000000000000000000000000000000000000000000001e16808203615221575050806151d86151b6612ee9565b806151d38188516001600160401b0360ff82169160081c166149f7565b613461565b930151908160a01c61520a57506001600160a01b0316906151fd908290849086615617565b61321f576131c992613a2f565b60249250519063033b960d60e41b82526004820152fd5b6044925191631ee5902560e11b835260048301526024820152fd5b9092503d805f833e61524e8183612d09565b81016020828203126105dd5781516001600160401b03928382116105dd57019060a0828203126105dd5784519261528484612cee565b82516001600160481b03811681036105dd5784526020830151602085015285830151868501526152b660608401615111565b606085015260808301519081116105dd576152d19201613061565b6080820152915f615173565b50513d5f823e3d90fd5b60ff7ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a005460401c161561531657565b604051631afcd79f60e31b8152600490fd5b604051615385916001600160a01b031661534182612cd3565b5f806020958685527f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c656487860152868151910182855af161537f612eac565b916159d2565b8051908161539257505050565b82806153a2938301019101613449565b156153aa5750565b6084906040519062461bcd60e51b82526004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b6064820152fd5b5f80808084335af1615411612eac565b501561541a5750565b60249060405190630b288dc560e21b82526004820152fd5b6001600160401b0390817f000000000000000000000000000000000000000000000000000000000001518016156154ed5761546b612f78565b50600160481b600160901b03615482612c1d612f96565b610100600160481b0360ff6154bc5f80516020615c2c83398151915296808854976154ad818861599d565b60081c16908560081c16613b6d565b92169160081b161760481b16906001600160401b0360901b4260901b1690600160481b600160d01b03191617179055565b5050565b6001600160401b03807f0000000000000000000000000000000000000000000000000000000000015180161561321f5761ffff6131c993615530612f78565b5016805f525f80516020615b8c83398151915280602052615556612c1d60405f20612fdd565b5f9283526020919091526040909120805467ffffffffffffffff60901b191642841660901b67ffffffffffffffff60901b16178155928290615598818461599d565b60081c16828260081c16018281115f146156035750610100600160481b0360ff6155c18461496a565b92169160081b161790825490806001600160481b038316926155e3848661599d565b60081c16908360081c16105f146155fb575090614a64565b905090614a64565b60ff6155c1610100600160481b039261496a565b90926001600160401b037f000000000000000000000000000000000000000000000000000000000001518081161561579457615651612f78565b5061ffff85165f525f80516020615b8c833981519152602052615679612c1d60405f20612fdd565b615683858261599d565b81808660081c169160081c16105b6156aa575050506156a5614cb592826157bc565b615880565b7f7f63c9251d82a933210c2b6d0b0f116252c3c116788120e64e8e8215df6f316294509060016020949261576e604051916156e483612cb8565b6001600160481b03958616835242811688840190815260a085901b85900395861660408086019182525f8a81527f4e8909a01183a67951f5a6147d6e76ed02ea890c72afea01a9edee91edc609b88c522094518554925170ffffffffffffffffffffffffffffffffff19909316981697909717911660481b67ffffffffffffffff60481b16178255565b019151166bffffffffffffffffffffffff60a01b825416179055604051908152a1600190565b5f615691565b906157a5818361599d565b6001600160401b03809160081c169160081c161190565b6001600160401b03807f0000000000000000000000000000000000000000000000000000000000015180161561321f57610100600160481b0360ff61587261ffff6131c996615809612f78565b501693845f525f80516020615b8c83398151915280602052615830612c1d60405f20612fdd565b5f9687526020919091526040909520805467ffffffffffffffff60901b191642831660901b67ffffffffffffffff60901b161781559581906154ad818861599d565b92169160081b161790614a64565b6001600160401b0390817f000000000000000000000000000000000000000000000000000000000001518016156154ed576158b9612f78565b506158c5612c1d612f96565b90600160481b600160901b035f80516020615c2c83398151915293845493816001600160401b0360901b4260901b16946158ff818461599d565b60081c16828260081c16018281115f146159895750610100600160481b0360ff6159288461496a565b92169160081b1617906001600160481b03851690615946828461599d565b80856001600160401b0360901b1988161760081c16908360081c16105f1461598257505b60481b1691600160481b600160d01b03191617179055565b905061596a565b60ff615928610100600160481b039261496a565b60ff91821691168181036159af575050565b604051635ce6db6160e11b815260ff918216600482015291166024820152604490fd5b91929015615a3457508151156159e6575090565b3b156159ef5790565b60405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606490fd5b825190915015615a475750805190602001fd5b60405162461bcd60e51b81526020600482015290819061063a906024830190612c6556feebcc9f646b0f459ff8f387587d536b0af3484cf442e1577400f322334e7d1ef047028352a8b3feae1a85fba43bc13f990568bb1637dce33d3dbfd791a0808b7f6c3cb3f3ae91330f31ba2bc0ff8855fc834fb66dc27e8e0b1a398617dabaa5a668dfeeddfa5e4e9adceec01a3aba274bdcbab3f6ac9956417a4332f2b08abdda9016d09d72d40fdae2fd8ceac6b6234c7706214fd39c1cd1e609a0528c19930064bacf405c5d7f563d3ba5252584a52c37e4fee380fd825b10666c27b8258022fd6568c039679b3b7cc93c26c41d9379b7b1bec1677120493b467688302cb11f00758a264b9bdbe3295fe36bd6ff7abaa122f48bf70e90af04a1b8a32d21e4e18561949d1c6242cee5c5a5aeb6b9c190ee611d7742fcec65d9e5b1341ea04d89efb21dcaedea63b55c44882f329622e13a8d0f5b947b3a372826208a9003da1549bca747e973430e858f2f5de357b8dba36ea6d375b81bdb5d53dfaabf0b3a7f852fa0677fef8612c6c15b518c9fa56761e9ed15cfd5c6e5399e5467985ac7ed9b779b17422d0df92223018b32b4d1fa46e071723d6817e2486d003becc55f00bfa91572ce1e5fe8776a160d3b1f862e83f5ee2c080a7423b4761602a3ad12497c25289a27ec8c9be54d4a154cf80490d69bda989cdb8328232e08fea9220420a264697066735822122085ac4db53de6930db3b039184653fb7a750b8e542da7aa92d1612cd0e41b416f64736f6c63430008160033","optimization_enabled":true,"verified_twin_address_hash":null,"is_verified":true,"compiler_settings":{"evmVersion":"shanghai","libraries":{"lib/native-token-transfers/evm/src/libraries/TransceiverStructs.sol":{"TransceiverStructs":"0xB55F857FC9A9757FFe70A3988F4a0b4F04F9D2a0"}},"metadata":{"appendCBOR":true,"bytecodeHash":"ipfs","useLiteralContent":false},"optimizer":{"enabled":true,"runs":200},"outputSelection":{"*":{"":["*"],"*":["*"]}},"remappings":["@openzeppelin/contracts/=lib/openzeppelin-contracts/contracts/","create3-factory/=lib/create3-factory/","ds-test/=lib/solmate/lib/ds-test/src/","erc4626-tests/=lib/openzeppelin-contracts/lib/erc4626-tests/","forge-std/=lib/forge-std/src/","halmos-cheatcodes/=lib/openzeppelin-contracts/lib/halmos-cheatcodes/src/","native-token-transfers/=lib/native-token-transfers/evm/src/","solidity-bytes-utils/=lib/native-token-transfers/evm/lib/solidity-bytes-utils/contracts/","solmate/=lib/solmate/src/","wormhole-solidity-sdk/=lib/native-token-transfers/evm/lib/wormhole-solidity-sdk/src/","openzeppelin-contracts/=lib/native-token-transfers/evm/lib/openzeppelin-contracts/"],"viaIR":true},"optimization_runs":200,"sourcify_repo_url":null,"decoded_constructor_args":[["0x8d58C0C60B8D6b88Fa98B291a646dB34d0F98258",{"internalType":"address","name":"_token","type":"address"}],["1",{"internalType":"enum IManagerBase.Mode","name":"_mode","type":"uint8"}],["30",{"internalType":"uint16","name":"_chainId","type":"uint16"}],["86400",{"internalType":"uint64","name":"_rateLimitDuration","type":"uint64"}],["false",{"internalType":"bool","name":"_skipRateLimiting","type":"bool"}]],"compiler_version":"v0.8.22+commit.4fc1097e","is_verified_via_verifier_alliance":false,"verified_at":"2026-09-24T02:23:37.376241Z","implementations":[],"proxy_type":null,"external_libraries":[{"name":"lib/native-token-transfers/evm/src/libraries/TransceiverStructs.sol:TransceiverStructs","address_hash":"0xB55F857FC9A9757FFe70A3988F4a0b4F04F9D2a0"}],"creation_bytecode":"0x61016034620005a757601f6200629338819003918201601f19168301916001600160401b038311848410176200055c5780849260a094604052833981010312620005a7578051906001600160a01b0382168203620005a7576020810151916002831015620005a75760408201519161ffff83168303620005a7576060810151906001600160401b03821690818303620005a7576080015180159182158203620005a757158092816200059e575b50821562000582575b505062000570576080527f8561949d1c6242cee5c5a5aeb6b9c190ee611d7742fcec65d9e5b1341ea04d8954620001147e758a264b9bdbe3295fe36bd6ff7abaa122f48bf70e90af04a1b8a32d21e4e15460ff8360081c1614620005ab565b7ffd6568c039679b3b7cc93c26c41d9379b7b1bec1677120493b467688302cb11f545f5b60ff8360081c168110620003d95750505f5b60ff8260081c168110620003545750604060ff6200016b92161115620005ab565b7ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a00805460ff8160401c1662000342576002600160401b03196001600160401b03821601620002f6575b50503060a05260c0526101009182526101209081526101404681523360e05260405191615c81938462000612853960805184818161148101528181611ad801528181611f54015281816129580152818161330601528181614c320152818161543e015281816154fc01528181615623015281816157c7015261588c015260a051846139bf015260c05184818161028d0152818161050f0152818161055b0152818161284401528181612f0e01528181613af601528181613d3f01528181613ff501526143d2015260e05184611c1d0152518381816104a601528181611fcd015281816120f70152818161289201528181613a8401528181613dc4015261407601525182818161132601528181611e13015281816128fb015281816145dd015261518101525181818161044401528181613a390152818161427b0152614cc80152f35b6001600160401b0319166001600160401b039081179091556040519081527fc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d290602090a15f80620001b4565b60405163f92ee8a960e01b8152600490fd5b6001808201808311620003c5575b60ff8460081c1681106200037b5750506001016200014a565b8190620003be6200038c85620005c7565b90546003906200039c85620005c7565b60018060a01b03915490841b1c169260018060a01b03921b1c161415620005ab565b0162000362565b634e487b7160e01b5f52601160045260245ffd5b620003e481620005c7565b9054600382901b81901c6001600160a01b03165f9081527f49bca747e973430e858f2f5de357b8dba36ea6d375b81bdb5d53dfaabf0b3a7f60205260409081902090519291906001600160401b0360608501908111908511176200055c5760608401604052546200048660ff821615801592838752602087019360ff808360081c1615928315875260101c16908160408a0152926200053f575b5050620005ab565b60018060401b03600160ff6040870151161b871616151590511515925f925f5b60ff8a60081c168110620004f5575b505050826001959492620004d3620004ee95620004dc9414620005ab565b151514620005ab565b60ff60408188169201511610620005ab565b0162000138565b6200050081620005c7565b9054600391821b1c6001600160a01b039081169185901b84901c16146200052a57600101620004a6565b5060019350849150829050620004d3620004b5565b9091508162000552575b505f806200047e565b9050155f62000549565b634e487b7160e01b5f52604160045260245ffd5b60405163e543ef0560e01b8152600490fd5b1591508162000595575b505f80620000b5565b90505f6200058c565b92505f620000ac565b5f80fd5b15620005b357565b634e487b7160e01b5f52600160045260245ffd5b7e758a264b9bdbe3295fe36bd6ff7abaa122f48bf70e90af04a1b8a32d21e4e18054821015620005fd575f5260205f2001905f90565b634e487b7160e01b5f52603260045260245ffdfe60806040526004361015610011575f80fd5b5f803560e01c80630271725014612bd0578063036de8af14612b495780630677df5414612b2b5780630900f010146126c4578063186ce61214612694578063190171751461265e5780631f97c9a81461246f578063203e4a9b1461218157806323d75e311461213b578063295a5212146120e1578063396c16b7146120a65780633b97e8561461208b5780633f4ba83a146120185780634b4fd03b14611fba578063689f90c314611f7857806374aa7bfc14611f345780637c91863414611dc35780638129fc1c14611b915780638413bcba14611a765780638456cb59146119fb57806386e11ffa146119d657806389c619dd146119785780638da5cb5b146119435780638e3ba8c91461190c5780638fd3ab80146117cf5780639057412d14611654578063961b94d0146115f757806397c351461461134a5780639a8a05921461130b5780639d782454146110de5780639f86029c14610de15780639fd0506d14610dac578063b150fc5514610c09578063b187bd2614610bdc578063b293f97f14610b48578063b4d591bb14610a89578063c0b07bde14610a43578063c128d170146109ca578063d788c14714610942578063da4856a114610910578063e5a9860314610865578063e75235b814610838578063f2fde38b146106fb578063f5cfec18146106d8578063f7514fbc146102bc578063fc0c546a146102775763fd96063c1461021f575f80fd5b3461027457602036600319011261027457606061023d600435613268565b6040805182516001600160481b031681526020808401516001600160401b031690820152918101516001600160a01b031690820152f35b80fd5b50346102745780600319360112610274576040517f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03168152602090f35b5034610274576020366003190112610274576004356001600160401b03811681036106d4576102e9613a00565b60025f80516020615b0c83398151915254146106c2576001600160401b0381165f525f80516020615bcc83398151915260205260405f206040519061032d82612c9d565b8054825260046001916001810154602085015261ffff60028201546001600160481b03811660408701526001600160401b038160481c16606087015260881c16608085015260018060a01b0360038201541660a0850152016040518092869083549361039885612e74565b808552946001811690811561069e575060011461065f575b50506103be92500382612d09565b60c08201526001600160401b036060820151161561063e5760a08101516001600160a01b03163381036106115750606061048760407ff80e572ae1b63e2449629b6c7d783add85c36473926f216077f17ee002bcfd07936001600160401b0386165f525f80516020615bcc83398151915260205261043d825f2061318c565b01516104687f0000000000000000000000000000000000000000000000000000000000000000614b63565b610470612ee9565b906001600160401b0360ff82169160081c166149f7565b926001600160401b0360405191168152336020820152836040820152a17f000000000000000000000000000000000000000000000000000000000000000060028110156105fd5780610550575060405163a9059cbb60e01b6020820152336024820152604481019190915261053c9061050d81606481015b03601f198101835282612d09565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316615328565b60015f80516020615bec8339815191525580f35b600181036105e157507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316803b156105dd576040516340c10f1960e01b815233600482015260248101929092525f908290604490829084905af180156105d2576105c3575b5061053c565b6105cc90612c8a565b5f6105bd565b6040513d5f823e3d90fd5b5f80fd5b6040516366001a8960e01b815260ff9091166004820152602490fd5b634e487b7160e01b5f52602160045260245ffd5b60405163ceb40a8560e01b81523360048201526001600160a01b03919091166024820152604490fd5b0390fd5b604051635feafa3160e11b81526001600160401b0383166004820152602490fd5b8852602088208892505b84831061068357506103be93505081016020015f806103b0565b81935090816020925483858901015201910190918492610669565b915050602092506103be94915060ff191682840152151560051b8201015f806103b0565b6040516309e3d0f360e11b8152600490fd5b5080fd5b503461027457806003193601126102745760206106f3613251565b604051908152f35b5034610274576020366003190112610274576001600160a01b03600435818116908181036108035761073c9061072f6133f6565b6107376133f6565b6148f9565b7f3031d39df71efbb605646fc51d7571499445af538fa6dd17ce8c07e8118ed97891825460ff5f80516020615b6c833981519152541680820361081a575050908391825b845481101561081657845f5281817f357eda4c1707ce60b55a439f3dc12fcacea5ca0fd863e2fc179a916cf05fccd1015416803b1561081257848091602460405180948193632c7b84dd60e11b83528960048401525af19081156108075785916107ef575b5050600101610780565b6107f890612c8a565b61080357835f6107e5565b8380fd5b6040513d87823e3d90fd5b8480fd5b8380f35b604492506040519163d2a13a2960e01b835260048301526024820152fd5b5034610274578060031936011261027457602060ff5f80516020615a8c8339815191525416604051908152f35b50346102745760203660031901126102745760043560ff8116908181036105dd5761088e6133f6565b81156108fe577f2a855b929b9a53c6fb5b5ed248b27e502b709c088e036a5aa17620c8fc5085a9916108f860ff925f80516020615a8c833981519152805493851985161790556108dc613946565b6040805160ff9490951684168552921660208401528291820190565b0390a180f35b60405163831761d760e01b8152600490fd5b50346102745761091f36612d8b565b9060025f80516020615b0c83398151915254146106c25761093f92613202565b80f35b50346102745760203660031901126102745761ffff61095f612c22565b610967612f78565b50165f525f80516020615b8c8339815191526020526109c661098b60405f20612fdd565b6040519182918291909160406001600160401b038160608401956001600160481b038082511686526020820151166020860152015116910152565b0390f35b50346102745760203660031901126102745761ffff906109e8612c22565b9060206040516109f781612cd3565b8281520152165f525f80516020615a6c8339815191526020526040805f2060ff8251610a2281612cd3565b60208260018554958685520154169101908152835192835251166020820152f35b50346102745780600319360112610274576109c6604051610a6381612cd3565b60058152640312e312e360dc1b6020820152604051918291602083526020830190612c65565b503461027457806003193601126102745760405180915f80516020615b4c833981519152908154808452602080940190819383525f80516020615aac83398151915290835b818110610b2b5750505084610ae4910385612d09565b60405193838594850191818652518092526040850193925b828110610b0b57505050500390f35b83516001600160a01b031685528695509381019392810192600101610afc565b82546001600160a01b031684529286019260019283019201610ace565b5060c036600319011261027457610b5d612c33565b906084359182151583036106d45760a4356001600160401b03928382116102745750610b8d903690600401612d45565b610b95613a00565b60025f80516020615b0c83398151915254146106c257602093610bc2926064359060443590600435613fda565b60015f80516020615bec8339815191525560405191168152f35b5034610274578060031936011261027457602060025f80516020615b0c8339815191525414604051908152f35b5034610274578060031936011261027457604051805f80516020615b4c833981519152805480845260208094019185525f80516020615aac83398151915290855b818110610d8f5750505081610c60910382612d09565b8051610c6b8161304a565b91610c796040519384612d09565b818352610c858261304a565b601f1901855b818110610d73575050845b828110610cf7575050506040519180830190808452825180925280604085019301945b828110610cc65784840385f35b85518051151585528083015115158584015260409081015160ff169085015294810194606090930192600101610cb9565b9294926001906001600160a01b03610d0f82856131ee565b51165f525f80516020615bac833981519152865260405f2060405190610d3482612cb8565b5460ff9081811615158352818160081c1615158984015260101c166040820152610d5e82896131ee565b52610d6981886131ee565b5001949294610c96565b8590610d80979597612f78565b82828a01015201959395610c8b565b82546001600160a01b031684529285019260019283019201610c4a565b50346102745780600319360112610274575f80516020615c0c833981519152546040516001600160a01b039091168152602090f35b5034610274576020806003193601126106d4576004356001600160a01b03818116929183810361081257610e136133f6565b83156110cc57835f525f80516020615bac8339815191529081845260ff928360405f205416156110b357855f528285528360405f205460081c161561109a57855f5282855260405f209261ff0019938481541690555f80516020615b6c833981519152938454868160081c169182156110865761ff005f1980940160081b1691161785555f80516020615b2c8339815191528054926001600160401b03908a5f528952600193610ed88260018b60405f205460101c161b19831616928216831061342e565b6001600160401b03191617905588925f80516020615b4c8339815191528054928b5b848110610f8e575b5050505050509260409492610f4a8293610f3d7f697a3853515b88013ad432f29f53d406debc9509ed6d9313dcfe115250fcd18f999761342e565b610f45614a8a565b614fa0565b5460081c165f80516020615a8c8339815191529081548381168210610f80575b50505416908351928352820152a161093f613946565b60ff19161781555f80610f6a565b838c610f9983613224565b929054600393841b1c1614610fb057508501610efa565b9596509091938281019081116110725790610fde84610fd1610ffc94613224565b905490891b1c1691613224565b90919060018060a01b038084549260031b9316831b921b1916179055565b8254801561105e57946040999794610f4a948a9894610f3d947f697a3853515b88013ad432f29f53d406debc9509ed6d9313dcfe115250fcd18f9e9c99019261104484613224565b81939154921b1b1916905555949799849799839750610f02565b634e487b7160e01b8c52603160045260248cfd5b634e487b7160e01b8d52601160045260248dfd5b634e487b7160e01b8b52601160045260248bfd5b6040516307d86e9160e21b815260048101879052602490fd5b604051630d583f4760e41b815260048101879052602490fd5b604051632f44bd7760e01b8152600490fd5b5034610274576110ed36612d8b565b90335f525f80516020615bac83398151915260209080825260ff60405f205460081c16156112f3575f80516020615b0c8339815191529160028354146106c25761ffff8616805f525f80516020615a6c83398151915282528460405f2054036112d5575060405163b3f07bbd60e01b815291818380611170898b600484016147fa565b038173b55f857fc9a9757ffe70a3988f4a0b4f04f9d2a05af49283156112ca57889361129b575b50335f528082526111b260ff60405f205460101c1684613017565b61128257606061126193927f35a2101eaac94b493e0dfca061f9a7f087913fde8678e7cde0aca9897edba0e592335f528082528a6001600160401b03610100600160481b03604082600160ff835f205460101c161b16938981525f80516020615acc833981519152875220928354928360081c161760081b1690610100600160481b031916179055335f52815260ff60405f205460101c166040519185835233908301526040820152a1612e0c565b611269578480f35b546002146106c25761127a92613202565b5f8080808480f35b604051631089c4a160e11b815260048101849052602490fd5b9092508181813d83116112c3575b6112b38183612d09565b810103126105dd5751915f611197565b503d6112a9565b6040513d8a823e3d90fd5b6044908560405191635788c0fd60e11b835260048301526024820152fd5b60405163a0ae911d60e01b8152336004820152602490fd5b5034610274578060031936011261027457602060405161ffff7f0000000000000000000000000000000000000000000000000000000000000000168152f35b506020366003190112610274576001600160401b03600435166004350361027457611373613a00565b60025f80516020615b0c83398151915254146106c2576001600160401b03600435165f525f80516020615bcc83398151915260205260405f2090604051916113ba83612c9d565b805483526001810154602084015261ffff60028201546001600160481b03811660408601526001600160401b038160481c16606086015260881c16608084015260018060a01b0360038201541660a08401526040518281939060048401549361142285612e74565b80855294600181169081156115d3575060011461158e575b505061144892500382612d09565b60c08201526001600160401b036060820151161561156c576114776001600160401b0360608301511642612f6b565b6001600160401b037f00000000000000000000000000000000000000000000000000000000000000001611611536576115146020916001600160401b03600435165f525f80516020615bcc83398151915283526114d660405f2061318c565b6040810151608082015182518584015160a085015160c090950151946001600160a01b031693909261ffff16906001600160481b0316600435614273565b60015f80516020615bec833981519152556001600160401b0360405191168152f35b6001600160401b0360606044920151166040519063c06cf05f60e01b82526001600160401b036004351660048301526024820152fd5b6024604051635feafa3160e11b81526001600160401b03600435166004820152fd5b60049193949250018252602082205b8183106115b7575050906020611448928201015f8061143a565b602091935080600191548385880101520191019091839261159d565b9150506020925061144894915060ff191682840152151560051b8201015f8061143a565b5060603660031901126102745761160c612c33565b604435611617613a00565b60025f80516020615b0c83398151915254146106c25760209181611514926040519261164284612cd3565b60018452853681860137600435613d24565b50346102745760403660031901126102745761166e612c22565b6024356001600160401b0381116117cb5761168d903690600401612d45565b916040519182905f80516020615b4c8339815191528281549182875260208097019086525f80516020615aac83398151915292865b888282106117ac575050506116d992500383612d09565b826117038351966040519788928392635b10743960e11b8452604060048501526044840190612c65565b906024830152038173b55f857fc9a9757ffe70a3988f4a0b4f04f9d2a05af49081156117a15783949561173c949261177d575b50613bd6565b604051926040840160408552835180915285606086019401915b8181106117695750505082938301520390f35b825185529386019391860191600101611756565b61179a9192503d8087833e6117928183612d09565b8101906130a3565b905f611736565b6040513d85823e3d90fd5b85546001600160a01b03168452600195860195889550930192016116c2565b8280fd5b50346102745780600319360112610274576117e86139bc565b7ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a0080546001600160401b038082169060018201918183116118f85760ff8460401c169081156118eb575b506118d957600160401b911680926001600160481b03191617179081835560ff7f7487ca88d037ca20519908b1ee7556206bef53bce0226a348750cb9d4f688e4e5416156118c7577fc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d2926020926118a7613946565b6118af614a8a565b68ff000000000000000019169055604051908152a180f35b604051632866815360e11b8152600490fd5b60405163f92ee8a960e01b8152600490fd5b905081831611155f611832565b634e487b7160e01b5f52601160045260245ffd5b50346102745760403660031901126102745760243560ff811681036105dd57611939602091600435613017565b6040519015158152f35b50346102745780600319360112610274575f80516020615aec833981519152546040516001600160a01b039091168152602090f35b5034610274576020366003190112610274576119cb6001600160401b0360209260405f80516020615b2c833981519152549160043581525f80516020615acc8339815191528652205460081c1616613b86565b60ff60405191168152f35b50346102745780600319360112610274576119ef612f78565b506109c661098b612f96565b50346102745780600319360112610274575f80516020615aec83398151915254611a2d906001600160a01b03166133a4565b5f80516020615b0c83398151915260028154146106c257600290557f0e2fb031ee032dc02d8011dc50b816eb450cf856abd8261680dac74f72165bd2602060405160018152a180f35b503461027457602036600319011261027457600435611a93613a00565b60025f80516020615b0c83398151915254146106c257611ab281613268565b602081016001600160401b03908181511615611b7857611ad58282511642612f6b565b827f00000000000000000000000000000000000000000000000000000000000000001611611b56578385527f4e8909a01183a67951f5a6147d6e76ed02ea890c72afea01a9edee91edc609b860205260408086208681556001018690558301518351869161053c916001600160481b0316906001600160a01b031687613a2f565b516040516301cb739d60e71b8152600481019490945216602483015250604490fd5b604051630301bcaf60e61b815260048101859052602490fd5b508060031936011261027457611ba56139bc565b7ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a00805460ff8160401c1615906001600160401b03811680159081611dbb575b6001149081611db1575b159081611da8575b506118d95767ffffffffffffffff198116600117835581611d89575b50611c1b6152e7565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0381163303611d60575034611d4e57611c5a6152e7565b611c626152e7565b611c6a6152e7565b60015f80516020615b0c833981519152555f80516020615c0c83398151915280546001600160a01b03191633179055611ca16152e7565b611ca96152e7565b611cb2336148f9565b611cba6152e7565b611cc26152e7565b60015f80516020615bec83398151915255611cf8610100600160481b0360ff611cf1611cec612ee9565b614a52565b161761370e565b611d00613946565b611d08614a8a565b611d10575080f35b68ff00000000000000001981541690557fc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d2602060405160018152a180f35b60405163bd28e88960e01b8152600490fd5b604051636345072160e11b81526001600160a01b03919091166004820152336024820152604490fd5b68ffffffffffffffffff1916680100000000000000011782555f611c12565b9050155f611bf6565b303b159150611bee565b839150611be4565b503461027457608036600319011261027457611ddd612c22565b6024356044359060ff82168092036105dd57611df76133f6565b61ffff92838116938415611f22578215611f10578315611efe577f0000000000000000000000000000000000000000000000000000000000000000168414611eec577f1456404e7f41f35c3daac941bb50bad417a66275c3040061b4287d787719599d92608092855f5260ff5f80516020615a6c8339815191529384602052611ecf60405f209183600160405194611e8e86612cd3565b8054865201541696602084019788528a5f52602052600160405f2086815501868519825416179055611eca611ec1612ee9565b80606435613461565b6134ae565b51935116604051938452602084015260408301526060820152a280f35b60405163101b8f9560e11b8152600490fd5b60405163ade64f0b60e01b8152600490fd5b60405163f839a0cb60e01b8152600490fd5b60405163100b0f2760e11b8152600490fd5b503461027457806003193601126102745760206040516001600160401b037f0000000000000000000000000000000000000000000000000000000000000000168152f35b5034610274578060031936011261027457602060ff7f5443fea4dc453d96b81ce55b62e11a4094cc4cbb8a360956a7253cfdb42506cb54166040519015158152f35b50346102745780600319360112610274577f00000000000000000000000000000000000000000000000000000000000000009060028210156120045760208260ff60405191168152f35b634e487b7160e01b81526021600452602490fd5b50346102745780600319360112610274576120316133f6565b5f80516020615b0c833981519152600281540361207957600190557fe11c2112add17fb763d3bd59f63b10429c3e11373da4fb8ef6725107a2fdc4b06020604051838152a180f35b604051637e38d1d360e11b8152600490fd5b503461027457806003193601126102745760206119cb612ee9565b50346102745760203660031901126102745760ff604060209260043581525f80516020615acc83398151915284522054166040519015158152f35b50346102745780600319360112610274576040517f0000000000000000000000000000000000000000000000000000000000000000600281101561212757602092508152f35b634e487b7160e01b83526021600452602483fd5b503461027457806003193601126102745760206001600160401b037fad78307a8b51804c575f26039dcb87c58925afb3b7c08732f3b21b942aed7a765416604051908152f35b5034610274576020806003193601126106d4576004356001600160a01b03811691828203610803576121b16133f6565b82156110cc57825f525f80516020615bac8339815191529182825260ff908160405f2054165f1461234b57845f5283835260405f2061010061ff00198254161790555b5f80516020615b4c83398151915290815491600160401b8310156123375782610fde91600161222595019055613224565b5f80516020615b6c83398151915292835461ff00612247848360081c16613935565b60081b169061ff001916178094555f80516020615b2c83398151915280546001600160401b039081811691885f5284875260018660405f205460101c161b16821791821461231e5767ffffffffffffffff19161790557ff05962b5774c658e85ed80c91a75af9d66d2af2253dda480f90bce78aff5eda5946060949093909290916122d0614a8a565b845f528252805f80516020615a8c83398151915280548281161561230f575b5054169260405194855260081c16908301526040820152a161093f613946565b60ff191660011781555f6122ef565b604051638d68f84d60e01b815260048101899052602490fd5b634e487b7160e01b5f52604160045260245ffd5b5f80516020615b6c83398151915282815416604081101561245d576040519061237382612cb8565b60018252858201906001825260408301908152885f5287875260405f2092511515918662ff000061ff0086549351151560081b16935160101b1693169062ffffff191617171790558054836123c9818316613935565b169060ff19161790557f3031d39df71efbb605646fc51d7571499445af538fa6dd17ce8c07e8118ed978805490600160401b8210156123375760018201808255821015612449575f527f357eda4c1707ce60b55a439f3dc12fcacea5ca0fd863e2fc179a916cf05fccd10180546001600160a01b031916861790556121f4565b634e487b7160e01b5f52603260045260245ffd5b60405163891684c360e01b8152600490fd5b5034610274576020366003190112610274576004356001600160401b0381168091036106d457606060c06040516124a581612c9d565b84815284602082015284604082015284838201528460808201528460a082015201525f525f80516020615bcc83398151915260205260405f20604051906124eb82612c9d565b805482526001810154602083015261ffff60028201546001600160481b03811660408501526001600160401b038160481c16606085015260881c16608083015260018060a01b0360038201541660a08301526040518381949060048401549361255385612e74565b808552946001811690811561263a57506001146125f5575b505061257992500383612d09565b60c081019182526109c66040519283926020845280516020850152602081015160408501526001600160481b0360408201511660608501526001600160401b03606082015116608085015261ffff60808201511660a085015260a0600180821b039101511660c08401525160e080840152610100830190612c65565b60049193949250018252602082205b81831061261e575050906020612579928201015f8061256b565b6020919350806001915483858901015201910190918492612604565b9150506020925061257994915060ff191682840152151560051b8201015f8061256b565b5034610274576020366003190112610274576126786133f6565b61093f61268f612686612ee9565b80600435613461565b61370e565b50346102745760403660031901126102745761093f6126b1612c33565b6126b96133f6565b611eca612686612ee9565b50346105dd576020806003193601126105dd576001600160a01b03600435818116908181036105dd576126f56133f6565b6126fd6139bc565b3b15612ad0577f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc80546001600160a01b031916821790557fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b5f80a27f7487ca88d037ca20519908b1ee7556206bef53bce0226a348750cb9d4f688e4e9182549161278a60ff84161561342e565b60ff199283166001178455303b156105dd5760405163011fa75760e71b81525f8160048183305af180156105d257612abd575b5060405163689f90c360e01b81528281600481305afa908115612a85578691612a90575b5015612819575b50507f5443fea4dc453d96b81ce55b62e11a4094cc4cbb8a360956a7253cfdb42506cb818154169055815416905580f35b604051637e062a3560e11b81528281600481305afa908115612a85578691612a47575b508161286c927f00000000000000000000000000000000000000000000000000000000000000001691161461342e565b6040516314ad290960e11b81528181600481305afa908115610807578591612a11575b507f00000000000000000000000000000000000000000000000000000000000000009060028210156129fd5760028110156129fd576128ce911461342e565b604051634d4502c960e11b81528181600481305afa80156108075785906129c7575b612923915061ffff807f00000000000000000000000000000000000000000000000000000000000000001691161461342e565b604051631d2a9eff60e21b8152908082600481305afa908115610807578591612987575b5061298091506001600160401b03807f00000000000000000000000000000000000000000000000000000000000000001691161461342e565b5f806127e8565b905081813d83116129c0575b61299d8183612d09565b8101031261080357516001600160401b038116810361080357612980905f612947565b503d612993565b508181813d83116129f6575b6129dd8183612d09565b81010312610812576129f161292391615111565b6128f0565b503d6129d3565b634e487b7160e01b86526021600452602486fd5b90508181813d8311612a40575b612a288183612d09565b8101031261081257516002811015610812575f61288f565b503d612a1e565b90508281813d8311612a7e575b612a5e8183612d09565b81010312612a7a5751908082168203612a7a579061286c61283c565b8580fd5b503d612a54565b6040513d88823e3d90fd5b612ab09150833d8511612ab6575b612aa88183612d09565b810190613449565b5f6127e1565b503d612a9e565b612ac8919550612c8a565b5f935f6127bd565b60405162461bcd60e51b815260048101849052602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201526c1bdd08184818dbdb9d1c9858dd609a1b6064820152608490fd5b346105dd5760203660031901126105dd576020611939600435612e0c565b346105dd5760203660031901126105dd576004356001600160a01b03818116918290036105dd57612b89815f80516020615aec83398151915254166133a4565b5f80516020615c0c83398151915280546001600160a01b031981168417909155167f51c4874e0f23f262e04a38c51751336dde72126d67f53eb672aaff02996b3ef65f80a3005b346105dd5760203660031901126105dd5761ffff612bec612c22565b612bf4612f78565b50165f525f80516020615b8c83398151915260205260206106f3610468612c1d60405f20612fdd565b6132fa565b6004359061ffff821682036105dd57565b6024359061ffff821682036105dd57565b5f5b838110612c555750505f910152565b8181015183820152602001612c46565b90602091612c7e81518092818552858086019101612c44565b601f01601f1916010190565b6001600160401b03811161233757604052565b60e081019081106001600160401b0382111761233757604052565b606081019081106001600160401b0382111761233757604052565b604081019081106001600160401b0382111761233757604052565b60a081019081106001600160401b0382111761233757604052565b90601f801991011681019081106001600160401b0382111761233757604052565b6001600160401b03811161233757601f01601f191660200190565b81601f820112156105dd57803590612d5c82612d2a565b92612d6a6040519485612d09565b828452602083830101116105dd57815f926020809301838601378301015290565b90600319906060828401126105dd5760043561ffff811681036105dd579260243592604435916001600160401b03918284116105dd5760609084830301126105dd5760405192612dda84612cb8565b806004013584526024810135602085015260448101359283116105dd57612e049201600401612d45565b604082015290565b6001600160401b039060ff612e60815f80516020615a8c83398151915254169384935f80516020615b2c83398151915254905f525f80516020615acc83398151915260205260405f205460081c1616613b86565b1610159081612e6d575090565b9050151590565b90600182811c92168015612ea2575b6020831014612e8e57565b634e487b7160e01b5f52602260045260245ffd5b91607f1691612e83565b3d15612ed6573d90612ebd82612d2a565b91612ecb6040519384612d09565b82523d5f602084013e565b606090565b519060ff821682036105dd57565b5f80604051602081019063313ce56760e01b825260048152612f0a81612cd3565b51907f00000000000000000000000000000000000000000000000000000000000000005afa612f37612eac565b9015612f59576020818051810103126105dd576020612f569101612edb565b90565b604051631222cd8360e01b8152600490fd5b919082039182116118f857565b60405190612f8582612cb8565b5f6040838281528260208201520152565b60405190612fa382612cb8565b8160406001600160401b035f80516020615c2c833981519152546001600160481b0380821685528160481c16602085015260901c16910152565b90604051612fea81612cb8565b60406001600160401b038294546001600160481b0380821685528160481c16602085015260901c16910152565b906001600160401b03915f525f80516020615acc833981519152602052600160ff60405f205460081c92161b1616151590565b6001600160401b0381116123375760051b60200190565b81601f820112156105dd57805161307781612d2a565b926130856040519485612d09565b818452602082840101116105dd57612f569160208085019101612c44565b9060209081838203126105dd5782516001600160401b03938482116105dd57019080601f830112156105dd5781516130da8161304a565b946040906130eb6040519788612d09565b828752858088019360051b860101948486116105dd57868101935b86851061311857505050505050505090565b84518381116105dd5782019084601f1983890301126105dd5784519061313d82612cd3565b6131488a8401612edb565b825285830151918583116105dd57613167898c80969581960101613061565b83820152815201940193613106565b818110613181575050565b5f8155600101613176565b6004905f81555f60018201555f60028201555f6003820155016131af8154612e74565b90816131b9575050565b81601f5f93116001146131cb5750555b565b9080839182526131ea601f60208420940160051c840160018501613176565b5555565b80518210156124495760209160051b010190565b91908161320f9184614815565b91909161321f576131c992615120565b505050565b5f80516020615b4c8339815191528054821015612449575f525f80516020615aac83398151915201905f90565b613259612f78565b50612f56610468612c1d612f96565b613270612f78565b505f527f4e8909a01183a67951f5a6147d6e76ed02ea890c72afea01a9edee91edc609b860205260405f20604051906132a882612cb8565b80546001600160481b038116835260481c6001600160401b03166020830152600101546001600160a01b0316604082015290565b81156132e6570490565b634e487b7160e01b5f52601260045260245ffd5b6001600160401b0390817f00000000000000000000000000000000000000000000000000000000000000001691821561338d5761337a828260ff936040610100600160481b039601511642038161335f602085019889519383875160081c16026132dc565b9160081c1601915160081c168082105f14613386575061496a565b9251169160081b161790565b905061496a565b506020015160ff16610100600160481b0317919050565b5f80516020615c0c83398151915254336001600160a01b0391821614159190826133e9575b50506133d157565b60405163e2a08e5d60e01b8152336004820152602490fd5b1633141590505f806133c9565b5f80516020615aec833981519152546001600160a01b0316330361341657565b60405163118cdaa760e01b8152336004820152602490fd5b1561343557565b634e487b7160e01b5f52600160045260245ffd5b908160209103126105dd575180151581036105dd5790565b61349961349460ff92610100600160481b03949561347e87614a52565b9085811686831610156134a457509586916149f7565b61496a565b92169160081b161790565b90509586916149f7565b9061ffff1690815f525f80516020615b8c83398151915260205260405f2080546134d6612ee9565b916008916001600160401b039181841c831691906001600160481b03828116841580613703575b156135b35750866040979460ff8a989561359286613599966135447f739ed886fd81a3ddc9f4b327ab69152e513cd45b26fda0c73660eaca8e1193019f6135a69d9a614a64565b815467ffffffffffffffff60901b19918e169190911679ffffffffffffffff000000000000000000ffffffffffffffffff199091161742891660901b67ffffffffffffffff60901b16179055565b16906149f7565b9460ff8116921c166149f7565b82519182526020820152a2565b6135bf612c1d84612fdd565b90896135cb818361579a565b156136b2576135d99161599d565b6135e7868a891c1686613b6d565b86610100600160481b03918260ff8816918b1b1617613606818561579a565b156136a75760ff918161361c613629938761599d565b8b1c1689858c1c16613b6d565b921691881b16175b61363b898261579a565b6136855796809460ff7f739ed886fd81a3ddc9f4b327ab69152e513cd45b26fda0c73660eaca8e1193019a9895613592866135999661368060409e6135a69d9a614a64565b613544565b604051631e74e8fb60e31b815290821660048201529088166024820152604490fd5b50505060ff16613631565b906136bc9161599d565b6136ca85878b8a1c16613b6d565b60ff8a1691878084610100600160481b0380958d1b16176136eb818561599d565b8b1c16918a1c16018781116118f857881b1617613631565b5060ff8416156134fd565b5f80516020615c2c8339815191528054613726612ee9565b916008916001600160401b039181841c831691906001600160481b0382811684158061392a575b156137f65750866040979460ff7f7e3b0fc388be9d36273f66210aed83be975df3a9adfffa4c734033f498f362cd9a989585613599956137e99a9754600160481b600160901b038d60481b1690600160481b600160901b0319161782555b815479ffffffffffffffff000000000000000000ffffffffffffffffff1916908c16174260901b67ffffffffffffffff60901b1617905516906149f7565b82519182526020820152a1565b613801612c1d612f96565b908961380d818361579a565b156138d95761381b9161599d565b613829868a891c1686613b6d565b86610100600160481b03918260ff8816918b1b1617613848818561579a565b156138ce5760ff918161361c61385e938761599d565b921691881b16175b613870898261579a565b6136855796809460ff7f7e3b0fc388be9d36273f66210aed83be975df3a9adfffa4c734033f498f362cd9a98956137e9989561359995600160481b600160901b0360409d60481b16600160481b600160901b031984161782556137ab565b50505060ff16613866565b906138e39161599d565b6138f185878b8a1c16613b6d565b60ff8a1691878084610100600160481b0380958d1b1617613912818561599d565b8b1c16918a1c16018781116118f857881b1617613866565b5060ff84161561374d565b60ff1660ff81146118f85760010190565b60ff5f80516020615a8c833981519152541660405161396481612cd3565b60ff5f80516020615b6c83398151915254818116835260081c1680602083015280831161399e57505160ff166139975750565b156108fe57565b82604491604051916313c3d1b160e01b835260048301526024820152fd5b307f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316146139ee57565b604051633c64f99360e21b8152600490fd5b5f80516020615bec8339815191526002815414613a1d5760029055565b604051633ee5aeb560e01b8152600490fd5b91613a5d906104687f0000000000000000000000000000000000000000000000000000000000000000614b63565b917f504e6efe18ab9eed10dc6501a417f5b12a2f7f2b1593aed9b89f9bce3cf29a915f80a27f000000000000000000000000000000000000000000000000000000000000000060028110156105fd5780613aeb575060405163a9059cbb60e01b60208201526001600160a01b03909116602482015260448101919091526131c99061050d81606481016104ff565b600181036105e157507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031691823b156105dd576040516340c10f1960e01b81526001600160a01b039290921660048301526024820152905f908290604490829084905af180156105d257613b645750565b6131c990612c8a565b6001600160401b0391821690821603919082116118f857565b905f915b6001600160401b03808216801561321f575f19019081116118f857613bb0911692613935565b91613b8a565b9060406020612f569360ff81511684520151918160208201520190612c65565b909291805191613be58361304a565b92604091613bf66040519586612d09565b818552613c028261304a565b602090601f190136878301375f975f955b848710613c2557505050505050509190565b909192939495988685613c9b868d613c4460018060a01b0391886131ee565b5116805f525f80516020615bac8339815191528252613c6c60ff865f205460101c16896131ee565b51908551808095819463b5634c7360e01b835261ffff60049916898401526024998a8401526044830190613bb6565b03915afa908115613d1a578d905f92613ce8575b50613cbb82918d6131ee565b528301809311613cd75750506001909901959493929190613c13565b601190634e487b7160e01b5f52525ffd5b809250888092503d8311613d13575b613d018183612d09565b810103126105dd57518c613cbb613caf565b503d613cf7565b8a513d5f823e3d90fd5b91939290935f948315613fc8578115613fb6578215613fa4577f000000000000000000000000000000000000000000000000000000000000000095613d693088614b8b565b60018060a01b03881690604098613dae8a516323b872dd60e01b6020820152602499338b830152306044830152606482015260648152613da881612cee565b84615328565b613dc182613dbc3084614b8b565b612f6b565b927f00000000000000000000000000000000000000000000000000000000000000006002811015613f9157600114613f0f575b50505061ffff83165f525f80516020615a6c83398151915260205260ff6001895f200154168015613efe57613e32613e2a612ee9565b918284613461565b98613e4e6001600160401b039260ff8c16848d60081c166149f7565b808403613ed85750507fad78307a8b51804c575f26039dcb87c58925afb3b7c08732f3b21b942aed7a769081549080821698818a14613ec65750938787878b968e968e96613eae9a60018b0116906001600160401b031916179055614be7565b613ebd57612f56953394614273565b50505091505090565b634e487b7160e01b8652601160045285fd5b60449189613ee7869384612f6b565b9151926338f831a560e11b84526004840152820152fd5b885163ade64f0b60e01b8152600490fd5b803b156105dd575f80918a8d5180948193630852cd8d60e31b83528960048401525af18015613f8757613f72575b50613f49903090614b8b565b808203613f565780613df4565b60449250878a51926302156a8f60e01b84526004840152820152fd5b613f7d919450612c8a565b5f92613f49613f3d565b8b513d5f823e3d90fd5b89634e487b7160e01b5f5260216004525ffd5b60405163717f139360e11b8152600490fd5b604051634e46966960e11b8152600490fd5b604051631f2a200560e01b8152600490fd5b94939291905f938615613fc8578215613fb6578315613fa4577f00000000000000000000000000000000000000000000000000000000000000009661401f3089614b8b565b9060018060a01b038916916040996140658b516323b872dd60e01b6020820152602494338683015230604483015260648201526064815261405f81612cee565b85615328565b61407382613dbc3084614b8b565b937f0000000000000000000000000000000000000000000000000000000000000000600281101561421457600114614194575b50505061ffff84165f525f80516020615a6c83398151915260205260ff60018a5f20015416908115614183576140e56140dd612ee9565b928385613461565b996141026001600160401b03938c8560ff82169160081c166149f7565b8085036141745750507fad78307a8b51804c575f26039dcb87c58925afb3b7c08732f3b21b942aed7a769182549181831699828b14614163575050938787878b968e968e96613eae9a60018b0116906001600160401b031916179055614be7565b634e487b7160e01b81526011600452fd5b90604492613ee7869384612f6b565b895163ade64f0b60e01b8152600490fd5b803b156105dd575f8091858e5180948193630852cd8d60e31b83528a60048401525af1801561420a576141f5575b506141ce903090614b8b565b8082036141db57806140a6565b6044928b51926302156a8f60e01b84526004840152820152fd5b614200919950612c8a565b5f976141ce6141c2565b8c513d5f823e3d90fd5b84634e487b7160e01b5f5260216004525ffd5b906020828203126105dd5781516001600160401b0381116105dd57612f569201613061565b9060606040612f569380518452602081015160208501520151918160408201520190612c65565b95919061429f7f0000000000000000000000000000000000000000000000000000000000000000614b63565b6040519283845f80516020615b4c833981519152602081549384815201905f525f80516020615aac833981519152925f5b8181106147d85750506142e592500385612d09565b7f3031d39df71efbb605646fc51d7571499445af538fa6dd17ce8c07e8118ed97854908451156147c6576143375f916040519384928392635b10743960e11b8452604060048501526044840190612c65565b906024830152038173b55f857fc9a9757ffe70a3988f4a0b4f04f9d2a05af49081156105d2575f916147ac575b50614370848285613bd6565b949085341061478d576143838634612f6b565b8061477e575b506060608060405161439a81612cee565b5f81525f60208201525f60408201525f838201520152604051986143bd8a612cee565b6001600160481b0385168a5260018060a01b037f00000000000000000000000000000000000000000000000000000000000000001660208b01528760408b015261ffff861660608b0152604051998a60208101106001600160401b0360208d0111176123375760805f918c60206144979e01604052838152828201526040519c8d9283926315cfa3cb60e11b8452602060048501526001600160481b038151166024850152602081015160448501526040810151606485015261ffff6060820151166084850152015160a060a484015260c4830190612c65565b038173b55f857fc9a9757ffe70a3988f4a0b4f04f9d2a05af4998a156105d2576145139a5f928d928492614762575b506001600160401b03604051936144dc85612cb8565b16835260018060a01b031660208301526040820152604051809b81926311692f3760e31b835260206004840152602483019061424c565b038173b55f857fc9a9757ffe70a3988f4a0b4f04f9d2a05af49889156105d2575f9961473e575b5061ffff85165f525f80516020615a6c83398151915260205260405f2054928251928415614722575f5b84811061464f575050505050509161ffff6080926145a57fe54e51e42099622516fa3b48e9733581c9dbdcb771cafb093f745a0532a3598295610470612ee9565b9260405193845260208401521660408201526001600160401b0387166060820152a3604051614625602282602081019461ffff60f01b7f000000000000000000000000000000000000000000000000000000000000000060f01b1686526146158151809260208686019101612c44565b8101036002810184520182612d09565b5190207f3e6ae56314c6da8b461d872f41c6d0bb69317b9d0232805aaccfa45df1a16fa05f80a290565b6001600160a01b0361466182846131ee565b51169061466e81866131ee565b51825f525f80516020615bac83398151915260205261469760ff60405f205460101c16866131ee565b51833b156105dd576146dc938f8f938d8c5f966146ee61ffff956040519b8c998a988997634b5b050560e01b895216600488015260a0602488015260a4870190613bb6565b85810360031901604487015290612c65565b916064840152608483015203925af19182156105d257600192614713575b5001614564565b61471c90612c8a565b5f61470c565b604051630ebc95af60e21b815261ffff88166004820152602490fd5b61475b9199503d805f833e6147538183612d09565b810190614227565b975f61453a565b6147779192503d8086833e6147538183612d09565b905f6144c6565b61478790615401565b5f614389565b6040516306a91e3760e51b815260048101879052346024820152604490fd5b6147c091503d805f833e6117928183612d09565b5f614364565b6040516334e7b19560e11b8152600490fd5b84546001600160a01b03168352600194850194899450602090930192016142d0565b60409061ffff612f569493168152816020820152019061424c565b60405163b3f07bbd60e01b81529193926020918391829161483a9190600484016147fa565b038173b55f857fc9a9757ffe70a3988f4a0b4f04f9d2a05af49081156105d2575f916148c7575b5061486b81612e0c565b156148af57614879816150dc565b9283614886575091505f90565b7f4069dff8c9df7e38d2867c0910bd96fd61787695e5380281148c04932d02bef25f80a35f9190565b60249060405190630451c4fb60e41b82526004820152fd5b90506020813d6020116148f1575b816148e260209383612d09565b810103126105dd57515f614861565b3d91506148d5565b6001600160a01b03908116908115614952575f80516020615aec83398151915280546001600160a01b031981168417909155167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e05f80a3565b604051631e4fbdf760e01b81525f6004820152602490fd5b6001600160401b039081811161497e571690565b60405162461bcd60e51b815260206004820152602660248201527f53616665436173743a2076616c756520646f65736e27742066697420696e203660448201526534206269747360d01b6064820152608490fd5b9060ff8091169116039060ff82116118f857565b60ff16604d81116118f857600a0a90565b919060ff821660ff8216818114614a4b571115614a2a57614a1f612f569392614a24926149d2565b6149e6565b906132dc565b614a1f90614a37926149d2565b908181029181830414901517156118f85790565b5050505090565b60ff811660081015612f565750600890565b90600160481b600160901b0382549160481b1690600160481b600160901b031916179055565b5f80516020615b6c8339815191525460ff8160081c16614ab95f80516020615b4c83398151915254821461342e565b5f5b818110614b3b57505f5b818110614ade575050604060ff6131c99216111561342e565b60018082018083116118f8575b838110614afc575050600101614ac5565b8190614b35614b0a85613224565b90546003916001600160a01b03919082614b2387613224565b905490861b1c16931b1c16141561342e565b01614aeb565b80614b5d614b4a600193613224565b848060a01b0391549060031b1c16614fa0565b01614abb565b468103614b6d5750565b604490604051906377d879fb60e01b82526004820152466024820152fd5b6040516370a0823160e01b602082019081526001600160a01b0390931660248083019190915281525f92839291614bc181612cb8565b51915afa614bcd612eac565b9015612f59576020818051810103126105dd576020015190565b9293949095979691614bfa611cec612ee9565b9889610100600160481b0360ff614c256134946001600160401b039e8f848816908860081c166149f7565b60081b91909116911617967f00000000000000000000000000000000000000000000000000000000000000008b1615614f9a57614c60612f78565b50614c6c612c1d612f96565b614c76898261599d565b8b808a60081c169160081c16105b811580614f93575b614f6d5781614f65575b50614cb957505050505050614cb5929350614cb081615432565b6154f1565b5f90565b60049293949650614cec9795977f0000000000000000000000000000000000000000000000000000000000000000614b63565b614cf4613251565b956040958b87519116978882526020998a830152878201527ff33512b84e24a49905c26c6991942fc5a9652411769fc1e448f967cdb049f08a60603392a2855192614d3e84612c9d565b8352878301988952858301906001600160481b038093168252614de28c60608601814216815261ffff608088019416845260a087019533875260c08801998a528b5f525f80516020615bcc8339815191528d528a5f20975188556001809e5190890155600288019551166001600160481b03198654161785555116839067ffffffffffffffff60481b82549160481b169067ffffffffffffffff60481b1916179055565b51815461ffff60881b191660889190911b61ffff60881b16179055516003820180546001600160a01b0319166001600160a01b0392909216919091179055915180519098919092019190811161233757614e3c8254612e74565b601f8111614f2c575b5084601f8211600114614eab5781907f69add1952a6a6b9cb86f04d05f0cb605cbb469a50ae916139d34495a9991481f9798995f92614ea0575b50505f19600383901b1c191690871b1790555b51908152a1612f5634615401565b015190505f80614e7f565b601f19821698835f52865f20995f5b818110614f1757509188999a91847f69add1952a6a6b9cb86f04d05f0cb605cbb469a50ae916139d34495a9991481f9a959410614eff575b505050811b019055614e92565b01515f1960f88460031b161c191690555f8080614ef2565b828401518c559a89019a928801928801614eba565b614f5590835f52865f20601f840160051c810191888510614f5b575b601f0160051c0190613176565b5f614e45565b9091508190614f48565b90505f614c96565b604487614f78613251565b90604051916326fb55dd60e01b835260048301526024820152fd5b5080614c8c565b5f614c84565b9060018060a01b0380921691825f525f80516020615bac83398151915260205260405f2060405190614fd182612cb8565b5460ff9161500d838316158015938484526020840193604087808460081c1615938415885260101c16910195818752926150c2575b505061342e565b5f80516020615b2c83398151915254956001600160401b036001976001868651161b1616151591511515915f915f905f80516020615b6c8339815191525497878960081c16925b83811061508a575b505050506131c99697509161508091615078828796951461342e565b15151461342e565b511691161161342e565b828261509583613224565b90549060031b1c16146150a9578b01615054565b5098998a9950935082915061507890508461508061505c565b909150816150d3575b505f80615006565b9050155f6150cb565b5f525f80516020615acc83398151915260205260405f20805460ff811661510a5760ff191660011790555f90565b5050600190565b519061ffff821682036105dd57565b61514c915f604080920151825180958192635399ded560e11b8352602060048401526024830190612c65565b038173b55f857fc9a9757ffe70a3988f4a0b4f04f9d2a05af49283156152dd575f9361523c575b5061ffff80606085015116907f000000000000000000000000000000000000000000000000000000000000000016808203615221575050806151d86151b6612ee9565b806151d38188516001600160401b0360ff82169160081c166149f7565b613461565b930151908160a01c61520a57506001600160a01b0316906151fd908290849086615617565b61321f576131c992613a2f565b60249250519063033b960d60e41b82526004820152fd5b6044925191631ee5902560e11b835260048301526024820152fd5b9092503d805f833e61524e8183612d09565b81016020828203126105dd5781516001600160401b03928382116105dd57019060a0828203126105dd5784519261528484612cee565b82516001600160481b03811681036105dd5784526020830151602085015285830151868501526152b660608401615111565b606085015260808301519081116105dd576152d19201613061565b6080820152915f615173565b50513d5f823e3d90fd5b60ff7ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a005460401c161561531657565b604051631afcd79f60e31b8152600490fd5b604051615385916001600160a01b031661534182612cd3565b5f806020958685527f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c656487860152868151910182855af161537f612eac565b916159d2565b8051908161539257505050565b82806153a2938301019101613449565b156153aa5750565b6084906040519062461bcd60e51b82526004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b6064820152fd5b5f80808084335af1615411612eac565b501561541a5750565b60249060405190630b288dc560e21b82526004820152fd5b6001600160401b0390817f000000000000000000000000000000000000000000000000000000000000000016156154ed5761546b612f78565b50600160481b600160901b03615482612c1d612f96565b610100600160481b0360ff6154bc5f80516020615c2c83398151915296808854976154ad818861599d565b60081c16908560081c16613b6d565b92169160081b161760481b16906001600160401b0360901b4260901b1690600160481b600160d01b03191617179055565b5050565b6001600160401b03807f0000000000000000000000000000000000000000000000000000000000000000161561321f5761ffff6131c993615530612f78565b5016805f525f80516020615b8c83398151915280602052615556612c1d60405f20612fdd565b5f9283526020919091526040909120805467ffffffffffffffff60901b191642841660901b67ffffffffffffffff60901b16178155928290615598818461599d565b60081c16828260081c16018281115f146156035750610100600160481b0360ff6155c18461496a565b92169160081b161790825490806001600160481b038316926155e3848661599d565b60081c16908360081c16105f146155fb575090614a64565b905090614a64565b60ff6155c1610100600160481b039261496a565b90926001600160401b037f000000000000000000000000000000000000000000000000000000000000000081161561579457615651612f78565b5061ffff85165f525f80516020615b8c833981519152602052615679612c1d60405f20612fdd565b615683858261599d565b81808660081c169160081c16105b6156aa575050506156a5614cb592826157bc565b615880565b7f7f63c9251d82a933210c2b6d0b0f116252c3c116788120e64e8e8215df6f316294509060016020949261576e604051916156e483612cb8565b6001600160481b03958616835242811688840190815260a085901b85900395861660408086019182525f8a81527f4e8909a01183a67951f5a6147d6e76ed02ea890c72afea01a9edee91edc609b88c522094518554925170ffffffffffffffffffffffffffffffffff19909316981697909717911660481b67ffffffffffffffff60481b16178255565b019151166bffffffffffffffffffffffff60a01b825416179055604051908152a1600190565b5f615691565b906157a5818361599d565b6001600160401b03809160081c169160081c161190565b6001600160401b03807f0000000000000000000000000000000000000000000000000000000000000000161561321f57610100600160481b0360ff61587261ffff6131c996615809612f78565b501693845f525f80516020615b8c83398151915280602052615830612c1d60405f20612fdd565b5f9687526020919091526040909520805467ffffffffffffffff60901b191642831660901b67ffffffffffffffff60901b161781559581906154ad818861599d565b92169160081b161790614a64565b6001600160401b0390817f000000000000000000000000000000000000000000000000000000000000000016156154ed576158b9612f78565b506158c5612c1d612f96565b90600160481b600160901b035f80516020615c2c83398151915293845493816001600160401b0360901b4260901b16946158ff818461599d565b60081c16828260081c16018281115f146159895750610100600160481b0360ff6159288461496a565b92169160081b1617906001600160481b03851690615946828461599d565b80856001600160401b0360901b1988161760081c16908360081c16105f1461598257505b60481b1691600160481b600160d01b03191617179055565b905061596a565b60ff615928610100600160481b039261496a565b60ff91821691168181036159af575050565b604051635ce6db6160e11b815260ff918216600482015291166024820152604490fd5b91929015615a3457508151156159e6575090565b3b156159ef5790565b60405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606490fd5b825190915015615a475750805190602001fd5b60405162461bcd60e51b81526020600482015290819061063a906024830190612c6556feebcc9f646b0f459ff8f387587d536b0af3484cf442e1577400f322334e7d1ef047028352a8b3feae1a85fba43bc13f990568bb1637dce33d3dbfd791a0808b7f6c3cb3f3ae91330f31ba2bc0ff8855fc834fb66dc27e8e0b1a398617dabaa5a668dfeeddfa5e4e9adceec01a3aba274bdcbab3f6ac9956417a4332f2b08abdda9016d09d72d40fdae2fd8ceac6b6234c7706214fd39c1cd1e609a0528c19930064bacf405c5d7f563d3ba5252584a52c37e4fee380fd825b10666c27b8258022fd6568c039679b3b7cc93c26c41d9379b7b1bec1677120493b467688302cb11f00758a264b9bdbe3295fe36bd6ff7abaa122f48bf70e90af04a1b8a32d21e4e18561949d1c6242cee5c5a5aeb6b9c190ee611d7742fcec65d9e5b1341ea04d89efb21dcaedea63b55c44882f329622e13a8d0f5b947b3a372826208a9003da1549bca747e973430e858f2f5de357b8dba36ea6d375b81bdb5d53dfaabf0b3a7f852fa0677fef8612c6c15b518c9fa56761e9ed15cfd5c6e5399e5467985ac7ed9b779b17422d0df92223018b32b4d1fa46e071723d6817e2486d003becc55f00bfa91572ce1e5fe8776a160d3b1f862e83f5ee2c080a7423b4761602a3ad12497c25289a27ec8c9be54d4a154cf80490d69bda989cdb8328232e08fea9220420a264697066735822122085ac4db53de6930db3b039184653fb7a750b8e542da7aa92d1612cd0e41b416f64736f6c634300081600330000000000000000000000008d58c0c60b8d6b88fa98b291a646db34d0f982580000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000001e00000000000000000000000000000000000000000000000000000000000151800000000000000000000000000000000000000000000000000000000000000000","name":"NttManager","is_blueprint":false,"license_type":"none","is_fully_verified":false,"is_verified_via_eth_bytecode_db":true,"language":"solidity","evm_version":"shanghai","can_be_visualized_via_sol2uml":true,"is_verified_via_sourcify":false,"additional_sources":[{"file_path":"lib/native-token-transfers/evm/lib/openzeppelin-contracts/contracts/token/ERC20/ERC20.sol","source_code":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.8.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 * 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     * The default value of {decimals} is 18. To select a different value for\n     * {decimals} you should overload it.\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 value {ERC20} uses, unless this function is\n     * 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(\n        address from,\n        address to,\n        uint256 amount\n    ) 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(\n        address from,\n        address to,\n        uint256 amount\n    ) 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(\n        address owner,\n        address spender,\n        uint256 amount\n    ) 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(\n        address owner,\n        address spender,\n        uint256 amount\n    ) 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(\n        address from,\n        address to,\n        uint256 amount\n    ) 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(\n        address from,\n        address to,\n        uint256 amount\n    ) internal virtual {}\n}\n"},{"file_path":"lib/native-token-transfers/evm/lib/wormhole-solidity-sdk/src/Utils.sol","source_code":"\n// SPDX-License-Identifier: Apache 2\npragma solidity ^0.8.13;\n\nimport \"./interfaces/IWormholeRelayer.sol\";\n\nfunction toWormholeFormat(address addr) pure returns (bytes32) {\n    return bytes32(uint256(uint160(addr)));\n}\n\nfunction fromWormholeFormat(bytes32 whFormatAddress) pure returns (address) {\n    if (uint256(whFormatAddress) >> 160 != 0) {\n        revert NotAnEvmAddress(whFormatAddress);\n    }\n    return address(uint160(uint256(whFormatAddress)));\n}\n"},{"file_path":"lib/native-token-transfers/evm/lib/wormhole-solidity-sdk/src/libraries/BytesParsing.sol","source_code":"// SPDX-License-Identifier: Apache 2\npragma solidity ^0.8.13;\n\nlibrary BytesParsing {\n  uint256 private constant freeMemoryPtr = 0x40;\n  uint256 private constant wordSize = 32;\n\n  error OutOfBounds(uint256 offset, uint256 length);\n  error LengthMismatch(uint256 encodedLength, uint256 expectedLength);\n  error InvalidBoolVal(uint8 val);\n\n  function checkBound(uint offset, uint length) internal pure {\n    if (offset > length)\n      revert OutOfBounds(offset, length);\n  }\n\n  function checkLength(bytes memory encoded, uint256 expected) internal pure {\n    if (encoded.length != expected)\n      revert LengthMismatch(encoded.length, expected);\n  }\n\n  function sliceUnchecked(\n    bytes memory encoded,\n    uint offset,\n    uint length\n  ) internal pure returns (bytes memory ret, uint nextOffset) {\n    //bail early for degenerate case\n    if (length == 0)\n      return (new bytes(0), offset);\n\n    assembly (\"memory-safe\") {\n      nextOffset := add(offset, length)\n      ret := mload(freeMemoryPtr)\n\n      //Explanation on how we copy data here:\n      //  The bytes type has the following layout in memory:\n      //    [length: 32 bytes, data: length bytes]\n      //  So if we allocate `bytes memory foo = new bytes(1);` then `foo` will be a pointer to 33\n      //    bytes where the first 32 bytes contain the length and the last byte is the actual data.\n      //  Since mload always loads 32 bytes of memory at once, we use our shift variable to align\n      //    our reads so that our last read lines up exactly with the last 32 bytes of `encoded`.\n      //  However this also means that if the length of `encoded` is not a multiple of 32 bytes, our\n      //    first read will necessarily partly contain bytes from `encoded`'s 32 length bytes that\n      //    will be written into the length part of our `ret` slice.\n      //  We remedy this issue by writing the length of our `ret` slice at the end, thus\n      //    overwritting those garbage bytes.\n      let shift := and(length, 31) //equivalent to `mod(length, 32)` but 2 gas cheaper\n      if iszero(shift) {\n        shift := wordSize\n      }\n\n      let dest := add(ret, shift)\n      let end := add(dest, length)\n      for {\n        let src := add(add(encoded, shift), offset)\n      } lt(dest, end) {\n        src := add(src, wordSize)\n        dest := add(dest, wordSize)\n      } {\n        mstore(dest, mload(src))\n      }\n\n      mstore(ret, length)\n      //When compiling with --via-ir then normally allocated memory (i.e. via new) will have 32 byte\n      //  memory alignment and so we enforce the same memory alignment here.\n      mstore(freeMemoryPtr, and(add(dest, 31), not(31)))\n    }\n  }\n\n  function slice(\n    bytes memory encoded,\n    uint offset,\n    uint length\n  ) internal pure returns (bytes memory ret, uint nextOffset) {\n    (ret, nextOffset) = sliceUnchecked(encoded, offset, length);\n    checkBound(nextOffset, encoded.length);\n  }\n\n  function asAddressUnchecked(\n    bytes memory encoded,\n    uint offset\n  ) internal pure returns (address, uint) {\n    (uint160 ret, uint nextOffset) = asUint160Unchecked(encoded, offset);\n    return (address(ret), nextOffset);\n  }\n\n  function asAddress(\n    bytes memory encoded,\n    uint offset\n  ) internal pure returns (address ret, uint nextOffset) {\n    (ret, nextOffset) = asAddressUnchecked(encoded, offset);\n    checkBound(nextOffset, encoded.length);\n  }\n\n  function asBoolUnchecked(\n    bytes memory encoded,\n    uint offset\n  ) internal pure returns (bool, uint) {\n    (uint8 val, uint nextOffset) = asUint8Unchecked(encoded, offset);\n    if (val & 0xfe != 0)\n      revert InvalidBoolVal(val);\n\n    uint cleanedVal = uint(val);\n    bool ret;\n    //skip 2x iszero opcode\n    assembly (\"memory-safe\") {\n      ret := cleanedVal\n    }\n    return (ret, nextOffset);\n  }\n\n  function asBool(\n    bytes memory encoded,\n    uint offset\n  ) internal pure returns (bool ret, uint nextOffset) {\n    (ret, nextOffset) = asBoolUnchecked(encoded, offset);\n    checkBound(nextOffset, encoded.length);\n  }\n\n/* -------------------------------------------------------------------------------------------------\nRemaining library code below was auto-generated by via the following js/node code:\n\nfor (let bytes = 1; bytes <= 32; ++bytes) {\n  const bits = bytes*8;\n  console.log(\n`function asUint${bits}Unchecked(\n  bytes memory encoded,\n  uint offset\n) internal pure returns (uint${bits} ret, uint nextOffset) {\n  assembly (\"memory-safe\") {\n    nextOffset := add(offset, ${bytes})\n    ret := mload(add(encoded, nextOffset))\n  }\n  return (ret, nextOffset);\n}\n\nfunction asUint${bits}(\n  bytes memory encoded,\n  uint offset\n) internal pure returns (uint${bits} ret, uint nextOffset) {\n  (ret, nextOffset) = asUint${bits}Unchecked(encoded, offset);\n  checkBound(nextOffset, encoded.length);\n}\n\nfunction asBytes${bytes}Unchecked(\n  bytes memory encoded,\n  uint offset\n) internal pure returns (bytes${bytes}, uint) {\n  (uint${bits} ret, uint nextOffset) = asUint${bits}Unchecked(encoded, offset);\n  return (bytes${bytes}(ret), nextOffset);\n}\n\nfunction asBytes${bytes}(\n  bytes memory encoded,\n  uint offset\n) internal pure returns (bytes${bytes}, uint) {\n  (uint${bits} ret, uint nextOffset) = asUint${bits}(encoded, offset);\n  return (bytes${bytes}(ret), nextOffset);\n}\n`\n  );\n}\n------------------------------------------------------------------------------------------------- */\n\n  function asUint8Unchecked(\n    bytes memory encoded,\n    uint offset\n  ) internal pure returns (uint8 ret, uint nextOffset) {\n    assembly (\"memory-safe\") {\n      nextOffset := add(offset, 1)\n      ret := mload(add(encoded, nextOffset))\n    }\n    return (ret, nextOffset);\n  }\n\n  function asUint8(\n    bytes memory encoded,\n    uint offset\n  ) internal pure returns (uint8 ret, uint nextOffset) {\n    (ret, nextOffset) = asUint8Unchecked(encoded, offset);\n    checkBound(nextOffset, encoded.length);\n  }\n\n  function asBytes1Unchecked(\n    bytes memory encoded,\n    uint offset\n  ) internal pure returns (bytes1, uint) {\n    (uint8 ret, uint nextOffset) = asUint8Unchecked(encoded, offset);\n    return (bytes1(ret), nextOffset);\n  }\n\n  function asBytes1(\n    bytes memory encoded,\n    uint offset\n  ) internal pure returns (bytes1, uint) {\n    (uint8 ret, uint nextOffset) = asUint8(encoded, offset);\n    return (bytes1(ret), nextOffset);\n  }\n\n  function asUint16Unchecked(\n    bytes memory encoded,\n    uint offset\n  ) internal pure returns (uint16 ret, uint nextOffset) {\n    assembly (\"memory-safe\") {\n      nextOffset := add(offset, 2)\n      ret := mload(add(encoded, nextOffset))\n    }\n    return (ret, nextOffset);\n  }\n\n  function asUint16(\n    bytes memory encoded,\n    uint offset\n  ) internal pure returns (uint16 ret, uint nextOffset) {\n    (ret, nextOffset) = asUint16Unchecked(encoded, offset);\n    checkBound(nextOffset, encoded.length);\n  }\n\n  function asBytes2Unchecked(\n    bytes memory encoded,\n    uint offset\n  ) internal pure returns (bytes2, uint) {\n    (uint16 ret, uint nextOffset) = asUint16Unchecked(encoded, offset);\n    return (bytes2(ret), nextOffset);\n  }\n\n  function asBytes2(\n    bytes memory encoded,\n    uint offset\n  ) internal pure returns (bytes2, uint) {\n    (uint16 ret, uint nextOffset) = asUint16(encoded, offset);\n    return (bytes2(ret), nextOffset);\n  }\n\n  function asUint24Unchecked(\n    bytes memory encoded,\n    uint offset\n  ) internal pure returns (uint24 ret, uint nextOffset) {\n    assembly (\"memory-safe\") {\n      nextOffset := add(offset, 3)\n      ret := mload(add(encoded, nextOffset))\n    }\n    return (ret, nextOffset);\n  }\n\n  function asUint24(\n    bytes memory encoded,\n    uint offset\n  ) internal pure returns (uint24 ret, uint nextOffset) {\n    (ret, nextOffset) = asUint24Unchecked(encoded, offset);\n    checkBound(nextOffset, encoded.length);\n  }\n\n  function asBytes3Unchecked(\n    bytes memory encoded,\n    uint offset\n  ) internal pure returns (bytes3, uint) {\n    (uint24 ret, uint nextOffset) = asUint24Unchecked(encoded, offset);\n    return (bytes3(ret), nextOffset);\n  }\n\n  function asBytes3(\n    bytes memory encoded,\n    uint offset\n  ) internal pure returns (bytes3, uint) {\n    (uint24 ret, uint nextOffset) = asUint24(encoded, offset);\n    return (bytes3(ret), nextOffset);\n  }\n\n  function asUint32Unchecked(\n    bytes memory encoded,\n    uint offset\n  ) internal pure returns (uint32 ret, uint nextOffset) {\n    assembly (\"memory-safe\") {\n      nextOffset := add(offset, 4)\n      ret := mload(add(encoded, nextOffset))\n    }\n    return (ret, nextOffset);\n  }\n\n  function asUint32(\n    bytes memory encoded,\n    uint offset\n  ) internal pure returns (uint32 ret, uint nextOffset) {\n    (ret, nextOffset) = asUint32Unchecked(encoded, offset);\n    checkBound(nextOffset, encoded.length);\n  }\n\n  function asBytes4Unchecked(\n    bytes memory encoded,\n    uint offset\n  ) internal pure returns (bytes4, uint) {\n    (uint32 ret, uint nextOffset) = asUint32Unchecked(encoded, offset);\n    return (bytes4(ret), nextOffset);\n  }\n\n  function asBytes4(\n    bytes memory encoded,\n    uint offset\n  ) internal pure returns (bytes4, uint) {\n    (uint32 ret, uint nextOffset) = asUint32(encoded, offset);\n    return (bytes4(ret), nextOffset);\n  }\n\n  function asUint40Unchecked(\n    bytes memory encoded,\n    uint offset\n  ) internal pure returns (uint40 ret, uint nextOffset) {\n    assembly (\"memory-safe\") {\n      nextOffset := add(offset, 5)\n      ret := mload(add(encoded, nextOffset))\n    }\n    return (ret, nextOffset);\n  }\n\n  function asUint40(\n    bytes memory encoded,\n    uint offset\n  ) internal pure returns (uint40 ret, uint nextOffset) {\n    (ret, nextOffset) = asUint40Unchecked(encoded, offset);\n    checkBound(nextOffset, encoded.length);\n  }\n\n  function asBytes5Unchecked(\n    bytes memory encoded,\n    uint offset\n  ) internal pure returns (bytes5, uint) {\n    (uint40 ret, uint nextOffset) = asUint40Unchecked(encoded, offset);\n    return (bytes5(ret), nextOffset);\n  }\n\n  function asBytes5(\n    bytes memory encoded,\n    uint offset\n  ) internal pure returns (bytes5, uint) {\n    (uint40 ret, uint nextOffset) = asUint40(encoded, offset);\n    return (bytes5(ret), nextOffset);\n  }\n\n  function asUint48Unchecked(\n    bytes memory encoded,\n    uint offset\n  ) internal pure returns (uint48 ret, uint nextOffset) {\n    assembly (\"memory-safe\") {\n      nextOffset := add(offset, 6)\n      ret := mload(add(encoded, nextOffset))\n    }\n    return (ret, nextOffset);\n  }\n\n  function asUint48(\n    bytes memory encoded,\n    uint offset\n  ) internal pure returns (uint48 ret, uint nextOffset) {\n    (ret, nextOffset) = asUint48Unchecked(encoded, offset);\n    checkBound(nextOffset, encoded.length);\n  }\n\n  function asBytes6Unchecked(\n    bytes memory encoded,\n    uint offset\n  ) internal pure returns (bytes6, uint) {\n    (uint48 ret, uint nextOffset) = asUint48Unchecked(encoded, offset);\n    return (bytes6(ret), nextOffset);\n  }\n\n  function asBytes6(\n    bytes memory encoded,\n    uint offset\n  ) internal pure returns (bytes6, uint) {\n    (uint48 ret, uint nextOffset) = asUint48(encoded, offset);\n    return (bytes6(ret), nextOffset);\n  }\n\n  function asUint56Unchecked(\n    bytes memory encoded,\n    uint offset\n  ) internal pure returns (uint56 ret, uint nextOffset) {\n    assembly (\"memory-safe\") {\n      nextOffset := add(offset, 7)\n      ret := mload(add(encoded, nextOffset))\n    }\n    return (ret, nextOffset);\n  }\n\n  function asUint56(\n    bytes memory encoded,\n    uint offset\n  ) internal pure returns (uint56 ret, uint nextOffset) {\n    (ret, nextOffset) = asUint56Unchecked(encoded, offset);\n    checkBound(nextOffset, encoded.length);\n  }\n\n  function asBytes7Unchecked(\n    bytes memory encoded,\n    uint offset\n  ) internal pure returns (bytes7, uint) {\n    (uint56 ret, uint nextOffset) = asUint56Unchecked(encoded, offset);\n    return (bytes7(ret), nextOffset);\n  }\n\n  function asBytes7(\n    bytes memory encoded,\n    uint offset\n  ) internal pure returns (bytes7, uint) {\n    (uint56 ret, uint nextOffset) = asUint56(encoded, offset);\n    return (bytes7(ret), nextOffset);\n  }\n\n  function asUint64Unchecked(\n    bytes memory encoded,\n    uint offset\n  ) internal pure returns (uint64 ret, uint nextOffset) {\n    assembly (\"memory-safe\") {\n      nextOffset := add(offset, 8)\n      ret := mload(add(encoded, nextOffset))\n    }\n    return (ret, nextOffset);\n  }\n\n  function asUint64(\n    bytes memory encoded,\n    uint offset\n  ) internal pure returns (uint64 ret, uint nextOffset) {\n    (ret, nextOffset) = asUint64Unchecked(encoded, offset);\n    checkBound(nextOffset, encoded.length);\n  }\n\n  function asBytes8Unchecked(\n    bytes memory encoded,\n    uint offset\n  ) internal pure returns (bytes8, uint) {\n    (uint64 ret, uint nextOffset) = asUint64Unchecked(encoded, offset);\n    return (bytes8(ret), nextOffset);\n  }\n\n  function asBytes8(\n    bytes memory encoded,\n    uint offset\n  ) internal pure returns (bytes8, uint) {\n    (uint64 ret, uint nextOffset) = asUint64(encoded, offset);\n    return (bytes8(ret), nextOffset);\n  }\n\n  function asUint72Unchecked(\n    bytes memory encoded,\n    uint offset\n  ) internal pure returns (uint72 ret, uint nextOffset) {\n    assembly (\"memory-safe\") {\n      nextOffset := add(offset, 9)\n      ret := mload(add(encoded, nextOffset))\n    }\n    return (ret, nextOffset);\n  }\n\n  function asUint72(\n    bytes memory encoded,\n    uint offset\n  ) internal pure returns (uint72 ret, uint nextOffset) {\n    (ret, nextOffset) = asUint72Unchecked(encoded, offset);\n    checkBound(nextOffset, encoded.length);\n  }\n\n  function asBytes9Unchecked(\n    bytes memory encoded,\n    uint offset\n  ) internal pure returns (bytes9, uint) {\n    (uint72 ret, uint nextOffset) = asUint72Unchecked(encoded, offset);\n    return (bytes9(ret), nextOffset);\n  }\n\n  function asBytes9(\n    bytes memory encoded,\n    uint offset\n  ) internal pure returns (bytes9, uint) {\n    (uint72 ret, uint nextOffset) = asUint72(encoded, offset);\n    return (bytes9(ret), nextOffset);\n  }\n\n  function asUint80Unchecked(\n    bytes memory encoded,\n    uint offset\n  ) internal pure returns (uint80 ret, uint nextOffset) {\n    assembly (\"memory-safe\") {\n      nextOffset := add(offset, 10)\n      ret := mload(add(encoded, nextOffset))\n    }\n    return (ret, nextOffset);\n  }\n\n  function asUint80(\n    bytes memory encoded,\n    uint offset\n  ) internal pure returns (uint80 ret, uint nextOffset) {\n    (ret, nextOffset) = asUint80Unchecked(encoded, offset);\n    checkBound(nextOffset, encoded.length);\n  }\n\n  function asBytes10Unchecked(\n    bytes memory encoded,\n    uint offset\n  ) internal pure returns (bytes10, uint) {\n    (uint80 ret, uint nextOffset) = asUint80Unchecked(encoded, offset);\n    return (bytes10(ret), nextOffset);\n  }\n\n  function asBytes10(\n    bytes memory encoded,\n    uint offset\n  ) internal pure returns (bytes10, uint) {\n    (uint80 ret, uint nextOffset) = asUint80(encoded, offset);\n    return (bytes10(ret), nextOffset);\n  }\n\n  function asUint88Unchecked(\n    bytes memory encoded,\n    uint offset\n  ) internal pure returns (uint88 ret, uint nextOffset) {\n    assembly (\"memory-safe\") {\n      nextOffset := add(offset, 11)\n      ret := mload(add(encoded, nextOffset))\n    }\n    return (ret, nextOffset);\n  }\n\n  function asUint88(\n    bytes memory encoded,\n    uint offset\n  ) internal pure returns (uint88 ret, uint nextOffset) {\n    (ret, nextOffset) = asUint88Unchecked(encoded, offset);\n    checkBound(nextOffset, encoded.length);\n  }\n\n  function asBytes11Unchecked(\n    bytes memory encoded,\n    uint offset\n  ) internal pure returns (bytes11, uint) {\n    (uint88 ret, uint nextOffset) = asUint88Unchecked(encoded, offset);\n    return (bytes11(ret), nextOffset);\n  }\n\n  function asBytes11(\n    bytes memory encoded,\n    uint offset\n  ) internal pure returns (bytes11, uint) {\n    (uint88 ret, uint nextOffset) = asUint88(encoded, offset);\n    return (bytes11(ret), nextOffset);\n  }\n\n  function asUint96Unchecked(\n    bytes memory encoded,\n    uint offset\n  ) internal pure returns (uint96 ret, uint nextOffset) {\n    assembly (\"memory-safe\") {\n      nextOffset := add(offset, 12)\n      ret := mload(add(encoded, nextOffset))\n    }\n    return (ret, nextOffset);\n  }\n\n  function asUint96(\n    bytes memory encoded,\n    uint offset\n  ) internal pure returns (uint96 ret, uint nextOffset) {\n    (ret, nextOffset) = asUint96Unchecked(encoded, offset);\n    checkBound(nextOffset, encoded.length);\n  }\n\n  function asBytes12Unchecked(\n    bytes memory encoded,\n    uint offset\n  ) internal pure returns (bytes12, uint) {\n    (uint96 ret, uint nextOffset) = asUint96Unchecked(encoded, offset);\n    return (bytes12(ret), nextOffset);\n  }\n\n  function asBytes12(\n    bytes memory encoded,\n    uint offset\n  ) internal pure returns (bytes12, uint) {\n    (uint96 ret, uint nextOffset) = asUint96(encoded, offset);\n    return (bytes12(ret), nextOffset);\n  }\n\n  function asUint104Unchecked(\n    bytes memory encoded,\n    uint offset\n  ) internal pure returns (uint104 ret, uint nextOffset) {\n    assembly (\"memory-safe\") {\n      nextOffset := add(offset, 13)\n      ret := mload(add(encoded, nextOffset))\n    }\n    return (ret, nextOffset);\n  }\n\n  function asUint104(\n    bytes memory encoded,\n    uint offset\n  ) internal pure returns (uint104 ret, uint nextOffset) {\n    (ret, nextOffset) = asUint104Unchecked(encoded, offset);\n    checkBound(nextOffset, encoded.length);\n  }\n\n  function asBytes13Unchecked(\n    bytes memory encoded,\n    uint offset\n  ) internal pure returns (bytes13, uint) {\n    (uint104 ret, uint nextOffset) = asUint104Unchecked(encoded, offset);\n    return (bytes13(ret), nextOffset);\n  }\n\n  function asBytes13(\n    bytes memory encoded,\n    uint offset\n  ) internal pure returns (bytes13, uint) {\n    (uint104 ret, uint nextOffset) = asUint104(encoded, offset);\n    return (bytes13(ret), nextOffset);\n  }\n\n  function asUint112Unchecked(\n    bytes memory encoded,\n    uint offset\n  ) internal pure returns (uint112 ret, uint nextOffset) {\n    assembly (\"memory-safe\") {\n      nextOffset := add(offset, 14)\n      ret := mload(add(encoded, nextOffset))\n    }\n    return (ret, nextOffset);\n  }\n\n  function asUint112(\n    bytes memory encoded,\n    uint offset\n  ) internal pure returns (uint112 ret, uint nextOffset) {\n    (ret, nextOffset) = asUint112Unchecked(encoded, offset);\n    checkBound(nextOffset, encoded.length);\n  }\n\n  function asBytes14Unchecked(\n    bytes memory encoded,\n    uint offset\n  ) internal pure returns (bytes14, uint) {\n    (uint112 ret, uint nextOffset) = asUint112Unchecked(encoded, offset);\n    return (bytes14(ret), nextOffset);\n  }\n\n  function asBytes14(\n    bytes memory encoded,\n    uint offset\n  ) internal pure returns (bytes14, uint) {\n    (uint112 ret, uint nextOffset) = asUint112(encoded, offset);\n    return (bytes14(ret), nextOffset);\n  }\n\n  function asUint120Unchecked(\n    bytes memory encoded,\n    uint offset\n  ) internal pure returns (uint120 ret, uint nextOffset) {\n    assembly (\"memory-safe\") {\n      nextOffset := add(offset, 15)\n      ret := mload(add(encoded, nextOffset))\n    }\n    return (ret, nextOffset);\n  }\n\n  function asUint120(\n    bytes memory encoded,\n    uint offset\n  ) internal pure returns (uint120 ret, uint nextOffset) {\n    (ret, nextOffset) = asUint120Unchecked(encoded, offset);\n    checkBound(nextOffset, encoded.length);\n  }\n\n  function asBytes15Unchecked(\n    bytes memory encoded,\n    uint offset\n  ) internal pure returns (bytes15, uint) {\n    (uint120 ret, uint nextOffset) = asUint120Unchecked(encoded, offset);\n    return (bytes15(ret), nextOffset);\n  }\n\n  function asBytes15(\n    bytes memory encoded,\n    uint offset\n  ) internal pure returns (bytes15, uint) {\n    (uint120 ret, uint nextOffset) = asUint120(encoded, offset);\n    return (bytes15(ret), nextOffset);\n  }\n\n  function asUint128Unchecked(\n    bytes memory encoded,\n    uint offset\n  ) internal pure returns (uint128 ret, uint nextOffset) {\n    assembly (\"memory-safe\") {\n      nextOffset := add(offset, 16)\n      ret := mload(add(encoded, nextOffset))\n    }\n    return (ret, nextOffset);\n  }\n\n  function asUint128(\n    bytes memory encoded,\n    uint offset\n  ) internal pure returns (uint128 ret, uint nextOffset) {\n    (ret, nextOffset) = asUint128Unchecked(encoded, offset);\n    checkBound(nextOffset, encoded.length);\n  }\n\n  function asBytes16Unchecked(\n    bytes memory encoded,\n    uint offset\n  ) internal pure returns (bytes16, uint) {\n    (uint128 ret, uint nextOffset) = asUint128Unchecked(encoded, offset);\n    return (bytes16(ret), nextOffset);\n  }\n\n  function asBytes16(\n    bytes memory encoded,\n    uint offset\n  ) internal pure returns (bytes16, uint) {\n    (uint128 ret, uint nextOffset) = asUint128(encoded, offset);\n    return (bytes16(ret), nextOffset);\n  }\n\n  function asUint136Unchecked(\n    bytes memory encoded,\n    uint offset\n  ) internal pure returns (uint136 ret, uint nextOffset) {\n    assembly (\"memory-safe\") {\n      nextOffset := add(offset, 17)\n      ret := mload(add(encoded, nextOffset))\n    }\n    return (ret, nextOffset);\n  }\n\n  function asUint136(\n    bytes memory encoded,\n    uint offset\n  ) internal pure returns (uint136 ret, uint nextOffset) {\n    (ret, nextOffset) = asUint136Unchecked(encoded, offset);\n    checkBound(nextOffset, encoded.length);\n  }\n\n  function asBytes17Unchecked(\n    bytes memory encoded,\n    uint offset\n  ) internal pure returns (bytes17, uint) {\n    (uint136 ret, uint nextOffset) = asUint136Unchecked(encoded, offset);\n    return (bytes17(ret), nextOffset);\n  }\n\n  function asBytes17(\n    bytes memory encoded,\n    uint offset\n  ) internal pure returns (bytes17, uint) {\n    (uint136 ret, uint nextOffset) = asUint136(encoded, offset);\n    return (bytes17(ret), nextOffset);\n  }\n\n  function asUint144Unchecked(\n    bytes memory encoded,\n    uint offset\n  ) internal pure returns (uint144 ret, uint nextOffset) {\n    assembly (\"memory-safe\") {\n      nextOffset := add(offset, 18)\n      ret := mload(add(encoded, nextOffset))\n    }\n    return (ret, nextOffset);\n  }\n\n  function asUint144(\n    bytes memory encoded,\n    uint offset\n  ) internal pure returns (uint144 ret, uint nextOffset) {\n    (ret, nextOffset) = asUint144Unchecked(encoded, offset);\n    checkBound(nextOffset, encoded.length);\n  }\n\n  function asBytes18Unchecked(\n    bytes memory encoded,\n    uint offset\n  ) internal pure returns (bytes18, uint) {\n    (uint144 ret, uint nextOffset) = asUint144Unchecked(encoded, offset);\n    return (bytes18(ret), nextOffset);\n  }\n\n  function asBytes18(\n    bytes memory encoded,\n    uint offset\n  ) internal pure returns (bytes18, uint) {\n    (uint144 ret, uint nextOffset) = asUint144(encoded, offset);\n    return (bytes18(ret), nextOffset);\n  }\n\n  function asUint152Unchecked(\n    bytes memory encoded,\n    uint offset\n  ) internal pure returns (uint152 ret, uint nextOffset) {\n    assembly (\"memory-safe\") {\n      nextOffset := add(offset, 19)\n      ret := mload(add(encoded, nextOffset))\n    }\n    return (ret, nextOffset);\n  }\n\n  function asUint152(\n    bytes memory encoded,\n    uint offset\n  ) internal pure returns (uint152 ret, uint nextOffset) {\n    (ret, nextOffset) = asUint152Unchecked(encoded, offset);\n    checkBound(nextOffset, encoded.length);\n  }\n\n  function asBytes19Unchecked(\n    bytes memory encoded,\n    uint offset\n  ) internal pure returns (bytes19, uint) {\n    (uint152 ret, uint nextOffset) = asUint152Unchecked(encoded, offset);\n    return (bytes19(ret), nextOffset);\n  }\n\n  function asBytes19(\n    bytes memory encoded,\n    uint offset\n  ) internal pure returns (bytes19, uint) {\n    (uint152 ret, uint nextOffset) = asUint152(encoded, offset);\n    return (bytes19(ret), nextOffset);\n  }\n\n  function asUint160Unchecked(\n    bytes memory encoded,\n    uint offset\n  ) internal pure returns (uint160 ret, uint nextOffset) {\n    assembly (\"memory-safe\") {\n      nextOffset := add(offset, 20)\n      ret := mload(add(encoded, nextOffset))\n    }\n    return (ret, nextOffset);\n  }\n\n  function asUint160(\n    bytes memory encoded,\n    uint offset\n  ) internal pure returns (uint160 ret, uint nextOffset) {\n    (ret, nextOffset) = asUint160Unchecked(encoded, offset);\n    checkBound(nextOffset, encoded.length);\n  }\n\n  function asBytes20Unchecked(\n    bytes memory encoded,\n    uint offset\n  ) internal pure returns (bytes20, uint) {\n    (uint160 ret, uint nextOffset) = asUint160Unchecked(encoded, offset);\n    return (bytes20(ret), nextOffset);\n  }\n\n  function asBytes20(\n    bytes memory encoded,\n    uint offset\n  ) internal pure returns (bytes20, uint) {\n    (uint160 ret, uint nextOffset) = asUint160(encoded, offset);\n    return (bytes20(ret), nextOffset);\n  }\n\n  function asUint168Unchecked(\n    bytes memory encoded,\n    uint offset\n  ) internal pure returns (uint168 ret, uint nextOffset) {\n    assembly (\"memory-safe\") {\n      nextOffset := add(offset, 21)\n      ret := mload(add(encoded, nextOffset))\n    }\n    return (ret, nextOffset);\n  }\n\n  function asUint168(\n    bytes memory encoded,\n    uint offset\n  ) internal pure returns (uint168 ret, uint nextOffset) {\n    (ret, nextOffset) = asUint168Unchecked(encoded, offset);\n    checkBound(nextOffset, encoded.length);\n  }\n\n  function asBytes21Unchecked(\n    bytes memory encoded,\n    uint offset\n  ) internal pure returns (bytes21, uint) {\n    (uint168 ret, uint nextOffset) = asUint168Unchecked(encoded, offset);\n    return (bytes21(ret), nextOffset);\n  }\n\n  function asBytes21(\n    bytes memory encoded,\n    uint offset\n  ) internal pure returns (bytes21, uint) {\n    (uint168 ret, uint nextOffset) = asUint168(encoded, offset);\n    return (bytes21(ret), nextOffset);\n  }\n\n  function asUint176Unchecked(\n    bytes memory encoded,\n    uint offset\n  ) internal pure returns (uint176 ret, uint nextOffset) {\n    assembly (\"memory-safe\") {\n      nextOffset := add(offset, 22)\n      ret := mload(add(encoded, nextOffset))\n    }\n    return (ret, nextOffset);\n  }\n\n  function asUint176(\n    bytes memory encoded,\n    uint offset\n  ) internal pure returns (uint176 ret, uint nextOffset) {\n    (ret, nextOffset) = asUint176Unchecked(encoded, offset);\n    checkBound(nextOffset, encoded.length);\n  }\n\n  function asBytes22Unchecked(\n    bytes memory encoded,\n    uint offset\n  ) internal pure returns (bytes22, uint) {\n    (uint176 ret, uint nextOffset) = asUint176Unchecked(encoded, offset);\n    return (bytes22(ret), nextOffset);\n  }\n\n  function asBytes22(\n    bytes memory encoded,\n    uint offset\n  ) internal pure returns (bytes22, uint) {\n    (uint176 ret, uint nextOffset) = asUint176(encoded, offset);\n    return (bytes22(ret), nextOffset);\n  }\n\n  function asUint184Unchecked(\n    bytes memory encoded,\n    uint offset\n  ) internal pure returns (uint184 ret, uint nextOffset) {\n    assembly (\"memory-safe\") {\n      nextOffset := add(offset, 23)\n      ret := mload(add(encoded, nextOffset))\n    }\n    return (ret, nextOffset);\n  }\n\n  function asUint184(\n    bytes memory encoded,\n    uint offset\n  ) internal pure returns (uint184 ret, uint nextOffset) {\n    (ret, nextOffset) = asUint184Unchecked(encoded, offset);\n    checkBound(nextOffset, encoded.length);\n  }\n\n  function asBytes23Unchecked(\n    bytes memory encoded,\n    uint offset\n  ) internal pure returns (bytes23, uint) {\n    (uint184 ret, uint nextOffset) = asUint184Unchecked(encoded, offset);\n    return (bytes23(ret), nextOffset);\n  }\n\n  function asBytes23(\n    bytes memory encoded,\n    uint offset\n  ) internal pure returns (bytes23, uint) {\n    (uint184 ret, uint nextOffset) = asUint184(encoded, offset);\n    return (bytes23(ret), nextOffset);\n  }\n\n  function asUint192Unchecked(\n    bytes memory encoded,\n    uint offset\n  ) internal pure returns (uint192 ret, uint nextOffset) {\n    assembly (\"memory-safe\") {\n      nextOffset := add(offset, 24)\n      ret := mload(add(encoded, nextOffset))\n    }\n    return (ret, nextOffset);\n  }\n\n  function asUint192(\n    bytes memory encoded,\n    uint offset\n  ) internal pure returns (uint192 ret, uint nextOffset) {\n    (ret, nextOffset) = asUint192Unchecked(encoded, offset);\n    checkBound(nextOffset, encoded.length);\n  }\n\n  function asBytes24Unchecked(\n    bytes memory encoded,\n    uint offset\n  ) internal pure returns (bytes24, uint) {\n    (uint192 ret, uint nextOffset) = asUint192Unchecked(encoded, offset);\n    return (bytes24(ret), nextOffset);\n  }\n\n  function asBytes24(\n    bytes memory encoded,\n    uint offset\n  ) internal pure returns (bytes24, uint) {\n    (uint192 ret, uint nextOffset) = asUint192(encoded, offset);\n    return (bytes24(ret), nextOffset);\n  }\n\n  function asUint200Unchecked(\n    bytes memory encoded,\n    uint offset\n  ) internal pure returns (uint200 ret, uint nextOffset) {\n    assembly (\"memory-safe\") {\n      nextOffset := add(offset, 25)\n      ret := mload(add(encoded, nextOffset))\n    }\n    return (ret, nextOffset);\n  }\n\n  function asUint200(\n    bytes memory encoded,\n    uint offset\n  ) internal pure returns (uint200 ret, uint nextOffset) {\n    (ret, nextOffset) = asUint200Unchecked(encoded, offset);\n    checkBound(nextOffset, encoded.length);\n  }\n\n  function asBytes25Unchecked(\n    bytes memory encoded,\n    uint offset\n  ) internal pure returns (bytes25, uint) {\n    (uint200 ret, uint nextOffset) = asUint200Unchecked(encoded, offset);\n    return (bytes25(ret), nextOffset);\n  }\n\n  function asBytes25(\n    bytes memory encoded,\n    uint offset\n  ) internal pure returns (bytes25, uint) {\n    (uint200 ret, uint nextOffset) = asUint200(encoded, offset);\n    return (bytes25(ret), nextOffset);\n  }\n\n  function asUint208Unchecked(\n    bytes memory encoded,\n    uint offset\n  ) internal pure returns (uint208 ret, uint nextOffset) {\n    assembly (\"memory-safe\") {\n      nextOffset := add(offset, 26)\n      ret := mload(add(encoded, nextOffset))\n    }\n    return (ret, nextOffset);\n  }\n\n  function asUint208(\n    bytes memory encoded,\n    uint offset\n  ) internal pure returns (uint208 ret, uint nextOffset) {\n    (ret, nextOffset) = asUint208Unchecked(encoded, offset);\n    checkBound(nextOffset, encoded.length);\n  }\n\n  function asBytes26Unchecked(\n    bytes memory encoded,\n    uint offset\n  ) internal pure returns (bytes26, uint) {\n    (uint208 ret, uint nextOffset) = asUint208Unchecked(encoded, offset);\n    return (bytes26(ret), nextOffset);\n  }\n\n  function asBytes26(\n    bytes memory encoded,\n    uint offset\n  ) internal pure returns (bytes26, uint) {\n    (uint208 ret, uint nextOffset) = asUint208(encoded, offset);\n    return (bytes26(ret), nextOffset);\n  }\n\n  function asUint216Unchecked(\n    bytes memory encoded,\n    uint offset\n  ) internal pure returns (uint216 ret, uint nextOffset) {\n    assembly (\"memory-safe\") {\n      nextOffset := add(offset, 27)\n      ret := mload(add(encoded, nextOffset))\n    }\n    return (ret, nextOffset);\n  }\n\n  function asUint216(\n    bytes memory encoded,\n    uint offset\n  ) internal pure returns (uint216 ret, uint nextOffset) {\n    (ret, nextOffset) = asUint216Unchecked(encoded, offset);\n    checkBound(nextOffset, encoded.length);\n  }\n\n  function asBytes27Unchecked(\n    bytes memory encoded,\n    uint offset\n  ) internal pure returns (bytes27, uint) {\n    (uint216 ret, uint nextOffset) = asUint216Unchecked(encoded, offset);\n    return (bytes27(ret), nextOffset);\n  }\n\n  function asBytes27(\n    bytes memory encoded,\n    uint offset\n  ) internal pure returns (bytes27, uint) {\n    (uint216 ret, uint nextOffset) = asUint216(encoded, offset);\n    return (bytes27(ret), nextOffset);\n  }\n\n  function asUint224Unchecked(\n    bytes memory encoded,\n    uint offset\n  ) internal pure returns (uint224 ret, uint nextOffset) {\n    assembly (\"memory-safe\") {\n      nextOffset := add(offset, 28)\n      ret := mload(add(encoded, nextOffset))\n    }\n    return (ret, nextOffset);\n  }\n\n  function asUint224(\n    bytes memory encoded,\n    uint offset\n  ) internal pure returns (uint224 ret, uint nextOffset) {\n    (ret, nextOffset) = asUint224Unchecked(encoded, offset);\n    checkBound(nextOffset, encoded.length);\n  }\n\n  function asBytes28Unchecked(\n    bytes memory encoded,\n    uint offset\n  ) internal pure returns (bytes28, uint) {\n    (uint224 ret, uint nextOffset) = asUint224Unchecked(encoded, offset);\n    return (bytes28(ret), nextOffset);\n  }\n\n  function asBytes28(\n    bytes memory encoded,\n    uint offset\n  ) internal pure returns (bytes28, uint) {\n    (uint224 ret, uint nextOffset) = asUint224(encoded, offset);\n    return (bytes28(ret), nextOffset);\n  }\n\n  function asUint232Unchecked(\n    bytes memory encoded,\n    uint offset\n  ) internal pure returns (uint232 ret, uint nextOffset) {\n    assembly (\"memory-safe\") {\n      nextOffset := add(offset, 29)\n      ret := mload(add(encoded, nextOffset))\n    }\n    return (ret, nextOffset);\n  }\n\n  function asUint232(\n    bytes memory encoded,\n    uint offset\n  ) internal pure returns (uint232 ret, uint nextOffset) {\n    (ret, nextOffset) = asUint232Unchecked(encoded, offset);\n    checkBound(nextOffset, encoded.length);\n  }\n\n  function asBytes29Unchecked(\n    bytes memory encoded,\n    uint offset\n  ) internal pure returns (bytes29, uint) {\n    (uint232 ret, uint nextOffset) = asUint232Unchecked(encoded, offset);\n    return (bytes29(ret), nextOffset);\n  }\n\n  function asBytes29(\n    bytes memory encoded,\n    uint offset\n  ) internal pure returns (bytes29, uint) {\n    (uint232 ret, uint nextOffset) = asUint232(encoded, offset);\n    return (bytes29(ret), nextOffset);\n  }\n\n  function asUint240Unchecked(\n    bytes memory encoded,\n    uint offset\n  ) internal pure returns (uint240 ret, uint nextOffset) {\n    assembly (\"memory-safe\") {\n      nextOffset := add(offset, 30)\n      ret := mload(add(encoded, nextOffset))\n    }\n    return (ret, nextOffset);\n  }\n\n  function asUint240(\n    bytes memory encoded,\n    uint offset\n  ) internal pure returns (uint240 ret, uint nextOffset) {\n    (ret, nextOffset) = asUint240Unchecked(encoded, offset);\n    checkBound(nextOffset, encoded.length);\n  }\n\n  function asBytes30Unchecked(\n    bytes memory encoded,\n    uint offset\n  ) internal pure returns (bytes30, uint) {\n    (uint240 ret, uint nextOffset) = asUint240Unchecked(encoded, offset);\n    return (bytes30(ret), nextOffset);\n  }\n\n  function asBytes30(\n    bytes memory encoded,\n    uint offset\n  ) internal pure returns (bytes30, uint) {\n    (uint240 ret, uint nextOffset) = asUint240(encoded, offset);\n    return (bytes30(ret), nextOffset);\n  }\n\n  function asUint248Unchecked(\n    bytes memory encoded,\n    uint offset\n  ) internal pure returns (uint248 ret, uint nextOffset) {\n    assembly (\"memory-safe\") {\n      nextOffset := add(offset, 31)\n      ret := mload(add(encoded, nextOffset))\n    }\n    return (ret, nextOffset);\n  }\n\n  function asUint248(\n    bytes memory encoded,\n    uint offset\n  ) internal pure returns (uint248 ret, uint nextOffset) {\n    (ret, nextOffset) = asUint248Unchecked(encoded, offset);\n    checkBound(nextOffset, encoded.length);\n  }\n\n  function asBytes31Unchecked(\n    bytes memory encoded,\n    uint offset\n  ) internal pure returns (bytes31, uint) {\n    (uint248 ret, uint nextOffset) = asUint248Unchecked(encoded, offset);\n    return (bytes31(ret), nextOffset);\n  }\n\n  function asBytes31(\n    bytes memory encoded,\n    uint offset\n  ) internal pure returns (bytes31, uint) {\n    (uint248 ret, uint nextOffset) = asUint248(encoded, offset);\n    return (bytes31(ret), nextOffset);\n  }\n\n  function asUint256Unchecked(\n    bytes memory encoded,\n    uint offset\n  ) internal pure returns (uint256 ret, uint nextOffset) {\n    assembly (\"memory-safe\") {\n      nextOffset := add(offset, 32)\n      ret := mload(add(encoded, nextOffset))\n    }\n    return (ret, nextOffset);\n  }\n\n  function asUint256(\n    bytes memory encoded,\n    uint offset\n  ) internal pure returns (uint256 ret, uint nextOffset) {\n    (ret, nextOffset) = asUint256Unchecked(encoded, offset);\n    checkBound(nextOffset, encoded.length);\n  }\n\n  function asBytes32Unchecked(\n    bytes memory encoded,\n    uint offset\n  ) internal pure returns (bytes32, uint) {\n    (uint256 ret, uint nextOffset) = asUint256Unchecked(encoded, offset);\n    return (bytes32(ret), nextOffset);\n  }\n\n  function asBytes32(\n    bytes memory encoded,\n    uint offset\n  ) internal pure returns (bytes32, uint) {\n    (uint256 ret, uint nextOffset) = asUint256(encoded, offset);\n    return (bytes32(ret), nextOffset);\n  }\n}\n"},{"file_path":"lib/native-token-transfers/evm/src/interfaces/ITransceiver.sol","source_code":"// SPDX-License-Identifier: Apache 2\npragma solidity >=0.8.8 <0.9.0;\n\nimport \"../libraries/TransceiverStructs.sol\";\n\ninterface ITransceiver {\n    /// @notice The caller is not the deployer.\n    /// @dev Selector: 0xc68a0e42.\n    /// @param deployer The address of the deployer.\n    /// @param caller The address of the caller.\n    error UnexpectedDeployer(address deployer, address caller);\n\n    /// @notice The caller is not the NttManager.\n    /// @dev Selector: 0xc5aa6153.\n    /// @param caller The address of the caller.\n    error CallerNotNttManager(address caller);\n\n    /// @notice Error when trying renounce transceiver ownership.\n    ///         Ensures the owner of the transceiver is in sync with\n    ///         the owner of the NttManager.\n    /// @dev Selector: 0x66791dd6.\n    /// @param currentOwner he current owner of the transceiver.\n    error CannotRenounceTransceiverOwnership(address currentOwner);\n\n    /// @notice Error when trying to transfer transceiver ownership.\n    /// @dev Selector: 0x306239eb.\n    /// @param currentOwner The current owner of the transceiver.\n    /// @param newOwner The new owner of the transceiver.\n    error CannotTransferTransceiverOwnership(address currentOwner, address newOwner);\n\n    /// @notice Error when the recipient NttManager address is not the\n    ///         corresponding manager of the transceiver.\n    /// @dev Selector: 0x73bdd322.\n    /// @param recipientNttManagerAddress The address of the recipient NttManager.\n    /// @param expectedRecipientNttManagerAddress The expected address of the recipient NttManager.\n    error UnexpectedRecipientNttManagerAddress(\n        bytes32 recipientNttManagerAddress, bytes32 expectedRecipientNttManagerAddress\n    );\n\n    /// @notice Returns the owner address of the NTT Manager that this transceiver is related to.\n    function getNttManagerOwner() external view returns (address);\n\n    /// @notice Returns the address of the token associated with this NTT deployment.\n    function getNttManagerToken() external view returns (address);\n\n    /// @notice Returns the string type of the transceiver. E.g. \"wormhole\", \"axelar\", etc.\n    function getTransceiverType() external view returns (string memory);\n\n    /// @notice Fetch the delivery price for a given recipient chain transfer.\n    /// @param recipientChain The Wormhole chain ID of the target chain.\n    /// @param instruction An additional Instruction provided by the Transceiver to be\n    ///        executed on the recipient chain.\n    /// @return deliveryPrice The cost of delivering a message to the recipient chain,\n    ///         in this chain's native token.\n    function quoteDeliveryPrice(\n        uint16 recipientChain,\n        TransceiverStructs.TransceiverInstruction memory instruction\n    ) external view returns (uint256);\n\n    /// @dev Send a message to another chain.\n    /// @param recipientChain The Wormhole chain ID of the recipient.\n    /// @param instruction An additional Instruction provided by the Transceiver to be\n    /// executed on the recipient chain.\n    /// @param nttManagerMessage A message to be sent to the nttManager on the recipient chain.\n    /// @param recipientNttManagerAddress The Wormhole formatted address of the peer NTT Manager on the recipient chain.\n    /// @param refundAddress The Wormhole formatted address of the refund recipient\n    function sendMessage(\n        uint16 recipientChain,\n        TransceiverStructs.TransceiverInstruction memory instruction,\n        bytes memory nttManagerMessage,\n        bytes32 recipientNttManagerAddress,\n        bytes32 refundAddress\n    ) external payable;\n\n    /// @notice Upgrades the transceiver to a new implementation.\n    /// @param newImplementation The address of the new implementation contract\n    function upgrade(\n        address newImplementation\n    ) external;\n\n    /// @notice Transfers the ownership of the transceiver to a new address.\n    /// @param newOwner The address of the new owner\n    function transferTransceiverOwnership(\n        address newOwner\n    ) external;\n}\n"},{"file_path":"lib/native-token-transfers/evm/lib/openzeppelin-contracts/contracts/utils/Context.sol","source_code":"// 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"},{"file_path":"lib/native-token-transfers/evm/src/libraries/Implementation.sol","source_code":"// SPDX-License-Identifier: Apache 2\npragma solidity >=0.8.8 <0.9.0;\n\nimport \"./external/Initializable.sol\";\nimport \"openzeppelin-contracts/contracts/proxy/ERC1967/ERC1967Upgrade.sol\";\n\n/// @dev This contract should be used as a base contract for implementation contracts\n///      that are used with ERC1967Proxy.\n///      It ensures that the contract cannot be initialized directly, only through\n///      the proxy (by disabling initializers in the constructor).\n///      It also exposes a migrate function that is called during upgrades.\nabstract contract Implementation is Initializable, ERC1967Upgrade {\n    address immutable _this;\n\n    error OnlyDelegateCall();\n    error NotMigrating();\n\n    constructor() {\n        _disableInitializers();\n        _this = address(this);\n    }\n\n    modifier onlyDelegateCall() {\n        _checkDelegateCall();\n        _;\n    }\n\n    struct _Migrating {\n        bool isMigrating;\n    }\n\n    struct _Bool {\n        bool value;\n    }\n\n    bytes32 private constant MIGRATING_SLOT = bytes32(uint256(keccak256(\"ntt.migrating\")) - 1);\n\n    bytes32 private constant MIGRATES_IMMUTABLES_SLOT =\n        bytes32(uint256(keccak256(\"ntt.migratesImmutables\")) - 1);\n\n    function _getMigratingStorage() private pure returns (_Migrating storage $) {\n        uint256 slot = uint256(MIGRATING_SLOT);\n        assembly (\"memory-safe\") {\n            $.slot := slot\n        }\n    }\n\n    function _getMigratesImmutablesStorage() internal pure returns (_Bool storage $) {\n        uint256 slot = uint256(MIGRATES_IMMUTABLES_SLOT);\n        assembly (\"memory-safe\") {\n            $.slot := slot\n        }\n    }\n\n    function _checkDelegateCall() internal view {\n        if (address(this) == _this) {\n            revert OnlyDelegateCall();\n        }\n    }\n\n    function initialize() external payable onlyDelegateCall initializer {\n        _initialize();\n    }\n\n    function migrate() external onlyDelegateCall reinitializer(_getInitializedVersion() + 1) {\n        // NOTE: we add the reinitializer() modifier so that onlyInitializing\n        // functions can be called inside\n        if (!_getMigratingStorage().isMigrating) {\n            revert NotMigrating();\n        }\n        _migrate();\n    }\n\n    function _migrate() internal virtual;\n\n    function _initialize() internal virtual;\n\n    function _checkImmutables() internal view virtual;\n\n    function _upgrade(\n        address newImplementation\n    ) internal {\n        _checkDelegateCall();\n        _upgradeTo(newImplementation);\n\n        _Migrating storage _migrating = _getMigratingStorage();\n        assert(!_migrating.isMigrating);\n        _migrating.isMigrating = true;\n\n        this.migrate();\n        if (!this.getMigratesImmutables()) {\n            _checkImmutables();\n        }\n        _setMigratesImmutables(false);\n\n        _migrating.isMigrating = false;\n    }\n\n    function getMigratesImmutables() public view returns (bool) {\n        return _getMigratesImmutablesStorage().value;\n    }\n\n    function _setMigratesImmutables(\n        bool value\n    ) internal {\n        _getMigratesImmutablesStorage().value = value;\n    }\n}\n"},{"file_path":"lib/native-token-transfers/evm/src/NttManager/TransceiverRegistry.sol","source_code":"// SPDX-License-Identifier: Apache 2\npragma solidity >=0.8.8 <0.9.0;\n\n/// @title TransceiverRegistry\n/// @author Wormhole Project Contributors.\n/// @notice This contract is responsible for handling the registration of Transceivers.\n/// @dev This contract checks that a few critical invariants hold when transceivers are added or removed,\n///      including:\n///         1. If a transceiver is not registered, it should be enabled.\n///         2. The value set in the bitmap of trannsceivers\n///            should directly correspond to the whether the transceiver is enabled\nabstract contract TransceiverRegistry {\n    constructor() {\n        _checkTransceiversInvariants();\n    }\n\n    /// @dev Information about registered transceivers.\n    struct TransceiverInfo {\n        // whether this transceiver is registered\n        bool registered;\n        // whether this transceiver is enabled\n        bool enabled;\n        uint8 index;\n    }\n\n    /// @dev Bitmap encoding the enabled transceivers.\n    /// invariant: forall (i: uint8), enabledTransceiverBitmap & i == 1 <=> transceiverInfos[i].enabled\n    struct _EnabledTransceiverBitmap {\n        uint64 bitmap;\n    }\n\n    /// @dev Total number of registered transceivers. This number can only increase.\n    /// invariant: numRegisteredTransceivers <= MAX_TRANSCEIVERS\n    /// invariant: forall (i: uint8),\n    ///   i < numRegisteredTransceivers <=> exists (a: address), transceiverInfos[a].index == i\n    struct _NumTransceivers {\n        uint8 registered;\n        uint8 enabled;\n    }\n\n    uint8 constant MAX_TRANSCEIVERS = 64;\n\n    /// @notice Error when the caller is not the transceiver.\n    /// @dev Selector 0xa0ae911d.\n    /// @param caller The address of the caller.\n    error CallerNotTransceiver(address caller);\n\n    /// @notice Error when the transceiver is the zero address.\n    /// @dev Selector 0x2f44bd77.\n    error InvalidTransceiverZeroAddress();\n\n    /// @notice Error when the transceiver is disabled.\n    /// @dev Selector 0x1f61ba44.\n    error DisabledTransceiver(address transceiver);\n\n    /// @notice Error when the number of registered transceivers\n    ///         exceeeds (MAX_TRANSCEIVERS = 64).\n    /// @dev Selector 0x891684c3.\n    error TooManyTransceivers();\n\n    /// @notice Error when attempting to remove a transceiver\n    ///         that is not registered.\n    /// @dev Selector 0xd583f470.\n    /// @param transceiver The address of the transceiver.\n    error NonRegisteredTransceiver(address transceiver);\n\n    /// @notice Error when attempting to enable a transceiver that is already enabled.\n    /// @dev Selector 0x8d68f84d.\n    /// @param transceiver The address of the transceiver.\n    error TransceiverAlreadyEnabled(address transceiver);\n\n    modifier onlyTransceiver() {\n        if (!_getTransceiverInfosStorage()[msg.sender].enabled) {\n            revert CallerNotTransceiver(msg.sender);\n        }\n        _;\n    }\n\n    // =============== Storage ===============================================\n\n    bytes32 private constant TRANSCEIVER_INFOS_SLOT =\n        bytes32(uint256(keccak256(\"ntt.transceiverInfos\")) - 1);\n\n    bytes32 private constant TRANSCEIVER_BITMAP_SLOT =\n        bytes32(uint256(keccak256(\"ntt.transceiverBitmap\")) - 1);\n\n    bytes32 private constant ENABLED_TRANSCEIVERS_SLOT =\n        bytes32(uint256(keccak256(\"ntt.enabledTransceivers\")) - 1);\n\n    bytes32 private constant REGISTERED_TRANSCEIVERS_SLOT =\n        bytes32(uint256(keccak256(\"ntt.registeredTransceivers\")) - 1);\n\n    bytes32 private constant NUM_REGISTERED_TRANSCEIVERS_SLOT =\n        bytes32(uint256(keccak256(\"ntt.numRegisteredTransceivers\")) - 1);\n\n    function _getTransceiverInfosStorage()\n        internal\n        pure\n        returns (mapping(address => TransceiverInfo) storage $)\n    {\n        uint256 slot = uint256(TRANSCEIVER_INFOS_SLOT);\n        assembly (\"memory-safe\") {\n            $.slot := slot\n        }\n    }\n\n    function _getEnabledTransceiversStorage() internal pure returns (address[] storage $) {\n        uint256 slot = uint256(ENABLED_TRANSCEIVERS_SLOT);\n        assembly (\"memory-safe\") {\n            $.slot := slot\n        }\n    }\n\n    function _getTransceiverBitmapStorage()\n        private\n        pure\n        returns (_EnabledTransceiverBitmap storage $)\n    {\n        uint256 slot = uint256(TRANSCEIVER_BITMAP_SLOT);\n        assembly (\"memory-safe\") {\n            $.slot := slot\n        }\n    }\n\n    function _getRegisteredTransceiversStorage() internal pure returns (address[] storage $) {\n        uint256 slot = uint256(REGISTERED_TRANSCEIVERS_SLOT);\n        assembly (\"memory-safe\") {\n            $.slot := slot\n        }\n    }\n\n    function _getNumTransceiversStorage() internal pure returns (_NumTransceivers storage $) {\n        uint256 slot = uint256(NUM_REGISTERED_TRANSCEIVERS_SLOT);\n        assembly (\"memory-safe\") {\n            $.slot := slot\n        }\n    }\n\n    // =============== Storage Getters/Setters ========================================\n\n    function _setTransceiver(\n        address transceiver\n    ) internal returns (uint8 index) {\n        mapping(address => TransceiverInfo) storage transceiverInfos = _getTransceiverInfosStorage();\n        _EnabledTransceiverBitmap storage _enabledTransceiverBitmap = _getTransceiverBitmapStorage();\n        address[] storage _enabledTransceivers = _getEnabledTransceiversStorage();\n\n        _NumTransceivers storage _numTransceivers = _getNumTransceiversStorage();\n\n        if (transceiver == address(0)) {\n            revert InvalidTransceiverZeroAddress();\n        }\n\n        if (transceiverInfos[transceiver].registered) {\n            transceiverInfos[transceiver].enabled = true;\n        } else {\n            if (_numTransceivers.registered >= MAX_TRANSCEIVERS) {\n                revert TooManyTransceivers();\n            }\n\n            transceiverInfos[transceiver] = TransceiverInfo({\n                registered: true,\n                enabled: true,\n                index: _numTransceivers.registered\n            });\n            _numTransceivers.registered++;\n            _getRegisteredTransceiversStorage().push(transceiver);\n        }\n\n        _enabledTransceivers.push(transceiver);\n        _numTransceivers.enabled++;\n\n        uint64 updatedEnabledTransceiverBitmap =\n            _enabledTransceiverBitmap.bitmap | uint64(1 << transceiverInfos[transceiver].index);\n        // ensure that this actually changed the bitmap\n        if (updatedEnabledTransceiverBitmap == _enabledTransceiverBitmap.bitmap) {\n            revert TransceiverAlreadyEnabled(transceiver);\n        }\n        _enabledTransceiverBitmap.bitmap = updatedEnabledTransceiverBitmap;\n\n        _checkTransceiversInvariants();\n\n        return transceiverInfos[transceiver].index;\n    }\n\n    function _removeTransceiver(\n        address transceiver\n    ) internal {\n        mapping(address => TransceiverInfo) storage transceiverInfos = _getTransceiverInfosStorage();\n        _EnabledTransceiverBitmap storage _enabledTransceiverBitmap = _getTransceiverBitmapStorage();\n        address[] storage _enabledTransceivers = _getEnabledTransceiversStorage();\n\n        if (transceiver == address(0)) {\n            revert InvalidTransceiverZeroAddress();\n        }\n\n        if (!transceiverInfos[transceiver].registered) {\n            revert NonRegisteredTransceiver(transceiver);\n        }\n\n        if (!transceiverInfos[transceiver].enabled) {\n            revert DisabledTransceiver(transceiver);\n        }\n\n        transceiverInfos[transceiver].enabled = false;\n        _getNumTransceiversStorage().enabled--;\n\n        uint64 updatedEnabledTransceiverBitmap =\n            _enabledTransceiverBitmap.bitmap & uint64(~(1 << transceiverInfos[transceiver].index));\n        // ensure that this actually changed the bitmap\n        assert(updatedEnabledTransceiverBitmap < _enabledTransceiverBitmap.bitmap);\n        _enabledTransceiverBitmap.bitmap = updatedEnabledTransceiverBitmap;\n\n        bool removed = false;\n\n        uint256 numEnabledTransceivers = _enabledTransceivers.length;\n        for (uint256 i = 0; i < numEnabledTransceivers; i++) {\n            if (_enabledTransceivers[i] == transceiver) {\n                _enabledTransceivers[i] = _enabledTransceivers[numEnabledTransceivers - 1];\n                _enabledTransceivers.pop();\n                removed = true;\n                break;\n            }\n        }\n        assert(removed);\n\n        _checkTransceiversInvariants();\n        // we call the invariant check on the transceiver here as well, since\n        // the above check only iterates through the enabled transceivers.\n        _checkTransceiverInvariants(transceiver);\n    }\n\n    function _getEnabledTransceiversBitmap() internal view virtual returns (uint64 bitmap) {\n        return _getTransceiverBitmapStorage().bitmap;\n    }\n\n    /// @notice Returns the Transceiver contracts that have been enabled via governance.\n    function getTransceivers() external pure returns (address[] memory result) {\n        result = _getEnabledTransceiversStorage();\n    }\n\n    /// @notice Returns the info for all enabled transceivers\n    function getTransceiverInfo() external view returns (TransceiverInfo[] memory) {\n        address[] memory enabledTransceivers = _getEnabledTransceiversStorage();\n        uint256 numEnabledTransceivers = enabledTransceivers.length;\n        TransceiverInfo[] memory result = new TransceiverInfo[](numEnabledTransceivers);\n\n        for (uint256 i = 0; i < numEnabledTransceivers; ++i) {\n            result[i] = _getTransceiverInfosStorage()[enabledTransceivers[i]];\n        }\n\n        return result;\n    }\n\n    // ============== Invariants =============================================\n\n    /// @dev Check that the transceiver nttManager is in a valid state.\n    /// Checking these invariants is somewhat costly, but we only need to do it\n    /// when modifying the transceivers, which happens infrequently.\n    function _checkTransceiversInvariants() internal view {\n        _NumTransceivers storage _numTransceivers = _getNumTransceiversStorage();\n        address[] storage _enabledTransceivers = _getEnabledTransceiversStorage();\n\n        uint256 numTransceiversEnabled = _numTransceivers.enabled;\n        assert(numTransceiversEnabled == _enabledTransceivers.length);\n\n        for (uint256 i = 0; i < numTransceiversEnabled; i++) {\n            _checkTransceiverInvariants(_enabledTransceivers[i]);\n        }\n\n        // invariant: each transceiver is only enabled once\n        for (uint256 i = 0; i < numTransceiversEnabled; i++) {\n            for (uint256 j = i + 1; j < numTransceiversEnabled; j++) {\n                assert(_enabledTransceivers[i] != _enabledTransceivers[j]);\n            }\n        }\n\n        // invariant: numRegisteredTransceivers <= MAX_TRANSCEIVERS\n        assert(_numTransceivers.registered <= MAX_TRANSCEIVERS);\n    }\n\n    // @dev Check that the transceiver is in a valid state.\n    function _checkTransceiverInvariants(\n        address transceiver\n    ) private view {\n        mapping(address => TransceiverInfo) storage transceiverInfos = _getTransceiverInfosStorage();\n        _EnabledTransceiverBitmap storage _enabledTransceiverBitmap = _getTransceiverBitmapStorage();\n        _NumTransceivers storage _numTransceivers = _getNumTransceiversStorage();\n        address[] storage _enabledTransceivers = _getEnabledTransceiversStorage();\n\n        TransceiverInfo memory transceiverInfo = transceiverInfos[transceiver];\n\n        // if an transceiver is not registered, it should not be enabled\n        assert(\n            transceiverInfo.registered || (!transceiverInfo.enabled && transceiverInfo.index == 0)\n        );\n\n        bool transceiverInEnabledBitmap =\n            (_enabledTransceiverBitmap.bitmap & uint64(1 << transceiverInfo.index)) != 0;\n        bool transceiverEnabled = transceiverInfo.enabled;\n\n        bool transceiverInEnabledTransceivers = false;\n\n        for (uint256 i = 0; i < _numTransceivers.enabled; i++) {\n            if (_enabledTransceivers[i] == transceiver) {\n                transceiverInEnabledTransceivers = true;\n                break;\n            }\n        }\n\n        // invariant: transceiverInfos[transceiver].enabled\n        //            <=> enabledTransceiverBitmap & (1 << transceiverInfos[transceiver].index) != 0\n        assert(transceiverInEnabledBitmap == transceiverEnabled);\n\n        // invariant: transceiverInfos[transceiver].enabled <=> transceiver in _enabledTransceivers\n        assert(transceiverInEnabledTransceivers == transceiverEnabled);\n\n        assert(transceiverInfo.index < _numTransceivers.registered);\n    }\n}\n"},{"file_path":"lib/native-token-transfers/evm/src/interfaces/IOwnableUpgradeable.sol","source_code":"// SPDX-License-Identifier: Apache 2\n//\npragma solidity >=0.8.8 <0.9.0;\n\ninterface IOwnableUpgradeable {\n    function owner() external view returns (address);\n}\n"},{"file_path":"lib/native-token-transfers/evm/lib/openzeppelin-contracts/contracts/utils/StorageSlot.sol","source_code":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/StorageSlot.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Library for reading and writing primitive types to specific storage slots.\n *\n * Storage slots are often used to avoid storage conflict when dealing with upgradeable contracts.\n * This library helps with reading and writing to such slots without the need for inline assembly.\n *\n * The functions in this library return Slot structs that contain a `value` member that can be used to read or write.\n *\n * Example usage to set ERC1967 implementation slot:\n * ```\n * contract ERC1967 {\n *     bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\n *\n *     function _getImplementation() internal view returns (address) {\n *         return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value;\n *     }\n *\n *     function _setImplementation(address newImplementation) internal {\n *         require(Address.isContract(newImplementation), \"ERC1967: new implementation is not a contract\");\n *         StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation;\n *     }\n * }\n * ```\n *\n * _Available since v4.1 for `address`, `bool`, `bytes32`, and `uint256`._\n */\nlibrary StorageSlot {\n    struct AddressSlot {\n        address value;\n    }\n\n    struct BooleanSlot {\n        bool value;\n    }\n\n    struct Bytes32Slot {\n        bytes32 value;\n    }\n\n    struct Uint256Slot {\n        uint256 value;\n    }\n\n    /**\n     * @dev Returns an `AddressSlot` with member `value` located at `slot`.\n     */\n    function getAddressSlot(bytes32 slot) internal pure returns (AddressSlot storage r) {\n        /// @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"},{"file_path":"lib/native-token-transfers/evm/lib/openzeppelin-contracts/contracts/utils/Address.sol","source_code":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.8.0) (utils/Address.sol)\n\npragma solidity ^0.8.1;\n\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary Address {\n    /**\n     * @dev Returns true if `account` is a contract.\n     *\n     * [IMPORTANT]\n     * ====\n     * It is unsafe to assume that an address for which this function returns\n     * false is an externally-owned account (EOA) and not a contract.\n     *\n     * Among others, `isContract` will return false for the following\n     * types of addresses:\n     *\n     *  - an externally-owned account\n     *  - a contract in construction\n     *  - an address where a contract will be created\n     *  - an address where a contract lived, but was destroyed\n     * ====\n     *\n     * [IMPORTANT]\n     * ====\n     * You shouldn't rely on `isContract` to protect against flash loan attacks!\n     *\n     * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n     * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n     * constructor.\n     * ====\n     */\n    function isContract(address account) internal view returns (bool) {\n        // This method relies on extcodesize/address.code.length, which returns 0\n        // for contracts in construction, since the code is only stored at the end\n        // of the constructor execution.\n\n        return account.code.length > 0;\n    }\n\n    /**\n     * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n     * `recipient`, forwarding all available gas and reverting on errors.\n     *\n     * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n     * of certain opcodes, possibly making contracts go over the 2300 gas limit\n     * imposed by `transfer`, making them unable to receive funds via\n     * `transfer`. {sendValue} removes this limitation.\n     *\n     * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n     *\n     * IMPORTANT: because control is transferred to `recipient`, care must be\n     * taken to not create reentrancy vulnerabilities. Consider using\n     * {ReentrancyGuard} or the\n     * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n     */\n    function sendValue(address payable recipient, uint256 amount) internal {\n        require(address(this).balance >= amount, \"Address: insufficient balance\");\n\n        (bool success, ) = recipient.call{value: amount}(\"\");\n        require(success, \"Address: unable to send value, recipient may have reverted\");\n    }\n\n    /**\n     * @dev Performs a Solidity function call using a low level `call`. A\n     * plain `call` is an unsafe replacement for a function call: use this\n     * function instead.\n     *\n     * If `target` reverts with a revert reason, it is bubbled up by this\n     * function (like regular Solidity function calls).\n     *\n     * Returns the raw returned data. To convert to the expected return value,\n     * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n     *\n     * Requirements:\n     *\n     * - `target` must be a contract.\n     * - calling `target` with `data` must not revert.\n     *\n     * _Available since v3.1._\n     */\n    function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n        return functionCallWithValue(target, data, 0, \"Address: low-level call failed\");\n    }\n\n    /**\n     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n     * `errorMessage` as a fallback revert reason when `target` reverts.\n     *\n     * _Available since v3.1._\n     */\n    function functionCall(\n        address target,\n        bytes memory data,\n        string memory errorMessage\n    ) internal returns (bytes memory) {\n        return functionCallWithValue(target, data, 0, errorMessage);\n    }\n\n    /**\n     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n     * but also transferring `value` wei to `target`.\n     *\n     * Requirements:\n     *\n     * - the calling contract must have an ETH balance of at least `value`.\n     * - the called Solidity function must be `payable`.\n     *\n     * _Available since v3.1._\n     */\n    function functionCallWithValue(\n        address target,\n        bytes memory data,\n        uint256 value\n    ) internal returns (bytes memory) {\n        return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n    }\n\n    /**\n     * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n     * with `errorMessage` as a fallback revert reason when `target` reverts.\n     *\n     * _Available since v3.1._\n     */\n    function functionCallWithValue(\n        address target,\n        bytes memory data,\n        uint256 value,\n        string memory errorMessage\n    ) internal returns (bytes memory) {\n        require(address(this).balance >= value, \"Address: insufficient balance for call\");\n        (bool success, bytes memory returndata) = target.call{value: value}(data);\n        return verifyCallResultFromTarget(target, success, returndata, errorMessage);\n    }\n\n    /**\n     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n     * but performing a static call.\n     *\n     * _Available since v3.3._\n     */\n    function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n        return functionStaticCall(target, data, \"Address: low-level static call failed\");\n    }\n\n    /**\n     * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n     * but performing a static call.\n     *\n     * _Available since v3.3._\n     */\n    function functionStaticCall(\n        address target,\n        bytes memory data,\n        string memory errorMessage\n    ) internal view returns (bytes memory) {\n        (bool success, bytes memory returndata) = target.staticcall(data);\n        return verifyCallResultFromTarget(target, success, returndata, errorMessage);\n    }\n\n    /**\n     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n     * but performing a delegate call.\n     *\n     * _Available since v3.4._\n     */\n    function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\n        return functionDelegateCall(target, data, \"Address: low-level delegate call failed\");\n    }\n\n    /**\n     * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n     * but performing a delegate call.\n     *\n     * _Available since v3.4._\n     */\n    function functionDelegateCall(\n        address target,\n        bytes memory data,\n        string memory errorMessage\n    ) internal returns (bytes memory) {\n        (bool success, bytes memory returndata) = target.delegatecall(data);\n        return verifyCallResultFromTarget(target, success, returndata, errorMessage);\n    }\n\n    /**\n     * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling\n     * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract.\n     *\n     * _Available since v4.8._\n     */\n    function verifyCallResultFromTarget(\n        address target,\n        bool success,\n        bytes memory returndata,\n        string memory errorMessage\n    ) internal view returns (bytes memory) {\n        if (success) {\n            if (returndata.length == 0) {\n                // only check isContract if the call was successful and the return data is empty\n                // otherwise we already know that it was a contract\n                require(isContract(target), \"Address: call to non-contract\");\n            }\n            return returndata;\n        } else {\n            _revert(returndata, errorMessage);\n        }\n    }\n\n    /**\n     * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the\n     * revert reason or using the provided one.\n     *\n     * _Available since v4.3._\n     */\n    function verifyCallResult(\n        bool success,\n        bytes memory returndata,\n        string memory errorMessage\n    ) internal pure returns (bytes memory) {\n        if (success) {\n            return returndata;\n        } else {\n            _revert(returndata, errorMessage);\n        }\n    }\n\n    function _revert(bytes memory returndata, string memory errorMessage) private pure {\n        // Look for revert reason and bubble it up if present\n        if (returndata.length > 0) {\n            // The easiest way to bubble the revert reason is using memory via assembly\n            /// @solidity memory-safe-assembly\n            assembly {\n                let returndata_size := mload(returndata)\n                revert(add(32, returndata), returndata_size)\n            }\n        } else {\n            revert(errorMessage);\n        }\n    }\n}\n"},{"file_path":"lib/native-token-transfers/evm/lib/wormhole-solidity-sdk/src/interfaces/IWormholeRelayer.sol","source_code":"// SPDX-License-Identifier: Apache 2\n\npragma solidity ^0.8.0;\n\n/**\n * @title WormholeRelayer\n * @author\n * @notice This project allows developers to build cross-chain applications powered by Wormhole without needing to\n * write and run their own relaying infrastructure\n *\n * We implement the IWormholeRelayer interface that allows users to request a delivery provider to relay a payload (and/or additional messages)\n * to a chain and address of their choice.\n */\n\n/**\n * @notice VaaKey identifies a wormhole message\n *\n * @custom:member chainId Wormhole chain ID of the chain where this VAA was emitted from\n * @custom:member emitterAddress Address of the emitter of the VAA, in Wormhole bytes32 format\n * @custom:member sequence Sequence number of the VAA\n */\nstruct VaaKey {\n    uint16 chainId;\n    bytes32 emitterAddress;\n    uint64 sequence;\n}\n\n// 0-127 are reserved for standardized KeyTypes, 128-255 are for custom use\nuint8 constant VAA_KEY_TYPE = 1;\n\nstruct MessageKey {\n    uint8 keyType; // 0-127 are reserved for standardized KeyTypes, 128-255 are for custom use\n    bytes encodedKey;\n}\n\ninterface IWormholeRelayerBase {\n    event SendEvent(\n        uint64 indexed sequence,\n        uint256 deliveryQuote,\n        uint256 paymentForExtraReceiverValue\n    );\n\n    function getRegisteredWormholeRelayerContract(\n        uint16 chainId\n    ) external view returns (bytes32);\n\n    /**\n     * @notice Returns true if a delivery has been attempted for the given deliveryHash\n     * Note: invalid deliveries where the tx reverts are not considered attempted\n     */\n    function deliveryAttempted(\n        bytes32 deliveryHash\n    ) external view returns (bool attempted);\n\n    /**\n     * @notice block number at which a delivery was successfully executed\n     */\n    function deliverySuccessBlock(\n        bytes32 deliveryHash\n    ) external view returns (uint256 blockNumber);\n\n    /**\n     * @notice block number of the latest attempt to execute a delivery that failed\n     */\n    function deliveryFailureBlock(\n        bytes32 deliveryHash\n    ) external view returns (uint256 blockNumber);\n}\n\n/**\n * @title IWormholeRelayerSend\n * @notice The interface to request deliveries\n */\ninterface IWormholeRelayerSend is IWormholeRelayerBase {\n    /**\n     * @notice Publishes an instruction for the default delivery provider\n     * to relay a payload to the address `targetAddress` on chain `targetChain`\n     * with gas limit `gasLimit` and `msg.value` equal to `receiverValue`\n     *\n     * `targetAddress` must implement the IWormholeReceiver interface\n     *\n     * This function must be called with `msg.value` equal to `quoteEVMDeliveryPrice(targetChain, receiverValue, gasLimit)`\n     *\n     * Any refunds (from leftover gas) will be paid to the delivery provider. In order to receive the refunds, use the `sendPayloadToEvm` function\n     * with `refundChain` and `refundAddress` as parameters\n     *\n     * @param targetChain in Wormhole Chain ID format\n     * @param targetAddress address to call on targetChain (that implements IWormholeReceiver)\n     * @param payload arbitrary bytes to pass in as parameter in call to `targetAddress`\n     * @param receiverValue msg.value that delivery provider should pass in for call to `targetAddress` (in targetChain currency units)\n     * @param gasLimit gas limit with which to call `targetAddress`.\n     * @return sequence sequence number of published VAA containing delivery instructions\n     */\n    function sendPayloadToEvm(\n        uint16 targetChain,\n        address targetAddress,\n        bytes memory payload,\n        uint256 receiverValue,\n        uint256 gasLimit\n    ) external payable returns (uint64 sequence);\n\n    /**\n     * @notice Publishes an instruction for the default delivery provider\n     * to relay a payload to the address `targetAddress` on chain `targetChain`\n     * with gas limit `gasLimit` and `msg.value` equal to `receiverValue`\n     *\n     * Any refunds (from leftover gas) will be sent to `refundAddress` on chain `refundChain`\n     * `targetAddress` must implement the IWormholeReceiver interface\n     *\n     * This function must be called with `msg.value` equal to `quoteEVMDeliveryPrice(targetChain, receiverValue, gasLimit)`\n     *\n     * @param targetChain in Wormhole Chain ID format\n     * @param targetAddress address to call on targetChain (that implements IWormholeReceiver)\n     * @param payload arbitrary bytes to pass in as parameter in call to `targetAddress`\n     * @param receiverValue msg.value that delivery provider should pass in for call to `targetAddress` (in targetChain currency units)\n     * @param gasLimit gas limit with which to call `targetAddress`. Any units of gas unused will be refunded according to the\n     *        `targetChainRefundPerGasUnused` rate quoted by the delivery provider\n     * @param refundChain The chain to deliver any refund to, in Wormhole Chain ID format\n     * @param refundAddress The address on `refundChain` to deliver any refund to\n     * @return sequence sequence number of published VAA containing delivery instructions\n     */\n    function sendPayloadToEvm(\n        uint16 targetChain,\n        address targetAddress,\n        bytes memory payload,\n        uint256 receiverValue,\n        uint256 gasLimit,\n        uint16 refundChain,\n        address refundAddress\n    ) external payable returns (uint64 sequence);\n\n    /**\n     * @notice Publishes an instruction for the default delivery provider\n     * to relay a payload and VAAs specified by `vaaKeys` to the address `targetAddress` on chain `targetChain`\n     * with gas limit `gasLimit` and `msg.value` equal to `receiverValue`\n     *\n     * `targetAddress` must implement the IWormholeReceiver interface\n     *\n     * This function must be called with `msg.value` equal to `quoteEVMDeliveryPrice(targetChain, receiverValue, gasLimit)`\n     *\n     * Any refunds (from leftover gas) will be paid to the delivery provider. In order to receive the refunds, use the `sendVaasToEvm` function\n     * with `refundChain` and `refundAddress` as parameters\n     *\n     * @param targetChain in Wormhole Chain ID format\n     * @param targetAddress address to call on targetChain (that implements IWormholeReceiver)\n     * @param payload arbitrary bytes to pass in as parameter in call to `targetAddress`\n     * @param receiverValue msg.value that delivery provider should pass in for call to `targetAddress` (in targetChain currency units)\n     * @param gasLimit gas limit with which to call `targetAddress`.\n     * @param vaaKeys Additional VAAs to pass in as parameter in call to `targetAddress`\n     * @return sequence sequence number of published VAA containing delivery instructions\n     */\n    function sendVaasToEvm(\n        uint16 targetChain,\n        address targetAddress,\n        bytes memory payload,\n        uint256 receiverValue,\n        uint256 gasLimit,\n        VaaKey[] memory vaaKeys\n    ) external payable returns (uint64 sequence);\n\n    /**\n     * @notice Publishes an instruction for the default delivery provider\n     * to relay a payload and VAAs specified by `vaaKeys` to the address `targetAddress` on chain `targetChain`\n     * with gas limit `gasLimit` and `msg.value` equal to `receiverValue`\n     *\n     * Any refunds (from leftover gas) will be sent to `refundAddress` on chain `refundChain`\n     * `targetAddress` must implement the IWormholeReceiver interface\n     *\n     * This function must be called with `msg.value` equal to `quoteEVMDeliveryPrice(targetChain, receiverValue, gasLimit)`\n     *\n     * @param targetChain in Wormhole Chain ID format\n     * @param targetAddress address to call on targetChain (that implements IWormholeReceiver)\n     * @param payload arbitrary bytes to pass in as parameter in call to `targetAddress`\n     * @param receiverValue msg.value that delivery provider should pass in for call to `targetAddress` (in targetChain currency units)\n     * @param gasLimit gas limit with which to call `targetAddress`. Any units of gas unused will be refunded according to the\n     *        `targetChainRefundPerGasUnused` rate quoted by the delivery provider\n     * @param vaaKeys Additional VAAs to pass in as parameter in call to `targetAddress`\n     * @param refundChain The chain to deliver any refund to, in Wormhole Chain ID format\n     * @param refundAddress The address on `refundChain` to deliver any refund to\n     * @return sequence sequence number of published VAA containing delivery instructions\n     */\n    function sendVaasToEvm(\n        uint16 targetChain,\n        address targetAddress,\n        bytes memory payload,\n        uint256 receiverValue,\n        uint256 gasLimit,\n        VaaKey[] memory vaaKeys,\n        uint16 refundChain,\n        address refundAddress\n    ) external payable returns (uint64 sequence);\n\n    /**\n     * @notice Publishes an instruction for the delivery provider at `deliveryProviderAddress`\n     * to relay a payload and VAAs specified by `vaaKeys` to the address `targetAddress` on chain `targetChain`\n     * with gas limit `gasLimit` and `msg.value` equal to\n     * receiverValue + (arbitrary amount that is paid for by paymentForExtraReceiverValue of this chain's wei) in targetChain wei.\n     *\n     * Any refunds (from leftover gas) will be sent to `refundAddress` on chain `refundChain`\n     * `targetAddress` must implement the IWormholeReceiver interface\n     *\n     * This function must be called with `msg.value` equal to\n     * quoteEVMDeliveryPrice(targetChain, receiverValue, gasLimit, deliveryProviderAddress) + paymentForExtraReceiverValue\n     *\n     * @param targetChain in Wormhole Chain ID format\n     * @param targetAddress address to call on targetChain (that implements IWormholeReceiver)\n     * @param payload arbitrary bytes to pass in as parameter in call to `targetAddress`\n     * @param receiverValue msg.value that delivery provider should pass in for call to `targetAddress` (in targetChain currency units)\n     * @param paymentForExtraReceiverValue amount (in current chain currency units) to spend on extra receiverValue\n     *        (in addition to the `receiverValue` specified)\n     * @param gasLimit gas limit with which to call `targetAddress`. Any units of gas unused will be refunded according to the\n     *        `targetChainRefundPerGasUnused` rate quoted by the delivery provider\n     * @param refundChain The chain to deliver any refund to, in Wormhole Chain ID format\n     * @param refundAddress The address on `refundChain` to deliver any refund to\n     * @param deliveryProviderAddress The address of the desired delivery provider's implementation of IDeliveryProvider\n     * @param vaaKeys Additional VAAs to pass in as parameter in call to `targetAddress`\n     * @param consistencyLevel Consistency level with which to publish the delivery instructions - see\n     *        https://book.wormhole.com/wormhole/3_coreLayerContracts.html?highlight=consistency#consistency-levels\n     * @return sequence sequence number of published VAA containing delivery instructions\n     */\n    function sendToEvm(\n        uint16 targetChain,\n        address targetAddress,\n        bytes memory payload,\n        uint256 receiverValue,\n        uint256 paymentForExtraReceiverValue,\n        uint256 gasLimit,\n        uint16 refundChain,\n        address refundAddress,\n        address deliveryProviderAddress,\n        VaaKey[] memory vaaKeys,\n        uint8 consistencyLevel\n    ) external payable returns (uint64 sequence);\n\n    /**\n     * @notice Publishes an instruction for the delivery provider at `deliveryProviderAddress`\n     * to relay a payload and external messages specified by `messageKeys` to the address `targetAddress` on chain `targetChain`\n     * with gas limit `gasLimit` and `msg.value` equal to\n     * receiverValue + (arbitrary amount that is paid for by paymentForExtraReceiverValue of this chain's wei) in targetChain wei.\n     *\n     * Any refunds (from leftover gas) will be sent to `refundAddress` on chain `refundChain`\n     * `targetAddress` must implement the IWormholeReceiver interface\n     *\n     * This function must be called with `msg.value` equal to\n     * quoteEVMDeliveryPrice(targetChain, receiverValue, gasLimit, deliveryProviderAddress) + paymentForExtraReceiverValue\n     *\n     * Note: MessageKeys can specify wormhole messages (VaaKeys) or other types of messages (ex. USDC CCTP attestations). Ensure the selected\n     * DeliveryProvider supports all the MessageKey.keyType values specified or it will not be delivered!\n     *\n     * @param targetChain in Wormhole Chain ID format\n     * @param targetAddress address to call on targetChain (that implements IWormholeReceiver)\n     * @param payload arbitrary bytes to pass in as parameter in call to `targetAddress`\n     * @param receiverValue msg.value that delivery provider should pass in for call to `targetAddress` (in targetChain currency units)\n     * @param paymentForExtraReceiverValue amount (in current chain currency units) to spend on extra receiverValue\n     *        (in addition to the `receiverValue` specified)\n     * @param gasLimit gas limit with which to call `targetAddress`. Any units of gas unused will be refunded according to the\n     *        `targetChainRefundPerGasUnused` rate quoted by the delivery provider\n     * @param refundChain The chain to deliver any refund to, in Wormhole Chain ID format\n     * @param refundAddress The address on `refundChain` to deliver any refund to\n     * @param deliveryProviderAddress The address of the desired delivery provider's implementation of IDeliveryProvider\n     * @param messageKeys Additional messagess to pass in as parameter in call to `targetAddress`\n     * @param consistencyLevel Consistency level with which to publish the delivery instructions - see\n     *        https://book.wormhole.com/wormhole/3_coreLayerContracts.html?highlight=consistency#consistency-levels\n     * @return sequence sequence number of published VAA containing delivery instructions\n     */\n    function sendToEvm(\n        uint16 targetChain,\n        address targetAddress,\n        bytes memory payload,\n        uint256 receiverValue,\n        uint256 paymentForExtraReceiverValue,\n        uint256 gasLimit,\n        uint16 refundChain,\n        address refundAddress,\n        address deliveryProviderAddress,\n        MessageKey[] memory messageKeys,\n        uint8 consistencyLevel\n    ) external payable returns (uint64 sequence);\n\n    /**\n     * @notice Publishes an instruction for the delivery provider at `deliveryProviderAddress`\n     * to relay a payload and VAAs specified by `vaaKeys` to the address `targetAddress` on chain `targetChain`\n     * with `msg.value` equal to\n     * receiverValue + (arbitrary amount that is paid for by paymentForExtraReceiverValue of this chain's wei) in targetChain wei.\n     *\n     * Any refunds (from leftover gas) will be sent to `refundAddress` on chain `refundChain`\n     * `targetAddress` must implement the IWormholeReceiver interface\n     *\n     * This function must be called with `msg.value` equal to\n     * quoteDeliveryPrice(targetChain, receiverValue, encodedExecutionParameters, deliveryProviderAddress) + paymentForExtraReceiverValue\n     *\n     * @param targetChain in Wormhole Chain ID format\n     * @param targetAddress address to call on targetChain (that implements IWormholeReceiver), in Wormhole bytes32 format\n     * @param payload arbitrary bytes to pass in as parameter in call to `targetAddress`\n     * @param receiverValue msg.value that delivery provider should pass in for call to `targetAddress` (in targetChain currency units)\n     * @param paymentForExtraReceiverValue amount (in current chain currency units) to spend on extra receiverValue\n     *        (in addition to the `receiverValue` specified)\n     * @param encodedExecutionParameters encoded information on how to execute delivery that may impact pricing\n     *        e.g. for version EVM_V1, this is a struct that encodes the `gasLimit` with which to call `targetAddress`\n     * @param refundChain The chain to deliver any refund to, in Wormhole Chain ID format\n     * @param refundAddress The address on `refundChain` to deliver any refund to, in Wormhole bytes32 format\n     * @param deliveryProviderAddress The address of the desired delivery provider's implementation of IDeliveryProvider\n     * @param vaaKeys Additional VAAs to pass in as parameter in call to `targetAddress`\n     * @param consistencyLevel Consistency level with which to publish the delivery instructions - see\n     *        https://book.wormhole.com/wormhole/3_coreLayerContracts.html?highlight=consistency#consistency-levels\n     * @return sequence sequence number of published VAA containing delivery instructions\n     */\n    function send(\n        uint16 targetChain,\n        bytes32 targetAddress,\n        bytes memory payload,\n        uint256 receiverValue,\n        uint256 paymentForExtraReceiverValue,\n        bytes memory encodedExecutionParameters,\n        uint16 refundChain,\n        bytes32 refundAddress,\n        address deliveryProviderAddress,\n        VaaKey[] memory vaaKeys,\n        uint8 consistencyLevel\n    ) external payable returns (uint64 sequence);\n\n    /**\n     * @notice Publishes an instruction for the delivery provider at `deliveryProviderAddress`\n     * to relay a payload and VAAs specified by `vaaKeys` to the address `targetAddress` on chain `targetChain`\n     * with `msg.value` equal to\n     * receiverValue + (arbitrary amount that is paid for by paymentForExtraReceiverValue of this chain's wei) in targetChain wei.\n     *\n     * Any refunds (from leftover gas) will be sent to `refundAddress` on chain `refundChain`\n     * `targetAddress` must implement the IWormholeReceiver interface\n     *\n     * This function must be called with `msg.value` equal to\n     * quoteDeliveryPrice(targetChain, receiverValue, encodedExecutionParameters, deliveryProviderAddress) + paymentForExtraReceiverValue\n     *\n     * Note: MessageKeys can specify wormhole messages (VaaKeys) or other types of messages (ex. USDC CCTP attestations). Ensure the selected\n     * DeliveryProvider supports all the MessageKey.keyType values specified or it will not be delivered!\n     *\n     * @param targetChain in Wormhole Chain ID format\n     * @param targetAddress address to call on targetChain (that implements IWormholeReceiver), in Wormhole bytes32 format\n     * @param payload arbitrary bytes to pass in as parameter in call to `targetAddress`\n     * @param receiverValue msg.value that delivery provider should pass in for call to `targetAddress` (in targetChain currency units)\n     * @param paymentForExtraReceiverValue amount (in current chain currency units) to spend on extra receiverValue\n     *        (in addition to the `receiverValue` specified)\n     * @param encodedExecutionParameters encoded information on how to execute delivery that may impact pricing\n     *        e.g. for version EVM_V1, this is a struct that encodes the `gasLimit` with which to call `targetAddress`\n     * @param refundChain The chain to deliver any refund to, in Wormhole Chain ID format\n     * @param refundAddress The address on `refundChain` to deliver any refund to, in Wormhole bytes32 format\n     * @param deliveryProviderAddress The address of the desired delivery provider's implementation of IDeliveryProvider\n     * @param messageKeys Additional messagess to pass in as parameter in call to `targetAddress`\n     * @param consistencyLevel Consistency level with which to publish the delivery instructions - see\n     *        https://book.wormhole.com/wormhole/3_coreLayerContracts.html?highlight=consistency#consistency-levels\n     * @return sequence sequence number of published VAA containing delivery instructions\n     */\n    function send(\n        uint16 targetChain,\n        bytes32 targetAddress,\n        bytes memory payload,\n        uint256 receiverValue,\n        uint256 paymentForExtraReceiverValue,\n        bytes memory encodedExecutionParameters,\n        uint16 refundChain,\n        bytes32 refundAddress,\n        address deliveryProviderAddress,\n        MessageKey[] memory messageKeys,\n        uint8 consistencyLevel\n    ) external payable returns (uint64 sequence);\n\n    /**\n     * @notice Requests a previously published delivery instruction to be redelivered\n     * (e.g. with a different delivery provider)\n     *\n     * This function must be called with `msg.value` equal to\n     * quoteEVMDeliveryPrice(targetChain, newReceiverValue, newGasLimit, newDeliveryProviderAddress)\n     *\n     *  @notice *** This will only be able to succeed if the following is true **\n     *         - newGasLimit >= gas limit of the old instruction\n     *         - newReceiverValue >= receiver value of the old instruction\n     *         - newDeliveryProvider's `targetChainRefundPerGasUnused` >= old relay provider's `targetChainRefundPerGasUnused`\n     *\n     * @param deliveryVaaKey VaaKey identifying the wormhole message containing the\n     *        previously published delivery instructions\n     * @param targetChain The target chain that the original delivery targeted. Must match targetChain from original delivery instructions\n     * @param newReceiverValue new msg.value that delivery provider should pass in for call to `targetAddress` (in targetChain currency units)\n     * @param newGasLimit gas limit with which to call `targetAddress`. Any units of gas unused will be refunded according to the\n     *        `targetChainRefundPerGasUnused` rate quoted by the delivery provider, to the refund chain and address specified in the original request\n     * @param newDeliveryProviderAddress The address of the desired delivery provider's implementation of IDeliveryProvider\n     * @return sequence sequence number of published VAA containing redelivery instructions\n     *\n     * @notice *** This will only be able to succeed if the following is true **\n     *         - newGasLimit >= gas limit of the old instruction\n     *         - newReceiverValue >= receiver value of the old instruction\n     */\n    function resendToEvm(\n        VaaKey memory deliveryVaaKey,\n        uint16 targetChain,\n        uint256 newReceiverValue,\n        uint256 newGasLimit,\n        address newDeliveryProviderAddress\n    ) external payable returns (uint64 sequence);\n\n    /**\n     * @notice Requests a previously published delivery instruction to be redelivered\n     *\n     *\n     * This function must be called with `msg.value` equal to\n     * quoteDeliveryPrice(targetChain, newReceiverValue, newEncodedExecutionParameters, newDeliveryProviderAddress)\n     *\n     * @param deliveryVaaKey VaaKey identifying the wormhole message containing the\n     *        previously published delivery instructions\n     * @param targetChain The target chain that the original delivery targeted. Must match targetChain from original delivery instructions\n     * @param newReceiverValue new msg.value that delivery provider should pass in for call to `targetAddress` (in targetChain currency units)\n     * @param newEncodedExecutionParameters new encoded information on how to execute delivery that may impact pricing\n     *        e.g. for version EVM_V1, this is a struct that encodes the `gasLimit` with which to call `targetAddress`\n     * @param newDeliveryProviderAddress The address of the desired delivery provider's implementation of IDeliveryProvider\n     * @return sequence sequence number of published VAA containing redelivery instructions\n     *\n     *  @notice *** This will only be able to succeed if the following is true **\n     *         - (For EVM_V1) newGasLimit >= gas limit of the old instruction\n     *         - newReceiverValue >= receiver value of the old instruction\n     *         - (For EVM_V1) newDeliveryProvider's `targetChainRefundPerGasUnused` >= old relay provider's `targetChainRefundPerGasUnused`\n     */\n    function resend(\n        VaaKey memory deliveryVaaKey,\n        uint16 targetChain,\n        uint256 newReceiverValue,\n        bytes memory newEncodedExecutionParameters,\n        address newDeliveryProviderAddress\n    ) external payable returns (uint64 sequence);\n\n    /**\n     * @notice Returns the price to request a relay to chain `targetChain`, using the default delivery provider\n     *\n     * @param targetChain in Wormhole Chain ID format\n     * @param receiverValue msg.value that delivery provider should pass in for call to `targetAddress` (in targetChain currency units)\n     * @param gasLimit gas limit with which to call `targetAddress`.\n     * @return nativePriceQuote Price, in units of current chain currency, that the delivery provider charges to perform the relay\n     * @return targetChainRefundPerGasUnused amount of target chain currency that will be refunded per unit of gas unused,\n     *         if a refundAddress is specified.\n     *         Note: This value can be overridden by the delivery provider on the target chain. The returned value here should be considered to be a\n     *         promise by the delivery provider of the amount of refund per gas unused that will be returned to the refundAddress at the target chain.\n     *         If a delivery provider decides to override, this will be visible as part of the emitted Delivery event on the target chain.\n     */\n    function quoteEVMDeliveryPrice(\n        uint16 targetChain,\n        uint256 receiverValue,\n        uint256 gasLimit\n    )\n        external\n        view\n        returns (\n            uint256 nativePriceQuote,\n            uint256 targetChainRefundPerGasUnused\n        );\n\n    /**\n     * @notice Returns the price to request a relay to chain `targetChain`, using delivery provider `deliveryProviderAddress`\n     *\n     * @param targetChain in Wormhole Chain ID format\n     * @param receiverValue msg.value that delivery provider should pass in for call to `targetAddress` (in targetChain currency units)\n     * @param gasLimit gas limit with which to call `targetAddress`.\n     * @param deliveryProviderAddress The address of the desired delivery provider's implementation of IDeliveryProvider\n     * @return nativePriceQuote Price, in units of current chain currency, that the delivery provider charges to perform the relay\n     * @return targetChainRefundPerGasUnused amount of target chain currency that will be refunded per unit of gas unused,\n     *         if a refundAddress is specified\n     *         Note: This value can be overridden by the delivery provider on the target chain. The returned value here should be considered to be a\n     *         promise by the delivery provider of the amount of refund per gas unused that will be returned to the refundAddress at the target chain.\n     *         If a delivery provider decides to override, this will be visible as part of the emitted Delivery event on the target chain.\n     */\n    function quoteEVMDeliveryPrice(\n        uint16 targetChain,\n        uint256 receiverValue,\n        uint256 gasLimit,\n        address deliveryProviderAddress\n    )\n        external\n        view\n        returns (\n            uint256 nativePriceQuote,\n            uint256 targetChainRefundPerGasUnused\n        );\n\n    /**\n     * @notice Returns the price to request a relay to chain `targetChain`, using delivery provider `deliveryProviderAddress`\n     *\n     * @param targetChain in Wormhole Chain ID format\n     * @param receiverValue msg.value that delivery provider should pass in for call to `targetAddress` (in targetChain currency units)\n     * @param encodedExecutionParameters encoded information on how to execute delivery that may impact pricing\n     *        e.g. for version EVM_V1, this is a struct that encodes the `gasLimit` with which to call `targetAddress`\n     * @param deliveryProviderAddress The address of the desired delivery provider's implementation of IDeliveryProvider\n     * @return nativePriceQuote Price, in units of current chain currency, that the delivery provider charges to perform the relay\n     * @return encodedExecutionInfo encoded information on how the delivery will be executed\n     *        e.g. for version EVM_V1, this is a struct that encodes the `gasLimit` and `targetChainRefundPerGasUnused`\n     *             (which is the amount of target chain currency that will be refunded per unit of gas unused,\n     *              if a refundAddress is specified)\n     */\n    function quoteDeliveryPrice(\n        uint16 targetChain,\n        uint256 receiverValue,\n        bytes memory encodedExecutionParameters,\n        address deliveryProviderAddress\n    )\n        external\n        view\n        returns (uint256 nativePriceQuote, bytes memory encodedExecutionInfo);\n\n    /**\n     * @notice Returns the (extra) amount of target chain currency that `targetAddress`\n     * will be called with, if the `paymentForExtraReceiverValue` field is set to `currentChainAmount`\n     *\n     * @param targetChain in Wormhole Chain ID format\n     * @param currentChainAmount The value that `paymentForExtraReceiverValue` will be set to\n     * @param deliveryProviderAddress The address of the desired delivery provider's implementation of IDeliveryProvider\n     * @return targetChainAmount The amount such that if `targetAddress` will be called with `msg.value` equal to\n     *         receiverValue + targetChainAmount\n     */\n    function quoteNativeForChain(\n        uint16 targetChain,\n        uint256 currentChainAmount,\n        address deliveryProviderAddress\n    ) external view returns (uint256 targetChainAmount);\n\n    /**\n     * @notice Returns the address of the current default delivery provider\n     * @return deliveryProvider The address of (the default delivery provider)'s contract on this source\n     *   chain. This must be a contract that implements IDeliveryProvider.\n     */\n    function getDefaultDeliveryProvider()\n        external\n        view\n        returns (address deliveryProvider);\n}\n\n/**\n * @title IWormholeRelayerDelivery\n * @notice The interface to execute deliveries. Only relevant for Delivery Providers\n */\ninterface IWormholeRelayerDelivery is IWormholeRelayerBase {\n    enum DeliveryStatus {\n        SUCCESS,\n        RECEIVER_FAILURE\n    }\n\n    enum RefundStatus {\n        REFUND_SENT,\n        REFUND_FAIL,\n        CROSS_CHAIN_REFUND_SENT,\n        CROSS_CHAIN_REFUND_FAIL_PROVIDER_NOT_SUPPORTED,\n        CROSS_CHAIN_REFUND_FAIL_NOT_ENOUGH,\n        NO_REFUND_REQUESTED\n    }\n\n    /**\n     * @custom:member recipientContract - The target contract address\n     * @custom:member sourceChain - The chain which this delivery was requested from (in wormhole\n     *     ChainID format)\n     * @custom:member sequence - The wormhole sequence number of the delivery VAA on the source chain\n     *     corresponding to this delivery request\n     * @custom:member deliveryVaaHash - The hash of the delivery VAA corresponding to this delivery\n     *     request\n     * @custom:member gasUsed - The amount of gas that was used to call your target contract\n     * @custom:member status:\n     *   - RECEIVER_FAILURE, if the target contract reverts\n     *   - SUCCESS, if the target contract doesn't revert\n     * @custom:member additionalStatusInfo:\n     *   - If status is SUCCESS, then this is empty.\n     *   - If status is RECEIVER_FAILURE, this is `RETURNDATA_TRUNCATION_THRESHOLD` bytes of the\n     *       return data (i.e. potentially truncated revert reason information).\n     * @custom:member refundStatus - Result of the refund. REFUND_SUCCESS or REFUND_FAIL are for\n     *     refunds where targetChain=refundChain; the others are for targetChain!=refundChain,\n     *     where a cross chain refund is necessary, or if the default code path is used where no refund is requested (NO_REFUND_REQUESTED)\n     * @custom:member overridesInfo:\n     *   - If not an override: empty bytes array\n     *   - Otherwise: An encoded `DeliveryOverride`\n     */\n    event Delivery(\n        address indexed recipientContract,\n        uint16 indexed sourceChain,\n        uint64 indexed sequence,\n        bytes32 deliveryVaaHash,\n        DeliveryStatus status,\n        uint256 gasUsed,\n        RefundStatus refundStatus,\n        bytes additionalStatusInfo,\n        bytes overridesInfo\n    );\n\n    /**\n     * @notice The delivery provider calls `deliver` to relay messages as described by one delivery instruction\n     *\n     * The delivery provider must pass in the specified (by VaaKeys[]) signed wormhole messages (VAAs) from the source chain\n     * as well as the signed wormhole message with the delivery instructions (the delivery VAA)\n     *\n     * The messages will be relayed to the target address (with the specified gas limit and receiver value) iff the following checks are met:\n     * - the delivery VAA has a valid signature\n     * - the delivery VAA's emitter is one of these WormholeRelayer contracts\n     * - the delivery provider passed in at least enough of this chain's currency as msg.value (enough meaning the maximum possible refund)\n     * - the instruction's target chain is this chain\n     * - the relayed signed VAAs match the descriptions in container.messages (the VAA hashes match, or the emitter address, sequence number pair matches, depending on the description given)\n     *\n     * @param encodedVMs - An array of signed wormhole messages (all from the same source chain\n     *     transaction)\n     * @param encodedDeliveryVAA - Signed wormhole message from the source chain's WormholeRelayer\n     *     contract with payload being the encoded delivery instruction container\n     * @param relayerRefundAddress - The address to which any refunds to the delivery provider\n     *     should be sent\n     * @param deliveryOverrides - Optional overrides field which must be either an empty bytes array or\n     *     an encoded DeliveryOverride struct\n     */\n    function deliver(\n        bytes[] memory encodedVMs,\n        bytes memory encodedDeliveryVAA,\n        address payable relayerRefundAddress,\n        bytes memory deliveryOverrides\n    ) external payable;\n}\n\ninterface IWormholeRelayer is IWormholeRelayerDelivery, IWormholeRelayerSend {}\n\n/*\n *  Errors thrown by IWormholeRelayer contract\n */\n\n// Bound chosen by the following formula: `memoryWord * 4 + selectorSize`.\n// This means that an error identifier plus four fixed size arguments should be available to developers.\n// In the case of a `require` revert with error message, this should provide 2 memory word's worth of data.\nuint256 constant RETURNDATA_TRUNCATION_THRESHOLD = 132;\n\n//When msg.value was not equal to `delivery provider's quoted delivery price` + `paymentForExtraReceiverValue`\nerror InvalidMsgValue(uint256 msgValue, uint256 totalFee);\n\nerror RequestedGasLimitTooLow();\n\nerror DeliveryProviderDoesNotSupportTargetChain(\n    address relayer,\n    uint16 chainId\n);\nerror DeliveryProviderCannotReceivePayment();\nerror DeliveryProviderDoesNotSupportMessageKeyType(uint8 keyType);\n\n//When calling `delivery()` a second time even though a delivery is already in progress\nerror ReentrantDelivery(address msgSender, address lockedBy);\n\nerror InvalidPayloadId(uint8 parsed, uint8 expected);\nerror InvalidPayloadLength(uint256 received, uint256 expected);\nerror InvalidVaaKeyType(uint8 parsed);\nerror TooManyMessageKeys(uint256 numMessageKeys);\n\nerror InvalidDeliveryVaa(string reason);\n//When the delivery VAA (signed wormhole message with delivery instructions) was not emitted by the\n//  registered WormholeRelayer contract\nerror InvalidEmitter(bytes32 emitter, bytes32 registered, uint16 chainId);\nerror MessageKeysLengthDoesNotMatchMessagesLength(uint256 keys, uint256 vaas);\nerror VaaKeysDoNotMatchVaas(uint8 index);\n//When someone tries to call an external function of the WormholeRelayer that is only intended to be\n//  called by the WormholeRelayer itself (to allow retroactive reverts for atomicity)\nerror RequesterNotWormholeRelayer();\n\n//When trying to relay a `DeliveryInstruction` to any other chain but the one it was specified for\nerror TargetChainIsNotThisChain(uint16 targetChain);\n//When a `DeliveryOverride` contains a gas limit that's less than the original\nerror InvalidOverrideGasLimit();\n//When a `DeliveryOverride` contains a receiver value that's less than the original\nerror InvalidOverrideReceiverValue();\n//When a `DeliveryOverride` contains a 'refund per unit of gas unused' that's less than the original\nerror InvalidOverrideRefundPerGasUnused();\n\n//When the delivery provider doesn't pass in sufficient funds (i.e. msg.value does not cover the\n// maximum possible refund to the user)\nerror InsufficientRelayerFunds(uint256 msgValue, uint256 minimum);\n\n//When a bytes32 field can't be converted into a 20 byte EVM address, because the 12 padding bytes\n//  are non-zero (duplicated from Utils.sol)\nerror NotAnEvmAddress(bytes32);\n"},{"file_path":"lib/native-token-transfers/evm/src/interfaces/IRateLimiterEvents.sol","source_code":"// SPDX-License-Identifier: Apache 2\npragma solidity >=0.8.8 <0.9.0;\n\nimport \"../libraries/TrimmedAmount.sol\";\n\ninterface IRateLimiterEvents {\n    /// @notice Emitted when an inbound transfer is queued\n    /// @dev Topic0\n    ///      0x7f63c9251d82a933210c2b6d0b0f116252c3c116788120e64e8e8215df6f3162.\n    /// @param digest The digest of the message.\n    event InboundTransferQueued(bytes32 digest);\n\n    /// @notice Emitted whenn an outbound transfer is queued.\n    /// @dev Topic0\n    ///      0x69add1952a6a6b9cb86f04d05f0cb605cbb469a50ae916139d34495a9991481f.\n    /// @param queueSequence The location of the transfer in the queue.\n    event OutboundTransferQueued(uint64 queueSequence);\n\n    /// @notice Emitted when an outbound transfer is rate limited.\n    /// @dev Topic0\n    ///      0xf33512b84e24a49905c26c6991942fc5a9652411769fc1e448f967cdb049f08a.\n    /// @param sender The initial sender of the transfer.\n    /// @param amount The amount to be transferred.\n    /// @param currentCapacity The capacity left for transfers within the 24-hour window.\n    event OutboundTransferRateLimited(\n        address indexed sender, uint64 sequence, uint256 amount, uint256 currentCapacity\n    );\n\n    /// @notice Emitted when the outbound transfer limit is updated.\n    /// @dev Topic0\n    ///      0x7e3b0fc388be9d36273f66210aed83be975df3a9adfffa4c734033f498f362cd.\n    /// @param oldLimit The old outbound limit.\n    /// @param newLimit The new outbound limit.\n    event OutboundTransferLimitUpdated(uint256 oldLimit, uint256 newLimit);\n\n    /// @notice Emitted when the inbound transfer limit is updated.\n    /// @dev Topic0\n    ///      0x739ed886fd81a3ddc9f4b327ab69152e513cd45b26fda0c73660eaca8e119301.\n    /// @param chainId The chain ID the limit is set for.\n    /// @param oldLimit The old inbound limit.\n    /// @param newLimit The new inbound limit.\n    event InboundTransferLimitUpdated(uint16 indexed chainId, uint256 oldLimit, uint256 newLimit);\n}\n"},{"file_path":"lib/native-token-transfers/evm/src/libraries/external/ReentrancyGuardUpgradeable.sol","source_code":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.0.0) (utils/ReentrancyGuard.sol)\n\npragma solidity ^0.8.19;\n\nimport {Initializable} from \"./Initializable.sol\";\n\n/**\n * @dev Contract module that helps prevent reentrant calls to a function.\n *\n * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier\n * available, which can be applied to functions to make sure there are no nested\n * (reentrant) calls to them.\n *\n * Note that because there is a single `nonReentrant` guard, functions marked as\n * `nonReentrant` may not call one another. This can be worked around by making\n * those functions `private`, and then adding `external` `nonReentrant` entry\n * points to them.\n *\n * TIP: If you would like to learn more about reentrancy and alternative ways\n * to protect against it, check out our blog post\n * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].\n */\nabstract contract ReentrancyGuardUpgradeable is Initializable {\n    // Booleans are more expensive than uint256 or any type that takes up a full\n    // word because each write operation emits an extra SLOAD to first read the\n    // slot's contents, replace the bits taken up by the boolean, and then write\n    // back. This is the compiler's defense against contract upgrades and\n    // pointer aliasing, and it cannot be disabled.\n\n    // The values being non-zero value makes deployment a bit more expensive,\n    // but in exchange the refund on every call to nonReentrant will be lower in\n    // amount. Since refunds are capped to a percentage of the total\n    // transaction's gas, it is best to keep them low in cases like this one, to\n    // increase the likelihood of the full refund coming into effect.\n    uint256 private constant NOT_ENTERED = 1;\n    uint256 private constant ENTERED = 2;\n\n    /// @custom:storage-location erc7201:openzeppelin.storage.ReentrancyGuard\n    struct ReentrancyGuardStorage {\n        uint256 _status;\n    }\n\n    // keccak256(abi.encode(uint256(keccak256(\"openzeppelin.storage.ReentrancyGuard\")) - 1)) & ~bytes32(uint256(0xff))\n    bytes32 private constant ReentrancyGuardStorageLocation =\n        0x9b779b17422d0df92223018b32b4d1fa46e071723d6817e2486d003becc55f00;\n\n    function _getReentrancyGuardStorage() private pure returns (ReentrancyGuardStorage storage $) {\n        assembly {\n            $.slot := ReentrancyGuardStorageLocation\n        }\n    }\n\n    /**\n     * @dev Unauthorized reentrant call.\n     */\n    error ReentrancyGuardReentrantCall();\n\n    function __ReentrancyGuard_init() internal onlyInitializing {\n        __ReentrancyGuard_init_unchained();\n    }\n\n    function __ReentrancyGuard_init_unchained() internal onlyInitializing {\n        ReentrancyGuardStorage storage $ = _getReentrancyGuardStorage();\n        $._status = NOT_ENTERED;\n    }\n\n    /**\n     * @dev Prevents a contract from calling itself, directly or indirectly.\n     * Calling a `nonReentrant` function from another `nonReentrant`\n     * function is not supported. It is possible to prevent this from happening\n     * by making the `nonReentrant` function external, and making it call a\n     * `private` function that does the actual work.\n     */\n    modifier nonReentrant() {\n        _nonReentrantBefore();\n        _;\n        _nonReentrantAfter();\n    }\n\n    function _nonReentrantBefore() private {\n        ReentrancyGuardStorage storage $ = _getReentrancyGuardStorage();\n        // On the first call to nonReentrant, _status will be NOT_ENTERED\n        if ($._status == ENTERED) {\n            revert ReentrancyGuardReentrantCall();\n        }\n\n        // Any calls to nonReentrant after this point will fail\n        $._status = ENTERED;\n    }\n\n    function _nonReentrantAfter() private {\n        ReentrancyGuardStorage storage $ = _getReentrancyGuardStorage();\n        // By storing the original value once again, a refund is triggered (see\n        // https://eips.ethereum.org/EIPS/eip-2200)\n        $._status = NOT_ENTERED;\n    }\n\n    /**\n     * @dev Returns true if the reentrancy guard is currently set to \"entered\", which indicates there is a\n     * `nonReentrant` function in the call stack.\n     */\n    function _reentrancyGuardEntered() internal view returns (bool) {\n        ReentrancyGuardStorage storage $ = _getReentrancyGuardStorage();\n        return $._status == ENTERED;\n    }\n}\n"},{"file_path":"lib/native-token-transfers/evm/src/libraries/PausableOwnable.sol","source_code":"// SPDX-License-Identifier: Apache 2\n\npragma solidity >=0.8.8 <0.9.0;\n\nimport \"./PausableUpgradeable.sol\";\nimport \"./external/OwnableUpgradeable.sol\";\n\nabstract contract PausableOwnable is PausableUpgradeable, OwnableUpgradeable {\n    /*\n     * @dev Modifier to allow only the Pauser and the Owner to access pausing functionality\n     */\n    modifier onlyOwnerOrPauser() {\n        _checkOwnerOrPauser(owner());\n        _;\n    }\n\n    /*\n     * @dev Modifier to allow only the Pauser to access some functionality\n     */\n    function _checkOwnerOrPauser(\n        address owner\n    ) internal view {\n        if (pauser() != msg.sender && owner != msg.sender) {\n            revert InvalidPauser(msg.sender);\n        }\n    }\n\n    function __PausedOwnable_init(address initialPauser, address owner) internal onlyInitializing {\n        __Paused_init(initialPauser);\n        __Ownable_init(owner);\n    }\n\n    /**\n     * @dev Transfers the ability to pause to a new account (`newPauser`).\n     */\n    function transferPauserCapability(\n        address newPauser\n    ) public virtual onlyOwnerOrPauser {\n        PauserStorage storage $ = _getPauserStorage();\n        address oldPauser = $._pauser;\n        $._pauser = newPauser;\n        emit PauserTransferred(oldPauser, newPauser);\n    }\n}\n"},{"file_path":"lib/native-token-transfers/evm/lib/openzeppelin-contracts/contracts/token/ERC20/extensions/draft-IERC20Permit.sol","source_code":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/draft-IERC20Permit.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in\n * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].\n *\n * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by\n * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't\n * need to send a transaction, and thus is not required to hold Ether at all.\n */\ninterface IERC20Permit {\n    /**\n     * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens,\n     * given ``owner``'s signed approval.\n     *\n     * IMPORTANT: The same issues {IERC20-approve} has related to transaction\n     * ordering also apply here.\n     *\n     * Emits an {Approval} event.\n     *\n     * Requirements:\n     *\n     * - `spender` cannot be the zero address.\n     * - `deadline` must be a timestamp in the future.\n     * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner`\n     * over the EIP712-formatted function arguments.\n     * - the signature must use ``owner``'s current nonce (see {nonces}).\n     *\n     * For more information on the signature format, see the\n     * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP\n     * section].\n     */\n    function permit(\n        address owner,\n        address spender,\n        uint256 value,\n        uint256 deadline,\n        uint8 v,\n        bytes32 r,\n        bytes32 s\n    ) external;\n\n    /**\n     * @dev Returns the current nonce for `owner`. This value must be\n     * included whenever a signature is generated for {permit}.\n     *\n     * Every successful call to {permit} increases ``owner``'s nonce by one. This\n     * prevents a signature from being used multiple times.\n     */\n    function nonces(address owner) external view returns (uint256);\n\n    /**\n     * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}.\n     */\n    // solhint-disable-next-line func-name-mixedcase\n    function DOMAIN_SEPARATOR() external view returns (bytes32);\n}\n"},{"file_path":"lib/native-token-transfers/evm/lib/openzeppelin-contracts/contracts/utils/math/SafeCast.sol","source_code":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.8.0) (utils/math/SafeCast.sol)\n// This file was procedurally generated from scripts/generate/templates/SafeCast.js.\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Wrappers over Solidity's uintXX/intXX casting operators with added overflow\n * checks.\n *\n * Downcasting from uint256/int256 in Solidity does not revert on overflow. This can\n * easily result in undesired exploitation or bugs, since developers usually\n * assume that overflows raise errors. `SafeCast` restores this intuition by\n * reverting the transaction when such an operation overflows.\n *\n * Using this library instead of the unchecked operations eliminates an entire\n * class of bugs, so it's recommended to use it always.\n *\n * Can be combined with {SafeMath} and {SignedSafeMath} to extend it to smaller types, by performing\n * all math on `uint256` and `int256` and then downcasting.\n */\nlibrary SafeCast {\n    /**\n     * @dev Returns the downcasted uint248 from uint256, reverting on\n     * overflow (when the input is greater than largest uint248).\n     *\n     * Counterpart to Solidity's `uint248` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 248 bits\n     *\n     * _Available since v4.7._\n     */\n    function toUint248(uint256 value) internal pure returns (uint248) {\n        require(value <= type(uint248).max, \"SafeCast: value doesn't fit in 248 bits\");\n        return uint248(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint240 from uint256, reverting on\n     * overflow (when the input is greater than largest uint240).\n     *\n     * Counterpart to Solidity's `uint240` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 240 bits\n     *\n     * _Available since v4.7._\n     */\n    function toUint240(uint256 value) internal pure returns (uint240) {\n        require(value <= type(uint240).max, \"SafeCast: value doesn't fit in 240 bits\");\n        return uint240(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint232 from uint256, reverting on\n     * overflow (when the input is greater than largest uint232).\n     *\n     * Counterpart to Solidity's `uint232` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 232 bits\n     *\n     * _Available since v4.7._\n     */\n    function toUint232(uint256 value) internal pure returns (uint232) {\n        require(value <= type(uint232).max, \"SafeCast: value doesn't fit in 232 bits\");\n        return uint232(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint224 from uint256, reverting on\n     * overflow (when the input is greater than largest uint224).\n     *\n     * Counterpart to Solidity's `uint224` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 224 bits\n     *\n     * _Available since v4.2._\n     */\n    function toUint224(uint256 value) internal pure returns (uint224) {\n        require(value <= type(uint224).max, \"SafeCast: value doesn't fit in 224 bits\");\n        return uint224(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint216 from uint256, reverting on\n     * overflow (when the input is greater than largest uint216).\n     *\n     * Counterpart to Solidity's `uint216` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 216 bits\n     *\n     * _Available since v4.7._\n     */\n    function toUint216(uint256 value) internal pure returns (uint216) {\n        require(value <= type(uint216).max, \"SafeCast: value doesn't fit in 216 bits\");\n        return uint216(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint208 from uint256, reverting on\n     * overflow (when the input is greater than largest uint208).\n     *\n     * Counterpart to Solidity's `uint208` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 208 bits\n     *\n     * _Available since v4.7._\n     */\n    function toUint208(uint256 value) internal pure returns (uint208) {\n        require(value <= type(uint208).max, \"SafeCast: value doesn't fit in 208 bits\");\n        return uint208(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint200 from uint256, reverting on\n     * overflow (when the input is greater than largest uint200).\n     *\n     * Counterpart to Solidity's `uint200` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 200 bits\n     *\n     * _Available since v4.7._\n     */\n    function toUint200(uint256 value) internal pure returns (uint200) {\n        require(value <= type(uint200).max, \"SafeCast: value doesn't fit in 200 bits\");\n        return uint200(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint192 from uint256, reverting on\n     * overflow (when the input is greater than largest uint192).\n     *\n     * Counterpart to Solidity's `uint192` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 192 bits\n     *\n     * _Available since v4.7._\n     */\n    function toUint192(uint256 value) internal pure returns (uint192) {\n        require(value <= type(uint192).max, \"SafeCast: value doesn't fit in 192 bits\");\n        return uint192(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint184 from uint256, reverting on\n     * overflow (when the input is greater than largest uint184).\n     *\n     * Counterpart to Solidity's `uint184` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 184 bits\n     *\n     * _Available since v4.7._\n     */\n    function toUint184(uint256 value) internal pure returns (uint184) {\n        require(value <= type(uint184).max, \"SafeCast: value doesn't fit in 184 bits\");\n        return uint184(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint176 from uint256, reverting on\n     * overflow (when the input is greater than largest uint176).\n     *\n     * Counterpart to Solidity's `uint176` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 176 bits\n     *\n     * _Available since v4.7._\n     */\n    function toUint176(uint256 value) internal pure returns (uint176) {\n        require(value <= type(uint176).max, \"SafeCast: value doesn't fit in 176 bits\");\n        return uint176(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint168 from uint256, reverting on\n     * overflow (when the input is greater than largest uint168).\n     *\n     * Counterpart to Solidity's `uint168` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 168 bits\n     *\n     * _Available since v4.7._\n     */\n    function toUint168(uint256 value) internal pure returns (uint168) {\n        require(value <= type(uint168).max, \"SafeCast: value doesn't fit in 168 bits\");\n        return uint168(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint160 from uint256, reverting on\n     * overflow (when the input is greater than largest uint160).\n     *\n     * Counterpart to Solidity's `uint160` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 160 bits\n     *\n     * _Available since v4.7._\n     */\n    function toUint160(uint256 value) internal pure returns (uint160) {\n        require(value <= type(uint160).max, \"SafeCast: value doesn't fit in 160 bits\");\n        return uint160(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint152 from uint256, reverting on\n     * overflow (when the input is greater than largest uint152).\n     *\n     * Counterpart to Solidity's `uint152` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 152 bits\n     *\n     * _Available since v4.7._\n     */\n    function toUint152(uint256 value) internal pure returns (uint152) {\n        require(value <= type(uint152).max, \"SafeCast: value doesn't fit in 152 bits\");\n        return uint152(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint144 from uint256, reverting on\n     * overflow (when the input is greater than largest uint144).\n     *\n     * Counterpart to Solidity's `uint144` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 144 bits\n     *\n     * _Available since v4.7._\n     */\n    function toUint144(uint256 value) internal pure returns (uint144) {\n        require(value <= type(uint144).max, \"SafeCast: value doesn't fit in 144 bits\");\n        return uint144(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint136 from uint256, reverting on\n     * overflow (when the input is greater than largest uint136).\n     *\n     * Counterpart to Solidity's `uint136` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 136 bits\n     *\n     * _Available since v4.7._\n     */\n    function toUint136(uint256 value) internal pure returns (uint136) {\n        require(value <= type(uint136).max, \"SafeCast: value doesn't fit in 136 bits\");\n        return uint136(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint128 from uint256, reverting on\n     * overflow (when the input is greater than largest uint128).\n     *\n     * Counterpart to Solidity's `uint128` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 128 bits\n     *\n     * _Available since v2.5._\n     */\n    function toUint128(uint256 value) internal pure returns (uint128) {\n        require(value <= type(uint128).max, \"SafeCast: value doesn't fit in 128 bits\");\n        return uint128(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint120 from uint256, reverting on\n     * overflow (when the input is greater than largest uint120).\n     *\n     * Counterpart to Solidity's `uint120` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 120 bits\n     *\n     * _Available since v4.7._\n     */\n    function toUint120(uint256 value) internal pure returns (uint120) {\n        require(value <= type(uint120).max, \"SafeCast: value doesn't fit in 120 bits\");\n        return uint120(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint112 from uint256, reverting on\n     * overflow (when the input is greater than largest uint112).\n     *\n     * Counterpart to Solidity's `uint112` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 112 bits\n     *\n     * _Available since v4.7._\n     */\n    function toUint112(uint256 value) internal pure returns (uint112) {\n        require(value <= type(uint112).max, \"SafeCast: value doesn't fit in 112 bits\");\n        return uint112(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint104 from uint256, reverting on\n     * overflow (when the input is greater than largest uint104).\n     *\n     * Counterpart to Solidity's `uint104` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 104 bits\n     *\n     * _Available since v4.7._\n     */\n    function toUint104(uint256 value) internal pure returns (uint104) {\n        require(value <= type(uint104).max, \"SafeCast: value doesn't fit in 104 bits\");\n        return uint104(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint96 from uint256, reverting on\n     * overflow (when the input is greater than largest uint96).\n     *\n     * Counterpart to Solidity's `uint96` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 96 bits\n     *\n     * _Available since v4.2._\n     */\n    function toUint96(uint256 value) internal pure returns (uint96) {\n        require(value <= type(uint96).max, \"SafeCast: value doesn't fit in 96 bits\");\n        return uint96(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint88 from uint256, reverting on\n     * overflow (when the input is greater than largest uint88).\n     *\n     * Counterpart to Solidity's `uint88` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 88 bits\n     *\n     * _Available since v4.7._\n     */\n    function toUint88(uint256 value) internal pure returns (uint88) {\n        require(value <= type(uint88).max, \"SafeCast: value doesn't fit in 88 bits\");\n        return uint88(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint80 from uint256, reverting on\n     * overflow (when the input is greater than largest uint80).\n     *\n     * Counterpart to Solidity's `uint80` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 80 bits\n     *\n     * _Available since v4.7._\n     */\n    function toUint80(uint256 value) internal pure returns (uint80) {\n        require(value <= type(uint80).max, \"SafeCast: value doesn't fit in 80 bits\");\n        return uint80(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint72 from uint256, reverting on\n     * overflow (when the input is greater than largest uint72).\n     *\n     * Counterpart to Solidity's `uint72` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 72 bits\n     *\n     * _Available since v4.7._\n     */\n    function toUint72(uint256 value) internal pure returns (uint72) {\n        require(value <= type(uint72).max, \"SafeCast: value doesn't fit in 72 bits\");\n        return uint72(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint64 from uint256, reverting on\n     * overflow (when the input is greater than largest uint64).\n     *\n     * Counterpart to Solidity's `uint64` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 64 bits\n     *\n     * _Available since v2.5._\n     */\n    function toUint64(uint256 value) internal pure returns (uint64) {\n        require(value <= type(uint64).max, \"SafeCast: value doesn't fit in 64 bits\");\n        return uint64(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint56 from uint256, reverting on\n     * overflow (when the input is greater than largest uint56).\n     *\n     * Counterpart to Solidity's `uint56` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 56 bits\n     *\n     * _Available since v4.7._\n     */\n    function toUint56(uint256 value) internal pure returns (uint56) {\n        require(value <= type(uint56).max, \"SafeCast: value doesn't fit in 56 bits\");\n        return uint56(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint48 from uint256, reverting on\n     * overflow (when the input is greater than largest uint48).\n     *\n     * Counterpart to Solidity's `uint48` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 48 bits\n     *\n     * _Available since v4.7._\n     */\n    function toUint48(uint256 value) internal pure returns (uint48) {\n        require(value <= type(uint48).max, \"SafeCast: value doesn't fit in 48 bits\");\n        return uint48(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint40 from uint256, reverting on\n     * overflow (when the input is greater than largest uint40).\n     *\n     * Counterpart to Solidity's `uint40` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 40 bits\n     *\n     * _Available since v4.7._\n     */\n    function toUint40(uint256 value) internal pure returns (uint40) {\n        require(value <= type(uint40).max, \"SafeCast: value doesn't fit in 40 bits\");\n        return uint40(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint32 from uint256, reverting on\n     * overflow (when the input is greater than largest uint32).\n     *\n     * Counterpart to Solidity's `uint32` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 32 bits\n     *\n     * _Available since v2.5._\n     */\n    function toUint32(uint256 value) internal pure returns (uint32) {\n        require(value <= type(uint32).max, \"SafeCast: value doesn't fit in 32 bits\");\n        return uint32(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint24 from uint256, reverting on\n     * overflow (when the input is greater than largest uint24).\n     *\n     * Counterpart to Solidity's `uint24` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 24 bits\n     *\n     * _Available since v4.7._\n     */\n    function toUint24(uint256 value) internal pure returns (uint24) {\n        require(value <= type(uint24).max, \"SafeCast: value doesn't fit in 24 bits\");\n        return uint24(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint16 from uint256, reverting on\n     * overflow (when the input is greater than largest uint16).\n     *\n     * Counterpart to Solidity's `uint16` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 16 bits\n     *\n     * _Available since v2.5._\n     */\n    function toUint16(uint256 value) internal pure returns (uint16) {\n        require(value <= type(uint16).max, \"SafeCast: value doesn't fit in 16 bits\");\n        return uint16(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint8 from uint256, reverting on\n     * overflow (when the input is greater than largest uint8).\n     *\n     * Counterpart to Solidity's `uint8` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 8 bits\n     *\n     * _Available since v2.5._\n     */\n    function toUint8(uint256 value) internal pure returns (uint8) {\n        require(value <= type(uint8).max, \"SafeCast: value doesn't fit in 8 bits\");\n        return uint8(value);\n    }\n\n    /**\n     * @dev Converts a signed int256 into an unsigned uint256.\n     *\n     * Requirements:\n     *\n     * - input must be greater than or equal to 0.\n     *\n     * _Available since v3.0._\n     */\n    function toUint256(int256 value) internal pure returns (uint256) {\n        require(value >= 0, \"SafeCast: value must be positive\");\n        return uint256(value);\n    }\n\n    /**\n     * @dev Returns the downcasted int248 from int256, reverting on\n     * overflow (when the input is less than smallest int248 or\n     * greater than largest int248).\n     *\n     * Counterpart to Solidity's `int248` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 248 bits\n     *\n     * _Available since v4.7._\n     */\n    function toInt248(int256 value) internal pure returns (int248 downcasted) {\n        downcasted = int248(value);\n        require(downcasted == value, \"SafeCast: value doesn't fit in 248 bits\");\n    }\n\n    /**\n     * @dev Returns the downcasted int240 from int256, reverting on\n     * overflow (when the input is less than smallest int240 or\n     * greater than largest int240).\n     *\n     * Counterpart to Solidity's `int240` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 240 bits\n     *\n     * _Available since v4.7._\n     */\n    function toInt240(int256 value) internal pure returns (int240 downcasted) {\n        downcasted = int240(value);\n        require(downcasted == value, \"SafeCast: value doesn't fit in 240 bits\");\n    }\n\n    /**\n     * @dev Returns the downcasted int232 from int256, reverting on\n     * overflow (when the input is less than smallest int232 or\n     * greater than largest int232).\n     *\n     * Counterpart to Solidity's `int232` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 232 bits\n     *\n     * _Available since v4.7._\n     */\n    function toInt232(int256 value) internal pure returns (int232 downcasted) {\n        downcasted = int232(value);\n        require(downcasted == value, \"SafeCast: value doesn't fit in 232 bits\");\n    }\n\n    /**\n     * @dev Returns the downcasted int224 from int256, reverting on\n     * overflow (when the input is less than smallest int224 or\n     * greater than largest int224).\n     *\n     * Counterpart to Solidity's `int224` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 224 bits\n     *\n     * _Available since v4.7._\n     */\n    function toInt224(int256 value) internal pure returns (int224 downcasted) {\n        downcasted = int224(value);\n        require(downcasted == value, \"SafeCast: value doesn't fit in 224 bits\");\n    }\n\n    /**\n     * @dev Returns the downcasted int216 from int256, reverting on\n     * overflow (when the input is less than smallest int216 or\n     * greater than largest int216).\n     *\n     * Counterpart to Solidity's `int216` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 216 bits\n     *\n     * _Available since v4.7._\n     */\n    function toInt216(int256 value) internal pure returns (int216 downcasted) {\n        downcasted = int216(value);\n        require(downcasted == value, \"SafeCast: value doesn't fit in 216 bits\");\n    }\n\n    /**\n     * @dev Returns the downcasted int208 from int256, reverting on\n     * overflow (when the input is less than smallest int208 or\n     * greater than largest int208).\n     *\n     * Counterpart to Solidity's `int208` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 208 bits\n     *\n     * _Available since v4.7._\n     */\n    function toInt208(int256 value) internal pure returns (int208 downcasted) {\n        downcasted = int208(value);\n        require(downcasted == value, \"SafeCast: value doesn't fit in 208 bits\");\n    }\n\n    /**\n     * @dev Returns the downcasted int200 from int256, reverting on\n     * overflow (when the input is less than smallest int200 or\n     * greater than largest int200).\n     *\n     * Counterpart to Solidity's `int200` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 200 bits\n     *\n     * _Available since v4.7._\n     */\n    function toInt200(int256 value) internal pure returns (int200 downcasted) {\n        downcasted = int200(value);\n        require(downcasted == value, \"SafeCast: value doesn't fit in 200 bits\");\n    }\n\n    /**\n     * @dev Returns the downcasted int192 from int256, reverting on\n     * overflow (when the input is less than smallest int192 or\n     * greater than largest int192).\n     *\n     * Counterpart to Solidity's `int192` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 192 bits\n     *\n     * _Available since v4.7._\n     */\n    function toInt192(int256 value) internal pure returns (int192 downcasted) {\n        downcasted = int192(value);\n        require(downcasted == value, \"SafeCast: value doesn't fit in 192 bits\");\n    }\n\n    /**\n     * @dev Returns the downcasted int184 from int256, reverting on\n     * overflow (when the input is less than smallest int184 or\n     * greater than largest int184).\n     *\n     * Counterpart to Solidity's `int184` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 184 bits\n     *\n     * _Available since v4.7._\n     */\n    function toInt184(int256 value) internal pure returns (int184 downcasted) {\n        downcasted = int184(value);\n        require(downcasted == value, \"SafeCast: value doesn't fit in 184 bits\");\n    }\n\n    /**\n     * @dev Returns the downcasted int176 from int256, reverting on\n     * overflow (when the input is less than smallest int176 or\n     * greater than largest int176).\n     *\n     * Counterpart to Solidity's `int176` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 176 bits\n     *\n     * _Available since v4.7._\n     */\n    function toInt176(int256 value) internal pure returns (int176 downcasted) {\n        downcasted = int176(value);\n        require(downcasted == value, \"SafeCast: value doesn't fit in 176 bits\");\n    }\n\n    /**\n     * @dev Returns the downcasted int168 from int256, reverting on\n     * overflow (when the input is less than smallest int168 or\n     * greater than largest int168).\n     *\n     * Counterpart to Solidity's `int168` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 168 bits\n     *\n     * _Available since v4.7._\n     */\n    function toInt168(int256 value) internal pure returns (int168 downcasted) {\n        downcasted = int168(value);\n        require(downcasted == value, \"SafeCast: value doesn't fit in 168 bits\");\n    }\n\n    /**\n     * @dev Returns the downcasted int160 from int256, reverting on\n     * overflow (when the input is less than smallest int160 or\n     * greater than largest int160).\n     *\n     * Counterpart to Solidity's `int160` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 160 bits\n     *\n     * _Available since v4.7._\n     */\n    function toInt160(int256 value) internal pure returns (int160 downcasted) {\n        downcasted = int160(value);\n        require(downcasted == value, \"SafeCast: value doesn't fit in 160 bits\");\n    }\n\n    /**\n     * @dev Returns the downcasted int152 from int256, reverting on\n     * overflow (when the input is less than smallest int152 or\n     * greater than largest int152).\n     *\n     * Counterpart to Solidity's `int152` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 152 bits\n     *\n     * _Available since v4.7._\n     */\n    function toInt152(int256 value) internal pure returns (int152 downcasted) {\n        downcasted = int152(value);\n        require(downcasted == value, \"SafeCast: value doesn't fit in 152 bits\");\n    }\n\n    /**\n     * @dev Returns the downcasted int144 from int256, reverting on\n     * overflow (when the input is less than smallest int144 or\n     * greater than largest int144).\n     *\n     * Counterpart to Solidity's `int144` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 144 bits\n     *\n     * _Available since v4.7._\n     */\n    function toInt144(int256 value) internal pure returns (int144 downcasted) {\n        downcasted = int144(value);\n        require(downcasted == value, \"SafeCast: value doesn't fit in 144 bits\");\n    }\n\n    /**\n     * @dev Returns the downcasted int136 from int256, reverting on\n     * overflow (when the input is less than smallest int136 or\n     * greater than largest int136).\n     *\n     * Counterpart to Solidity's `int136` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 136 bits\n     *\n     * _Available since v4.7._\n     */\n    function toInt136(int256 value) internal pure returns (int136 downcasted) {\n        downcasted = int136(value);\n        require(downcasted == value, \"SafeCast: value doesn't fit in 136 bits\");\n    }\n\n    /**\n     * @dev Returns the downcasted int128 from int256, reverting on\n     * overflow (when the input is less than smallest int128 or\n     * greater than largest int128).\n     *\n     * Counterpart to Solidity's `int128` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 128 bits\n     *\n     * _Available since v3.1._\n     */\n    function toInt128(int256 value) internal pure returns (int128 downcasted) {\n        downcasted = int128(value);\n        require(downcasted == value, \"SafeCast: value doesn't fit in 128 bits\");\n    }\n\n    /**\n     * @dev Returns the downcasted int120 from int256, reverting on\n     * overflow (when the input is less than smallest int120 or\n     * greater than largest int120).\n     *\n     * Counterpart to Solidity's `int120` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 120 bits\n     *\n     * _Available since v4.7._\n     */\n    function toInt120(int256 value) internal pure returns (int120 downcasted) {\n        downcasted = int120(value);\n        require(downcasted == value, \"SafeCast: value doesn't fit in 120 bits\");\n    }\n\n    /**\n     * @dev Returns the downcasted int112 from int256, reverting on\n     * overflow (when the input is less than smallest int112 or\n     * greater than largest int112).\n     *\n     * Counterpart to Solidity's `int112` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 112 bits\n     *\n     * _Available since v4.7._\n     */\n    function toInt112(int256 value) internal pure returns (int112 downcasted) {\n        downcasted = int112(value);\n        require(downcasted == value, \"SafeCast: value doesn't fit in 112 bits\");\n    }\n\n    /**\n     * @dev Returns the downcasted int104 from int256, reverting on\n     * overflow (when the input is less than smallest int104 or\n     * greater than largest int104).\n     *\n     * Counterpart to Solidity's `int104` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 104 bits\n     *\n     * _Available since v4.7._\n     */\n    function toInt104(int256 value) internal pure returns (int104 downcasted) {\n        downcasted = int104(value);\n        require(downcasted == value, \"SafeCast: value doesn't fit in 104 bits\");\n    }\n\n    /**\n     * @dev Returns the downcasted int96 from int256, reverting on\n     * overflow (when the input is less than smallest int96 or\n     * greater than largest int96).\n     *\n     * Counterpart to Solidity's `int96` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 96 bits\n     *\n     * _Available since v4.7._\n     */\n    function toInt96(int256 value) internal pure returns (int96 downcasted) {\n        downcasted = int96(value);\n        require(downcasted == value, \"SafeCast: value doesn't fit in 96 bits\");\n    }\n\n    /**\n     * @dev Returns the downcasted int88 from int256, reverting on\n     * overflow (when the input is less than smallest int88 or\n     * greater than largest int88).\n     *\n     * Counterpart to Solidity's `int88` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 88 bits\n     *\n     * _Available since v4.7._\n     */\n    function toInt88(int256 value) internal pure returns (int88 downcasted) {\n        downcasted = int88(value);\n        require(downcasted == value, \"SafeCast: value doesn't fit in 88 bits\");\n    }\n\n    /**\n     * @dev Returns the downcasted int80 from int256, reverting on\n     * overflow (when the input is less than smallest int80 or\n     * greater than largest int80).\n     *\n     * Counterpart to Solidity's `int80` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 80 bits\n     *\n     * _Available since v4.7._\n     */\n    function toInt80(int256 value) internal pure returns (int80 downcasted) {\n        downcasted = int80(value);\n        require(downcasted == value, \"SafeCast: value doesn't fit in 80 bits\");\n    }\n\n    /**\n     * @dev Returns the downcasted int72 from int256, reverting on\n     * overflow (when the input is less than smallest int72 or\n     * greater than largest int72).\n     *\n     * Counterpart to Solidity's `int72` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 72 bits\n     *\n     * _Available since v4.7._\n     */\n    function toInt72(int256 value) internal pure returns (int72 downcasted) {\n        downcasted = int72(value);\n        require(downcasted == value, \"SafeCast: value doesn't fit in 72 bits\");\n    }\n\n    /**\n     * @dev Returns the downcasted int64 from int256, reverting on\n     * overflow (when the input is less than smallest int64 or\n     * greater than largest int64).\n     *\n     * Counterpart to Solidity's `int64` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 64 bits\n     *\n     * _Available since v3.1._\n     */\n    function toInt64(int256 value) internal pure returns (int64 downcasted) {\n        downcasted = int64(value);\n        require(downcasted == value, \"SafeCast: value doesn't fit in 64 bits\");\n    }\n\n    /**\n     * @dev Returns the downcasted int56 from int256, reverting on\n     * overflow (when the input is less than smallest int56 or\n     * greater than largest int56).\n     *\n     * Counterpart to Solidity's `int56` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 56 bits\n     *\n     * _Available since v4.7._\n     */\n    function toInt56(int256 value) internal pure returns (int56 downcasted) {\n        downcasted = int56(value);\n        require(downcasted == value, \"SafeCast: value doesn't fit in 56 bits\");\n    }\n\n    /**\n     * @dev Returns the downcasted int48 from int256, reverting on\n     * overflow (when the input is less than smallest int48 or\n     * greater than largest int48).\n     *\n     * Counterpart to Solidity's `int48` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 48 bits\n     *\n     * _Available since v4.7._\n     */\n    function toInt48(int256 value) internal pure returns (int48 downcasted) {\n        downcasted = int48(value);\n        require(downcasted == value, \"SafeCast: value doesn't fit in 48 bits\");\n    }\n\n    /**\n     * @dev Returns the downcasted int40 from int256, reverting on\n     * overflow (when the input is less than smallest int40 or\n     * greater than largest int40).\n     *\n     * Counterpart to Solidity's `int40` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 40 bits\n     *\n     * _Available since v4.7._\n     */\n    function toInt40(int256 value) internal pure returns (int40 downcasted) {\n        downcasted = int40(value);\n        require(downcasted == value, \"SafeCast: value doesn't fit in 40 bits\");\n    }\n\n    /**\n     * @dev Returns the downcasted int32 from int256, reverting on\n     * overflow (when the input is less than smallest int32 or\n     * greater than largest int32).\n     *\n     * Counterpart to Solidity's `int32` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 32 bits\n     *\n     * _Available since v3.1._\n     */\n    function toInt32(int256 value) internal pure returns (int32 downcasted) {\n        downcasted = int32(value);\n        require(downcasted == value, \"SafeCast: value doesn't fit in 32 bits\");\n    }\n\n    /**\n     * @dev Returns the downcasted int24 from int256, reverting on\n     * overflow (when the input is less than smallest int24 or\n     * greater than largest int24).\n     *\n     * Counterpart to Solidity's `int24` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 24 bits\n     *\n     * _Available since v4.7._\n     */\n    function toInt24(int256 value) internal pure returns (int24 downcasted) {\n        downcasted = int24(value);\n        require(downcasted == value, \"SafeCast: value doesn't fit in 24 bits\");\n    }\n\n    /**\n     * @dev Returns the downcasted int16 from int256, reverting on\n     * overflow (when the input is less than smallest int16 or\n     * greater than largest int16).\n     *\n     * Counterpart to Solidity's `int16` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 16 bits\n     *\n     * _Available since v3.1._\n     */\n    function toInt16(int256 value) internal pure returns (int16 downcasted) {\n        downcasted = int16(value);\n        require(downcasted == value, \"SafeCast: value doesn't fit in 16 bits\");\n    }\n\n    /**\n     * @dev Returns the downcasted int8 from int256, reverting on\n     * overflow (when the input is less than smallest int8 or\n     * greater than largest int8).\n     *\n     * Counterpart to Solidity's `int8` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 8 bits\n     *\n     * _Available since v3.1._\n     */\n    function toInt8(int256 value) internal pure returns (int8 downcasted) {\n        downcasted = int8(value);\n        require(downcasted == value, \"SafeCast: value doesn't fit in 8 bits\");\n    }\n\n    /**\n     * @dev Converts an unsigned uint256 into a signed int256.\n     *\n     * Requirements:\n     *\n     * - input must be less than or equal to maxInt256.\n     *\n     * _Available since v3.0._\n     */\n    function toInt256(uint256 value) internal pure returns (int256) {\n        // Note: Unsafe cast below is okay because `type(int256).max` is guaranteed to be positive\n        require(value <= uint256(type(int256).max), \"SafeCast: value doesn't fit in an int256\");\n        return int256(value);\n    }\n}\n"},{"file_path":"lib/native-token-transfers/evm/src/libraries/external/OwnableUpgradeable.sol","source_code":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.0.0) (access/Ownable.sol)\n\n// COPIED FROM OPENZEPPELIN v5.0.1\n// COPIED TO CHANGE SOLC FROM ^0.8.20 TO ^0.8.19\n\npragma solidity ^0.8.19;\n\nimport {ContextUpgradeable} from \"./ContextUpgradeable.sol\";\nimport {Initializable} from \"./Initializable.sol\";\nimport \"../../interfaces/IOwnableUpgradeable.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 * The initial owner is set to the address provided by the deployer. This can\n * 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, IOwnableUpgradeable {\n    /// @custom:storage-location erc7201:openzeppelin.storage.Ownable\n    struct OwnableStorage {\n        address _owner;\n    }\n\n    // keccak256(abi.encode(uint256(keccak256(\"openzeppelin.storage.Ownable\")) - 1)) & ~bytes32(uint256(0xff))\n    bytes32 private constant OwnableStorageLocation =\n        0x9016d09d72d40fdae2fd8ceac6b6234c7706214fd39c1cd1e609a0528c199300;\n\n    function _getOwnableStorage() private pure returns (OwnableStorage storage $) {\n        assembly {\n            $.slot := OwnableStorageLocation\n        }\n    }\n\n    /**\n     * @dev The caller account is not authorized to perform an operation.\n     */\n    error OwnableUnauthorizedAccount(address account);\n\n    /**\n     * @dev The owner is not a valid owner account. (eg. `address(0)`)\n     */\n    error OwnableInvalidOwner(address owner);\n\n    event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n    /**\n     * @dev Initializes the contract setting the address provided by the deployer as the initial owner.\n     */\n    function __Ownable_init(\n        address initialOwner\n    ) internal onlyInitializing {\n        __Ownable_init_unchained(initialOwner);\n    }\n\n    function __Ownable_init_unchained(\n        address initialOwner\n    ) internal onlyInitializing {\n        if (initialOwner == address(0)) {\n            revert OwnableInvalidOwner(address(0));\n        }\n        _transferOwnership(initialOwner);\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        OwnableStorage storage $ = _getOwnableStorage();\n        return $._owner;\n    }\n\n    /**\n     * @dev Throws if the sender is not the owner.\n     */\n    function _checkOwner() internal view virtual {\n        if (owner() != _msgSender()) {\n            revert OwnableUnauthorizedAccount(_msgSender());\n        }\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(\n        address newOwner\n    ) public virtual onlyOwner {\n        if (newOwner == address(0)) {\n            revert OwnableInvalidOwner(address(0));\n        }\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(\n        address newOwner\n    ) internal virtual {\n        OwnableStorage storage $ = _getOwnableStorage();\n        address oldOwner = $._owner;\n        $._owner = newOwner;\n        emit OwnershipTransferred(oldOwner, newOwner);\n    }\n}\n"},{"file_path":"lib/native-token-transfers/evm/src/libraries/PausableUpgradeable.sol","source_code":"// SPDX-License-Identifier: Apache 2\npragma solidity >=0.8.8 <0.9.0;\n\n/**\n * @dev Contact Module that allows children to implement logic to pause and unpause the contract.\n * This is based on the OpenZeppelin Pausable contract but makes use of deterministic storage slots\n * and the EVM native word size to optimize gas costs.\n *\n * The `whenPaused` and `whenNotPaused` modifiers are used to\n * execute code based on the current state of the contract.\n *\n */\nimport {Initializable} from \"./external/Initializable.sol\";\n\nabstract contract PausableUpgradeable is Initializable {\n    /*\n     * @custom:storage-location erc7201:openzeppelin.storage.Pausable.\n     * @dev Storage slot with the pauser account, this is managed by the `PauserStorage` struct\n    */\n    struct PauserStorage {\n        address _pauser;\n    }\n\n    // @dev Storage slot with the pause flag, this is managed by the `PauseStorage` struct\n    struct PauseStorage {\n        uint256 _pauseFlag;\n    }\n\n    /// NOTE: use uint256 to save on gas because it is the native word size of the EVM\n    /// it is cheaper than using a bool because modifying a boolean value requires an extra SLOAD\n    uint256 private constant NOT_PAUSED = 1;\n    uint256 private constant PAUSED = 2;\n\n    event PauserTransferred(address indexed oldPauser, address indexed newPauser);\n\n    /**\n     * @dev Contract is not paused, functionality is unblocked\n     */\n    error RequireContractIsNotPaused();\n    /**\n     * @dev Contract state is paused, blocking\n     */\n    error RequireContractIsPaused();\n\n    /**\n     * @dev the pauser is not a valid pauser account (e.g. `address(0)`)\n     */\n    error InvalidPauser(address account);\n\n    // @dev Emitted when the contract is paused\n    event Paused(bool paused);\n    event NotPaused(bool notPaused);\n\n    bytes32 private constant PAUSE_SLOT = bytes32(uint256(keccak256(\"Pause.pauseFlag\")) - 1);\n    bytes32 private constant PAUSER_ROLE_SLOT = bytes32(uint256(keccak256(\"Pause.pauseRole\")) - 1);\n\n    function _getPauserStorage() internal pure returns (PauserStorage storage $) {\n        uint256 slot = uint256(PAUSER_ROLE_SLOT);\n        assembly (\"memory-safe\") {\n            $.slot := slot\n        }\n    }\n\n    /**\n     * @dev Returns the current pauser account address.\n     */\n    function pauser() public view returns (address) {\n        return _getPauserStorage()._pauser;\n    }\n\n    function _getPauseStorage() private pure returns (PauseStorage storage $) {\n        uint256 slot = uint256(PAUSE_SLOT);\n        assembly (\"memory-safe\") {\n            $.slot := slot\n        }\n    }\n\n    function _setPauseStorage(\n        uint256 pauseFlag\n    ) internal {\n        _getPauseStorage()._pauseFlag = pauseFlag;\n    }\n\n    function __Paused_init(\n        address initialPauser\n    ) internal onlyInitializing {\n        __Paused_init_unchained(initialPauser);\n    }\n\n    function __Paused_init_unchained(\n        address initialPauser\n    ) internal onlyInitializing {\n        // set pause flag to false initially\n        PauseStorage storage $ = _getPauseStorage();\n        $._pauseFlag = NOT_PAUSED;\n\n        // set the initial pauser\n        PauserStorage storage $_role = _getPauserStorage();\n        $_role._pauser = initialPauser;\n    }\n\n    /**\n     * @dev Modifier to make a function callable only when the contract is not paused.\n     * Calling a function when this flag is set to `PAUSED` will cause the transaction to revert.\n     */\n    modifier whenNotPaused() {\n        if (isPaused()) {\n            revert RequireContractIsNotPaused();\n        }\n        _;\n    }\n\n    /**\n     * @dev Modifier to make a function callable only when the contract is not paused.\n     * Calling a function when this flag is set to `PAUSED` will cause the transaction to revert.\n     */\n    modifier whenPaused() {\n        if (!isPaused()) {\n            revert RequireContractIsPaused();\n        }\n        _;\n    }\n\n    /*\n     * @dev Modifier to allow only the Pauser to access pausing functionality\n     */\n    modifier onlyPauser() {\n        _checkPauser();\n        _;\n    }\n\n    /*\n     * @dev Modifier to allow only the Pauser to access some functionality\n     */\n    function _checkPauser() internal view {\n        if (pauser() != msg.sender) {\n            revert InvalidPauser(msg.sender);\n        }\n    }\n\n    /**\n     * @dev pauses the function and emits the `Paused` event\n     */\n    function _pause() internal virtual whenNotPaused {\n        // this can only be set to PAUSED when the state is NOTPAUSED\n        _setPauseStorage(PAUSED);\n        emit Paused(true);\n    }\n\n    /**\n     * @dev unpauses the function\n     */\n    function _unpause() internal virtual whenPaused {\n        // this can only be set to NOTPAUSED when the state is PAUSED\n        _setPauseStorage(NOT_PAUSED);\n        emit NotPaused(false);\n    }\n\n    /**\n     * @dev Returns true if the method is paused, and false otherwise.\n     */\n    function isPaused() public view returns (bool) {\n        PauseStorage storage $ = _getPauseStorage();\n        return $._pauseFlag == PAUSED;\n    }\n}\n"},{"file_path":"lib/native-token-transfers/evm/src/libraries/TransceiverStructs.sol","source_code":"// SPDX-License-Identifier: Apache 2\npragma solidity >=0.8.8 <0.9.0;\n\nimport \"wormhole-solidity-sdk/libraries/BytesParsing.sol\";\nimport \"./TrimmedAmount.sol\";\n\nlibrary TransceiverStructs {\n    using BytesParsing for bytes;\n    using TrimmedAmountLib for TrimmedAmount;\n\n    /// @notice Error thrown when the payload length exceeds the allowed maximum.\n    /// @dev Selector 0xa3419691.\n    /// @param size The size of the payload.\n    error PayloadTooLong(uint256 size);\n\n    /// @notice Error thrown when the prefix of an encoded message\n    ///         does not match the expected value.\n    /// @dev Selector 0x56d2569d.\n    /// @param prefix The prefix that was found in the encoded message.\n    error IncorrectPrefix(bytes4 prefix);\n\n    /// @notice Error thrown when the transceiver instructions aren't\n    ///         encoded with strictly increasing indices\n    /// @dev Selector 0x0555a4b9.\n    /// @param lastIndex Last parsed instruction index\n    /// @param instructionIndex The instruction index that was unordered\n    error UnorderedInstructions(uint256 lastIndex, uint256 instructionIndex);\n\n    /// @notice Error thrown when a transceiver instruction index\n    ///         is greater than the number of registered transceivers\n    /// @dev We index from 0 so if providedIndex == numTransceivers then we're out-of-bounds too\n    /// @dev Selector 0x689f5016.\n    /// @param providedIndex The index specified in the instruction\n    /// @param numTransceivers The number of registered transceivers\n    error InvalidInstructionIndex(uint256 providedIndex, uint256 numTransceivers);\n\n    /// @dev Prefix for all NativeTokenTransfer payloads\n    ///      This is 0x99'N''T''T'\n    bytes4 constant NTT_PREFIX = 0x994E5454;\n\n    /// @dev Message emitted and received by the nttManager contract.\n    ///      The wire format is as follows:\n    ///      - id - 32 bytes\n    ///      - sender - 32 bytes\n    ///      - payloadLength - 2 bytes\n    ///      - payload - `payloadLength` bytes\n    struct NttManagerMessage {\n        /// @notice unique message identifier\n        /// @dev This is incrementally assigned on EVM chains, but this is not\n        /// guaranteed on other runtimes.\n        bytes32 id;\n        /// @notice original message sender address.\n        bytes32 sender;\n        /// @notice payload that corresponds to the type.\n        bytes payload;\n    }\n\n    function nttManagerMessageDigest(\n        uint16 sourceChainId,\n        NttManagerMessage memory m\n    ) public pure returns (bytes32) {\n        return _nttManagerMessageDigest(sourceChainId, encodeNttManagerMessage(m));\n    }\n\n    function _nttManagerMessageDigest(\n        uint16 sourceChainId,\n        bytes memory encodedNttManagerMessage\n    ) internal pure returns (bytes32) {\n        return keccak256(abi.encodePacked(sourceChainId, encodedNttManagerMessage));\n    }\n\n    function encodeNttManagerMessage(\n        NttManagerMessage memory m\n    ) public pure returns (bytes memory encoded) {\n        if (m.payload.length > type(uint16).max) {\n            revert PayloadTooLong(m.payload.length);\n        }\n        uint16 payloadLength = uint16(m.payload.length);\n        return abi.encodePacked(m.id, m.sender, payloadLength, m.payload);\n    }\n\n    /// @notice Parse a NttManagerMessage.\n    /// @param encoded The byte array corresponding to the encoded message\n    /// @return nttManagerMessage The parsed NttManagerMessage struct.\n    function parseNttManagerMessage(\n        bytes memory encoded\n    ) public pure returns (NttManagerMessage memory nttManagerMessage) {\n        uint256 offset = 0;\n        (nttManagerMessage.id, offset) = encoded.asBytes32Unchecked(offset);\n        (nttManagerMessage.sender, offset) = encoded.asBytes32Unchecked(offset);\n        uint256 payloadLength;\n        (payloadLength, offset) = encoded.asUint16Unchecked(offset);\n        (nttManagerMessage.payload, offset) = encoded.sliceUnchecked(offset, payloadLength);\n        encoded.checkLength(offset);\n    }\n\n    /// @dev Native Token Transfer payload.\n    ///      The wire format is as follows:\n    ///      - NTT_PREFIX - 4 bytes\n    ///      - numDecimals - 1 byte\n    ///      - amount - 8 bytes\n    ///      - sourceToken - 32 bytes\n    ///      - to - 32 bytes\n    ///      - toChain - 2 bytes\n    ///      - additionalPayloadLength - 2 bytes, optional\n    ///      - additionalPayload - `additionalPayloadLength` bytes\n    struct NativeTokenTransfer {\n        /// @notice Amount being transferred (big-endian u64 and u8 for decimals)\n        TrimmedAmount amount;\n        /// @notice Source chain token address.\n        bytes32 sourceToken;\n        /// @notice Address of the recipient.\n        bytes32 to;\n        /// @notice Chain ID of the recipient\n        uint16 toChain;\n        /// @notice Custom payload\n        /// @dev Recommended that the first 4 bytes are a unique prefix\n        bytes additionalPayload;\n    }\n\n    function encodeNativeTokenTransfer(\n        NativeTokenTransfer memory m\n    ) public pure returns (bytes memory encoded) {\n        // The `amount` and `decimals` fields are encoded in reverse order compared to how they are declared in the\n        // `TrimmedAmount` type. This is consistent with the Rust NTT implementation.\n        TrimmedAmount transferAmount = m.amount;\n        if (m.additionalPayload.length > 0) {\n            if (m.additionalPayload.length > type(uint16).max) {\n                revert PayloadTooLong(m.additionalPayload.length);\n            }\n            uint16 additionalPayloadLength = uint16(m.additionalPayload.length);\n            return abi.encodePacked(\n                NTT_PREFIX,\n                transferAmount.getDecimals(),\n                transferAmount.getAmount(),\n                m.sourceToken,\n                m.to,\n                m.toChain,\n                additionalPayloadLength,\n                m.additionalPayload\n            );\n        }\n        return abi.encodePacked(\n            NTT_PREFIX,\n            transferAmount.getDecimals(),\n            transferAmount.getAmount(),\n            m.sourceToken,\n            m.to,\n            m.toChain\n        );\n    }\n\n    /// @dev Parse a NativeTokenTransfer.\n    /// @param encoded The byte array corresponding to the encoded message\n    /// @return nativeTokenTransfer The parsed NativeTokenTransfer struct.\n    function parseNativeTokenTransfer(\n        bytes memory encoded\n    ) public pure returns (NativeTokenTransfer memory nativeTokenTransfer) {\n        uint256 offset = 0;\n        bytes4 prefix;\n        (prefix, offset) = encoded.asBytes4Unchecked(offset);\n        if (prefix != NTT_PREFIX) {\n            revert IncorrectPrefix(prefix);\n        }\n\n        // The `amount` and `decimals` fields are parsed in reverse order compared to how they are declared in the\n        // `TrimmedAmount` struct. This is consistent with the Rust NTT implementation.\n        uint8 numDecimals;\n        (numDecimals, offset) = encoded.asUint8Unchecked(offset);\n        uint64 amount;\n        (amount, offset) = encoded.asUint64Unchecked(offset);\n        nativeTokenTransfer.amount = packTrimmedAmount(amount, numDecimals);\n\n        (nativeTokenTransfer.sourceToken, offset) = encoded.asBytes32Unchecked(offset);\n        (nativeTokenTransfer.to, offset) = encoded.asBytes32Unchecked(offset);\n        (nativeTokenTransfer.toChain, offset) = encoded.asUint16Unchecked(offset);\n        // The additional payload may be omitted, but if it is included, it is prefixed by a u16 for its length.\n        // If there are at least 2 bytes remaining, attempt to parse the additional payload.\n        if (encoded.length >= offset + 2) {\n            uint256 payloadLength;\n            (payloadLength, offset) = encoded.asUint16Unchecked(offset);\n            (nativeTokenTransfer.additionalPayload, offset) =\n                encoded.sliceUnchecked(offset, payloadLength);\n        }\n        encoded.checkLength(offset);\n    }\n\n    /// @dev Message emitted by Transceiver implementations.\n    ///      Each message includes an Transceiver-specified 4-byte prefix.\n    ///      The wire format is as follows:\n    ///      - prefix - 4 bytes\n    ///      - sourceNttManagerAddress - 32 bytes\n    ///      - recipientNttManagerAddress - 32 bytes\n    ///      - nttManagerPayloadLength - 2 bytes\n    ///      - nttManagerPayload - `nttManagerPayloadLength` bytes\n    ///      - transceiverPayloadLength - 2 bytes\n    ///      - transceiverPayload - `transceiverPayloadLength` bytes\n    struct TransceiverMessage {\n        /// @notice Address of the NttManager contract that emitted this message.\n        bytes32 sourceNttManagerAddress;\n        /// @notice Address of the NttManager contract that receives this message.\n        bytes32 recipientNttManagerAddress;\n        /// @notice Payload provided to the Transceiver contract by the NttManager contract.\n        bytes nttManagerPayload;\n        /// @notice Optional payload that the transceiver can encode and use for its own message passing purposes.\n        bytes transceiverPayload;\n    }\n\n    // @notice Encodes an Transceiver message for communication between the\n    //         NttManager and the Transceiver.\n    // @param m The TransceiverMessage struct containing the message details.\n    // @return encoded The byte array corresponding to the encoded message.\n    // @custom:throw PayloadTooLong if the length of transceiverId, nttManagerPayload,\n    //         or transceiverPayload exceeds the allowed maximum.\n    function encodeTransceiverMessage(\n        bytes4 prefix,\n        TransceiverMessage memory m\n    ) public pure returns (bytes memory encoded) {\n        if (m.nttManagerPayload.length > type(uint16).max) {\n            revert PayloadTooLong(m.nttManagerPayload.length);\n        }\n        uint16 nttManagerPayloadLength = uint16(m.nttManagerPayload.length);\n\n        if (m.transceiverPayload.length > type(uint16).max) {\n            revert PayloadTooLong(m.transceiverPayload.length);\n        }\n        uint16 transceiverPayloadLength = uint16(m.transceiverPayload.length);\n\n        return abi.encodePacked(\n            prefix,\n            m.sourceNttManagerAddress,\n            m.recipientNttManagerAddress,\n            nttManagerPayloadLength,\n            m.nttManagerPayload,\n            transceiverPayloadLength,\n            m.transceiverPayload\n        );\n    }\n\n    function buildAndEncodeTransceiverMessage(\n        bytes4 prefix,\n        bytes32 sourceNttManagerAddress,\n        bytes32 recipientNttManagerAddress,\n        bytes memory nttManagerMessage,\n        bytes memory transceiverPayload\n    ) public pure returns (TransceiverMessage memory, bytes memory) {\n        TransceiverMessage memory transceiverMessage = TransceiverMessage({\n            sourceNttManagerAddress: sourceNttManagerAddress,\n            recipientNttManagerAddress: recipientNttManagerAddress,\n            nttManagerPayload: nttManagerMessage,\n            transceiverPayload: transceiverPayload\n        });\n        bytes memory encoded = encodeTransceiverMessage(prefix, transceiverMessage);\n        return (transceiverMessage, encoded);\n    }\n\n    /// @dev Parses an encoded message and extracts information into an TransceiverMessage struct.\n    /// @param encoded The encoded bytes containing information about the TransceiverMessage.\n    /// @return transceiverMessage The parsed TransceiverMessage struct.\n    /// @custom:throw IncorrectPrefix if the prefix of the encoded message does not\n    ///         match the expected prefix.\n    function parseTransceiverMessage(\n        bytes4 expectedPrefix,\n        bytes memory encoded\n    ) internal pure returns (TransceiverMessage memory transceiverMessage) {\n        uint256 offset = 0;\n        bytes4 prefix;\n\n        (prefix, offset) = encoded.asBytes4Unchecked(offset);\n\n        if (prefix != expectedPrefix) {\n            revert IncorrectPrefix(prefix);\n        }\n\n        (transceiverMessage.sourceNttManagerAddress, offset) = encoded.asBytes32Unchecked(offset);\n        (transceiverMessage.recipientNttManagerAddress, offset) = encoded.asBytes32Unchecked(offset);\n        uint16 nttManagerPayloadLength;\n        (nttManagerPayloadLength, offset) = encoded.asUint16Unchecked(offset);\n        (transceiverMessage.nttManagerPayload, offset) =\n            encoded.sliceUnchecked(offset, nttManagerPayloadLength);\n        uint16 transceiverPayloadLength;\n        (transceiverPayloadLength, offset) = encoded.asUint16Unchecked(offset);\n        (transceiverMessage.transceiverPayload, offset) =\n            encoded.sliceUnchecked(offset, transceiverPayloadLength);\n\n        // Check if the entire byte array has been processed\n        encoded.checkLength(offset);\n    }\n\n    /// @dev Parses the payload of an Transceiver message and returns\n    ///      the parsed NttManagerMessage struct.\n    /// @param expectedPrefix The prefix that should be encoded in the nttManager message.\n    /// @param payload The payload sent across the wire.\n    function parseTransceiverAndNttManagerMessage(\n        bytes4 expectedPrefix,\n        bytes memory payload\n    ) public pure returns (TransceiverMessage memory, NttManagerMessage memory) {\n        // parse the encoded message payload from the Transceiver\n        TransceiverMessage memory parsedTransceiverMessage =\n            parseTransceiverMessage(expectedPrefix, payload);\n\n        // parse the encoded message payload from the NttManager\n        NttManagerMessage memory parsedNttManagerMessage =\n            parseNttManagerMessage(parsedTransceiverMessage.nttManagerPayload);\n\n        return (parsedTransceiverMessage, parsedNttManagerMessage);\n    }\n\n    /// @dev Variable-length transceiver-specific instruction that can be passed by the caller to the nttManager.\n    ///      The index field refers to the index of the registeredTransceiver that this instruction should be passed to.\n    ///      The serialization format is:\n    ///      - index - 1 byte\n    ///      - payloadLength - 1 byte\n    ///      - payload - `payloadLength` bytes\n    struct TransceiverInstruction {\n        uint8 index;\n        bytes payload;\n    }\n\n    function encodeTransceiverInstruction(\n        TransceiverInstruction memory instruction\n    ) public pure returns (bytes memory) {\n        if (instruction.payload.length > type(uint8).max) {\n            revert PayloadTooLong(instruction.payload.length);\n        }\n        uint8 payloadLength = uint8(instruction.payload.length);\n        return abi.encodePacked(instruction.index, payloadLength, instruction.payload);\n    }\n\n    function parseTransceiverInstructionUnchecked(\n        bytes memory encoded,\n        uint256 offset\n    ) public pure returns (TransceiverInstruction memory instruction, uint256 nextOffset) {\n        (instruction.index, nextOffset) = encoded.asUint8Unchecked(offset);\n        uint8 instructionLength;\n        (instructionLength, nextOffset) = encoded.asUint8Unchecked(nextOffset);\n        (instruction.payload, nextOffset) = encoded.sliceUnchecked(nextOffset, instructionLength);\n    }\n\n    function parseTransceiverInstructionChecked(\n        bytes memory encoded\n    ) public pure returns (TransceiverInstruction memory instruction) {\n        uint256 offset = 0;\n        (instruction, offset) = parseTransceiverInstructionUnchecked(encoded, offset);\n        encoded.checkLength(offset);\n    }\n\n    /// @dev Encode an array of multiple variable-length transceiver-specific instructions.\n    ///      The serialization format is:\n    ///      - instructionsLength - 1 byte\n    ///      - `instructionsLength` number of serialized `TransceiverInstruction` types.\n    function encodeTransceiverInstructions(\n        TransceiverInstruction[] memory instructions\n    ) public pure returns (bytes memory) {\n        if (instructions.length > type(uint8).max) {\n            revert PayloadTooLong(instructions.length);\n        }\n        uint256 instructionsLength = instructions.length;\n\n        bytes memory encoded;\n        for (uint256 i = 0; i < instructionsLength; i++) {\n            bytes memory innerEncoded = encodeTransceiverInstruction(instructions[i]);\n            encoded = bytes.concat(encoded, innerEncoded);\n        }\n        return abi.encodePacked(uint8(instructionsLength), encoded);\n    }\n\n    function parseTransceiverInstructions(\n        bytes memory encoded,\n        uint256 numRegisteredTransceivers\n    ) public pure returns (TransceiverInstruction[] memory) {\n        uint256 offset = 0;\n        uint256 instructionsLength;\n        (instructionsLength, offset) = encoded.asUint8Unchecked(offset);\n\n        // We allocate an array with the length of the number of registered transceivers\n        // This gives us the flexibility to not have to pass instructions for transceivers that\n        // don't need them\n        TransceiverInstruction[] memory instructions =\n            new TransceiverInstruction[](numRegisteredTransceivers);\n\n        uint256 lastIndex = 0;\n        for (uint256 i = 0; i < instructionsLength; i++) {\n            TransceiverInstruction memory instruction;\n            (instruction, offset) = parseTransceiverInstructionUnchecked(encoded, offset);\n\n            uint8 instructionIndex = instruction.index;\n\n            // The instructions passed in have to be strictly increasing in terms of transceiver index\n            if (i != 0 && instructionIndex <= lastIndex) {\n                revert UnorderedInstructions(lastIndex, instructionIndex);\n            }\n\n            // Instruction index is out of bounds\n            if (instructionIndex >= numRegisteredTransceivers) {\n                revert InvalidInstructionIndex(instructionIndex, numRegisteredTransceivers);\n            }\n\n            lastIndex = instructionIndex;\n\n            instructions[instructionIndex] = instruction;\n        }\n\n        encoded.checkLength(offset);\n\n        return instructions;\n    }\n\n    struct TransceiverInit {\n        bytes4 transceiverIdentifier;\n        bytes32 nttManagerAddress;\n        uint8 nttManagerMode;\n        bytes32 tokenAddress;\n        uint8 tokenDecimals;\n    }\n\n    function encodeTransceiverInit(\n        TransceiverInit memory init\n    ) public pure returns (bytes memory) {\n        return abi.encodePacked(\n            init.transceiverIdentifier,\n            init.nttManagerAddress,\n            init.nttManagerMode,\n            init.tokenAddress,\n            init.tokenDecimals\n        );\n    }\n\n    function decodeTransceiverInit(\n        bytes memory encoded\n    ) public pure returns (TransceiverInit memory init) {\n        uint256 offset = 0;\n        (init.transceiverIdentifier, offset) = encoded.asBytes4Unchecked(offset);\n        (init.nttManagerAddress, offset) = encoded.asBytes32Unchecked(offset);\n        (init.nttManagerMode, offset) = encoded.asUint8Unchecked(offset);\n        (init.tokenAddress, offset) = encoded.asBytes32Unchecked(offset);\n        (init.tokenDecimals, offset) = encoded.asUint8Unchecked(offset);\n        encoded.checkLength(offset);\n    }\n\n    struct TransceiverRegistration {\n        bytes4 transceiverIdentifier;\n        uint16 transceiverChainId;\n        bytes32 transceiverAddress;\n    }\n\n    function encodeTransceiverRegistration(\n        TransceiverRegistration memory registration\n    ) public pure returns (bytes memory) {\n        return abi.encodePacked(\n            registration.transceiverIdentifier,\n            registration.transceiverChainId,\n            registration.transceiverAddress\n        );\n    }\n\n    function decodeTransceiverRegistration(\n        bytes memory encoded\n    ) public pure returns (TransceiverRegistration memory registration) {\n        uint256 offset = 0;\n        (registration.transceiverIdentifier, offset) = encoded.asBytes4Unchecked(offset);\n        (registration.transceiverChainId, offset) = encoded.asUint16Unchecked(offset);\n        (registration.transceiverAddress, offset) = encoded.asBytes32Unchecked(offset);\n        encoded.checkLength(offset);\n    }\n}\n"},{"file_path":"lib/native-token-transfers/evm/lib/openzeppelin-contracts/contracts/token/ERC20/extensions/IERC20Metadata.sol","source_code":"// 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"},{"file_path":"lib/native-token-transfers/evm/lib/openzeppelin-contracts/contracts/interfaces/draft-IERC1822.sol","source_code":"// 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"},{"file_path":"lib/native-token-transfers/evm/lib/openzeppelin-contracts/contracts/token/ERC20/extensions/ERC20Burnable.sol","source_code":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC20/extensions/ERC20Burnable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../ERC20.sol\";\nimport \"../../../utils/Context.sol\";\n\n/**\n * @dev Extension of {ERC20} that allows token holders to destroy both their own\n * tokens and those that they have an allowance for, in a way that can be\n * recognized off-chain (via event analysis).\n */\nabstract contract ERC20Burnable is Context, ERC20 {\n    /**\n     * @dev Destroys `amount` tokens from the caller.\n     *\n     * See {ERC20-_burn}.\n     */\n    function burn(uint256 amount) public virtual {\n        _burn(_msgSender(), amount);\n    }\n\n    /**\n     * @dev Destroys `amount` tokens from `account`, deducting from the caller's\n     * allowance.\n     *\n     * See {ERC20-_burn} and {ERC20-allowance}.\n     *\n     * Requirements:\n     *\n     * - the caller must have allowance for ``accounts``'s tokens of at least\n     * `amount`.\n     */\n    function burnFrom(address account, uint256 amount) public virtual {\n        _spendAllowance(account, _msgSender(), amount);\n        _burn(account, amount);\n    }\n}\n"},{"file_path":"lib/native-token-transfers/evm/lib/openzeppelin-contracts/contracts/proxy/beacon/IBeacon.sol","source_code":"// 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"},{"file_path":"lib/native-token-transfers/evm/src/libraries/external/ContextUpgradeable.sol","source_code":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.0.1) (utils/Context.sol)\n\n// COPIED FROM OPENZEPPELIN v5.0.1\n// COPIED TO CHANGE SOLC FROM ^0.8.20 TO ^0.8.19\n\npragma solidity ^0.8.19;\n\nimport {Initializable} from \"./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    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    function _contextSuffixLength() internal view virtual returns (uint256) {\n        return 0;\n    }\n}\n"},{"file_path":"lib/native-token-transfers/evm/lib/openzeppelin-contracts/contracts/token/ERC20/utils/SafeERC20.sol","source_code":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.8.0) (token/ERC20/utils/SafeERC20.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC20.sol\";\nimport \"../extensions/draft-IERC20Permit.sol\";\nimport \"../../../utils/Address.sol\";\n\n/**\n * @title SafeERC20\n * @dev Wrappers around ERC20 operations that throw on failure (when the token\n * contract returns false). Tokens that return no value (and instead revert or\n * throw on failure) are also supported, non-reverting calls are assumed to be\n * successful.\n * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,\n * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\n */\nlibrary SafeERC20 {\n    using Address for address;\n\n    function safeTransfer(\n        IERC20 token,\n        address to,\n        uint256 value\n    ) internal {\n        _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\n    }\n\n    function safeTransferFrom(\n        IERC20 token,\n        address from,\n        address to,\n        uint256 value\n    ) internal {\n        _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));\n    }\n\n    /**\n     * @dev Deprecated. This function has issues similar to the ones found in\n     * {IERC20-approve}, and its usage is discouraged.\n     *\n     * Whenever possible, use {safeIncreaseAllowance} and\n     * {safeDecreaseAllowance} instead.\n     */\n    function safeApprove(\n        IERC20 token,\n        address spender,\n        uint256 value\n    ) internal {\n        // safeApprove should only be called when setting an initial allowance,\n        // or when resetting it to zero. To increase and decrease it, use\n        // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'\n        require(\n            (value == 0) || (token.allowance(address(this), spender) == 0),\n            \"SafeERC20: approve from non-zero to non-zero allowance\"\n        );\n        _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));\n    }\n\n    function safeIncreaseAllowance(\n        IERC20 token,\n        address spender,\n        uint256 value\n    ) internal {\n        uint256 newAllowance = token.allowance(address(this), spender) + value;\n        _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\n    }\n\n    function safeDecreaseAllowance(\n        IERC20 token,\n        address spender,\n        uint256 value\n    ) internal {\n        unchecked {\n            uint256 oldAllowance = token.allowance(address(this), spender);\n            require(oldAllowance >= value, \"SafeERC20: decreased allowance below zero\");\n            uint256 newAllowance = oldAllowance - value;\n            _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\n        }\n    }\n\n    function safePermit(\n        IERC20Permit token,\n        address owner,\n        address spender,\n        uint256 value,\n        uint256 deadline,\n        uint8 v,\n        bytes32 r,\n        bytes32 s\n    ) internal {\n        uint256 nonceBefore = token.nonces(owner);\n        token.permit(owner, spender, value, deadline, v, r, s);\n        uint256 nonceAfter = token.nonces(owner);\n        require(nonceAfter == nonceBefore + 1, \"SafeERC20: permit did not succeed\");\n    }\n\n    /**\n     * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\n     * on the return value: the return value is optional (but if data is returned, it must not be false).\n     * @param token The token targeted by the call.\n     * @param data The call data (encoded using abi.encode or one of its variants).\n     */\n    function _callOptionalReturn(IERC20 token, bytes memory data) private {\n        // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\n        // we're implementing it ourselves. We use {Address-functionCall} to perform this call, which verifies that\n        // the target address contains contract code and also asserts for success in the low-level call.\n\n        bytes memory returndata = address(token).functionCall(data, \"SafeERC20: low-level call failed\");\n        if (returndata.length > 0) {\n            // Return data is optional\n            require(abi.decode(returndata, (bool)), \"SafeERC20: ERC20 operation did not succeed\");\n        }\n    }\n}\n"},{"file_path":"lib/native-token-transfers/evm/src/libraries/RateLimiter.sol","source_code":"// SPDX-License-Identifier: Apache 2\npragma solidity >=0.8.8 <0.9.0;\n\nimport \"../interfaces/IRateLimiter.sol\";\nimport \"../interfaces/IRateLimiterEvents.sol\";\nimport \"./TransceiverHelpers.sol\";\nimport \"./TransceiverStructs.sol\";\nimport \"../libraries/TrimmedAmount.sol\";\nimport \"openzeppelin-contracts/contracts/utils/math/SafeCast.sol\";\n\nabstract contract RateLimiter is IRateLimiter, IRateLimiterEvents {\n    using TrimmedAmountLib for TrimmedAmount;\n\n    /// @dev The duration (in seconds) it takes for the limits to fully replenish.\n    uint64 public immutable rateLimitDuration;\n\n    /// =============== STORAGE ===============================================\n\n    bytes32 private constant OUTBOUND_LIMIT_PARAMS_SLOT =\n        bytes32(uint256(keccak256(\"ntt.outboundLimitParams\")) - 1);\n\n    bytes32 private constant OUTBOUND_QUEUE_SLOT =\n        bytes32(uint256(keccak256(\"ntt.outboundQueue\")) - 1);\n\n    bytes32 private constant INBOUND_LIMIT_PARAMS_SLOT =\n        bytes32(uint256(keccak256(\"ntt.inboundLimitParams\")) - 1);\n\n    bytes32 private constant INBOUND_QUEUE_SLOT =\n        bytes32(uint256(keccak256(\"ntt.inboundQueue\")) - 1);\n\n    function _getOutboundLimitParamsStorage() internal pure returns (RateLimitParams storage $) {\n        uint256 slot = uint256(OUTBOUND_LIMIT_PARAMS_SLOT);\n        assembly (\"memory-safe\") {\n            $.slot := slot\n        }\n    }\n\n    function _getOutboundQueueStorage()\n        internal\n        pure\n        returns (mapping(uint64 => OutboundQueuedTransfer) storage $)\n    {\n        uint256 slot = uint256(OUTBOUND_QUEUE_SLOT);\n        assembly (\"memory-safe\") {\n            $.slot := slot\n        }\n    }\n\n    function _getInboundLimitParamsStorage()\n        internal\n        pure\n        returns (mapping(uint16 => RateLimitParams) storage $)\n    {\n        uint256 slot = uint256(INBOUND_LIMIT_PARAMS_SLOT);\n        assembly (\"memory-safe\") {\n            $.slot := slot\n        }\n    }\n\n    function _getInboundQueueStorage()\n        internal\n        pure\n        returns (mapping(bytes32 => InboundQueuedTransfer) storage $)\n    {\n        uint256 slot = uint256(INBOUND_QUEUE_SLOT);\n        assembly (\"memory-safe\") {\n            $.slot := slot\n        }\n    }\n\n    constructor(uint64 _rateLimitDuration, bool _skipRateLimiting) {\n        if (\n            _rateLimitDuration == 0 && !_skipRateLimiting\n                || _rateLimitDuration != 0 && _skipRateLimiting\n        ) {\n            revert UndefinedRateLimiting();\n        }\n\n        rateLimitDuration = _rateLimitDuration;\n    }\n\n    function _setLimit(TrimmedAmount limit, RateLimitParams storage rateLimitParams) internal {\n        TrimmedAmount oldLimit = rateLimitParams.limit;\n        if (oldLimit.isNull()) {\n            rateLimitParams.currentCapacity = limit;\n        } else {\n            TrimmedAmount currentCapacity = _getCurrentCapacity(rateLimitParams);\n            rateLimitParams.currentCapacity =\n                _calculateNewCurrentCapacity(limit, oldLimit, currentCapacity);\n        }\n        rateLimitParams.limit = limit;\n\n        rateLimitParams.lastTxTimestamp = uint64(block.timestamp);\n    }\n\n    function _setOutboundLimit(\n        TrimmedAmount limit\n    ) internal virtual {\n        RateLimitParams storage rateLimitParams = _getOutboundLimitParamsStorage();\n        TrimmedAmount oldLimit = rateLimitParams.limit;\n        uint8 decimals = tokenDecimals();\n        _setLimit(limit, rateLimitParams);\n        emit OutboundTransferLimitUpdated(oldLimit.untrim(decimals), limit.untrim(decimals));\n    }\n\n    function getOutboundLimitParams() public pure virtual returns (RateLimitParams memory) {\n        return _getOutboundLimitParamsStorage();\n    }\n\n    function getCurrentOutboundCapacity() public view virtual returns (uint256) {\n        TrimmedAmount trimmedCapacity = _getCurrentCapacity(getOutboundLimitParams());\n        uint8 decimals = tokenDecimals();\n        return trimmedCapacity.untrim(decimals);\n    }\n\n    function getOutboundQueuedTransfer(\n        uint64 queueSequence\n    ) public view virtual returns (OutboundQueuedTransfer memory) {\n        return _getOutboundQueueStorage()[queueSequence];\n    }\n\n    function _setInboundLimit(TrimmedAmount limit, uint16 chainId_) internal virtual {\n        RateLimitParams storage rateLimitParams = _getInboundLimitParamsStorage()[chainId_];\n        TrimmedAmount oldLimit = rateLimitParams.limit;\n        uint8 decimals = tokenDecimals();\n        _setLimit(limit, rateLimitParams);\n        emit InboundTransferLimitUpdated(\n            chainId_, oldLimit.untrim(decimals), limit.untrim(decimals)\n        );\n    }\n\n    function getInboundLimitParams(\n        uint16 chainId_\n    ) public view virtual returns (RateLimitParams memory) {\n        return _getInboundLimitParamsStorage()[chainId_];\n    }\n\n    function getCurrentInboundCapacity(\n        uint16 chainId_\n    ) public view virtual returns (uint256) {\n        TrimmedAmount trimmedCapacity = _getCurrentCapacity(getInboundLimitParams(chainId_));\n        uint8 decimals = tokenDecimals();\n        return trimmedCapacity.untrim(decimals);\n    }\n\n    function getInboundQueuedTransfer(\n        bytes32 digest\n    ) public view virtual returns (InboundQueuedTransfer memory) {\n        return _getInboundQueueStorage()[digest];\n    }\n\n    /**\n     * @dev Gets the current capacity for a parameterized rate limits struct\n     */\n    function _getCurrentCapacity(\n        RateLimitParams memory rateLimitParams\n    ) internal view returns (TrimmedAmount capacity) {\n        // If the rate limit duration is 0 then the rate limiter is skipped\n        if (rateLimitDuration == 0) {\n            return\n                packTrimmedAmount(type(uint64).max, rateLimitParams.currentCapacity.getDecimals());\n        }\n\n        // The capacity and rate limit are expressed as trimmed amounts, i.e.\n        // 64-bit unsigned integers. The following operations upcast the 64-bit\n        // unsigned integers to 256-bit unsigned integers to avoid overflow.\n        // Specifically, the calculatedCapacity can overflow the u64 max.\n        // For example, if the limit is uint64.max, then the multiplication in calculatedCapacity\n        // will overflow when timePassed is greater than rateLimitDuration.\n        // Operating on uint256 avoids this issue. The overflow is cancelled out by the min operation,\n        // whose second argument is a uint64, so the result can safely be downcast to a uint64.\n        unchecked {\n            uint256 timePassed = block.timestamp - rateLimitParams.lastTxTimestamp;\n            // Multiply (limit * timePassed), then divide by the duration.\n            // Dividing first has terrible numerical stability --\n            // when rateLimitDuration is close to the limit, there is significant rounding error.\n            // We are safe to multiply first, since these numbers are u64 TrimmedAmount types\n            // and we're performing arithmetic on u256 words.\n            uint256 calculatedCapacity = rateLimitParams.currentCapacity.getAmount()\n                + (rateLimitParams.limit.getAmount() * timePassed) / rateLimitDuration;\n\n            uint256 result = min(calculatedCapacity, rateLimitParams.limit.getAmount());\n            return packTrimmedAmount(\n                SafeCast.toUint64(result), rateLimitParams.currentCapacity.getDecimals()\n            );\n        }\n    }\n\n    /**\n     * @dev Updates the current capacity\n     *\n     * @param newLimit The new limit\n     * @param oldLimit The old limit\n     * @param currentCapacity The current capacity\n     */\n    function _calculateNewCurrentCapacity(\n        TrimmedAmount newLimit,\n        TrimmedAmount oldLimit,\n        TrimmedAmount currentCapacity\n    ) internal pure returns (TrimmedAmount newCurrentCapacity) {\n        TrimmedAmount difference;\n\n        if (oldLimit > newLimit) {\n            difference = oldLimit - newLimit;\n            newCurrentCapacity = currentCapacity > difference\n                ? currentCapacity - difference\n                : packTrimmedAmount(0, currentCapacity.getDecimals());\n        } else {\n            difference = newLimit - oldLimit;\n            newCurrentCapacity = currentCapacity + difference;\n        }\n\n        if (newCurrentCapacity > newLimit) {\n            revert CapacityCannotExceedLimit(newCurrentCapacity, newLimit);\n        }\n    }\n\n    function _consumeOutboundAmount(\n        TrimmedAmount amount\n    ) internal {\n        if (rateLimitDuration == 0) return;\n        _consumeRateLimitAmount(\n            amount, _getCurrentCapacity(getOutboundLimitParams()), _getOutboundLimitParamsStorage()\n        );\n    }\n\n    function _backfillOutboundAmount(\n        TrimmedAmount amount\n    ) internal {\n        if (rateLimitDuration == 0) return;\n        _backfillRateLimitAmount(\n            amount, _getCurrentCapacity(getOutboundLimitParams()), _getOutboundLimitParamsStorage()\n        );\n    }\n\n    function _consumeInboundAmount(TrimmedAmount amount, uint16 chainId_) internal {\n        if (rateLimitDuration == 0) return;\n        _consumeRateLimitAmount(\n            amount,\n            _getCurrentCapacity(getInboundLimitParams(chainId_)),\n            _getInboundLimitParamsStorage()[chainId_]\n        );\n    }\n\n    function _backfillInboundAmount(TrimmedAmount amount, uint16 chainId_) internal {\n        if (rateLimitDuration == 0) return;\n        _backfillRateLimitAmount(\n            amount,\n            _getCurrentCapacity(getInboundLimitParams(chainId_)),\n            _getInboundLimitParamsStorage()[chainId_]\n        );\n    }\n\n    function _consumeRateLimitAmount(\n        TrimmedAmount amount,\n        TrimmedAmount capacity,\n        RateLimitParams storage rateLimitParams\n    ) internal {\n        rateLimitParams.lastTxTimestamp = uint64(block.timestamp);\n        rateLimitParams.currentCapacity = capacity - amount;\n    }\n\n    /// @dev Refills the capacity by the given amount.\n    /// This is used to replenish the capacity via backflows.\n    function _backfillRateLimitAmount(\n        TrimmedAmount amount,\n        TrimmedAmount capacity,\n        RateLimitParams storage rateLimitParams\n    ) internal {\n        rateLimitParams.lastTxTimestamp = uint64(block.timestamp);\n        rateLimitParams.currentCapacity = capacity.saturatingAdd(amount).min(rateLimitParams.limit);\n    }\n\n    function _isOutboundAmountRateLimited(\n        TrimmedAmount amount\n    ) internal view returns (bool) {\n        return rateLimitDuration != 0\n            ? _isAmountRateLimited(_getCurrentCapacity(getOutboundLimitParams()), amount)\n            : false;\n    }\n\n    function _isInboundAmountRateLimited(\n        TrimmedAmount amount,\n        uint16 chainId_\n    ) internal view returns (bool) {\n        return rateLimitDuration != 0\n            ? _isAmountRateLimited(_getCurrentCapacity(getInboundLimitParams(chainId_)), amount)\n            : false;\n    }\n\n    function _isAmountRateLimited(\n        TrimmedAmount capacity,\n        TrimmedAmount amount\n    ) internal pure returns (bool) {\n        return capacity < amount;\n    }\n\n    function _enqueueOutboundTransfer(\n        uint64 sequence,\n        TrimmedAmount amount,\n        uint16 recipientChain,\n        bytes32 recipient,\n        bytes32 refundAddress,\n        address senderAddress,\n        bytes memory transceiverInstructions\n    ) internal {\n        _getOutboundQueueStorage()[sequence] = OutboundQueuedTransfer({\n            amount: amount,\n            recipientChain: recipientChain,\n            recipient: recipient,\n            refundAddress: refundAddress,\n            txTimestamp: uint64(block.timestamp),\n            sender: senderAddress,\n            transceiverInstructions: transceiverInstructions\n        });\n\n        emit OutboundTransferQueued(sequence);\n    }\n\n    function _enqueueInboundTransfer(\n        bytes32 digest,\n        TrimmedAmount amount,\n        address recipient\n    ) internal {\n        _getInboundQueueStorage()[digest] = InboundQueuedTransfer({\n            amount: amount,\n            recipient: recipient,\n            txTimestamp: uint64(block.timestamp)\n        });\n\n        emit InboundTransferQueued(digest);\n    }\n\n    function tokenDecimals() public view virtual returns (uint8);\n}\n"},{"file_path":"lib/native-token-transfers/evm/lib/openzeppelin-contracts/contracts/proxy/ERC1967/ERC1967Upgrade.sol","source_code":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0) (proxy/ERC1967/ERC1967Upgrade.sol)\n\npragma solidity ^0.8.2;\n\nimport \"../beacon/IBeacon.sol\";\nimport \"../../interfaces/draft-IERC1822.sol\";\nimport \"../../utils/Address.sol\";\nimport \"../../utils/StorageSlot.sol\";\n\n/**\n * @dev This abstract contract provides getters and event emitting update functions for\n * https://eips.ethereum.org/EIPS/eip-1967[EIP1967] slots.\n *\n * _Available since v4.1._\n *\n * @custom:oz-upgrades-unsafe-allow delegatecall\n */\nabstract contract ERC1967Upgrade {\n    // This is the keccak-256 hash of \"eip1967.proxy.rollback\" subtracted by 1\n    bytes32 private constant _ROLLBACK_SLOT = 0x4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd9143;\n\n    /**\n     * @dev Storage slot with the address of the current implementation.\n     * This is the keccak-256 hash of \"eip1967.proxy.implementation\" subtracted by 1, and is\n     * validated in the constructor.\n     */\n    bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\n\n    /**\n     * @dev Emitted when the implementation is upgraded.\n     */\n    event Upgraded(address indexed implementation);\n\n    /**\n     * @dev Returns the current implementation address.\n     */\n    function _getImplementation() internal view returns (address) {\n        return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value;\n    }\n\n    /**\n     * @dev Stores a new address in the EIP1967 implementation slot.\n     */\n    function _setImplementation(address newImplementation) private {\n        require(Address.isContract(newImplementation), \"ERC1967: new implementation is not a contract\");\n        StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation;\n    }\n\n    /**\n     * @dev Perform implementation upgrade\n     *\n     * Emits an {Upgraded} event.\n     */\n    function _upgradeTo(address newImplementation) internal {\n        _setImplementation(newImplementation);\n        emit Upgraded(newImplementation);\n    }\n\n    /**\n     * @dev Perform implementation upgrade with additional setup call.\n     *\n     * Emits an {Upgraded} event.\n     */\n    function _upgradeToAndCall(\n        address newImplementation,\n        bytes memory data,\n        bool forceCall\n    ) internal {\n        _upgradeTo(newImplementation);\n        if (data.length > 0 || forceCall) {\n            Address.functionDelegateCall(newImplementation, data);\n        }\n    }\n\n    /**\n     * @dev Perform implementation upgrade with security checks for UUPS proxies, and additional setup call.\n     *\n     * Emits an {Upgraded} event.\n     */\n    function _upgradeToAndCallUUPS(\n        address newImplementation,\n        bytes memory data,\n        bool forceCall\n    ) internal {\n        // Upgrades from old implementations will perform a rollback test. This test requires the new\n        // implementation to upgrade back to the old, non-ERC1822 compliant, implementation. Removing\n        // this special case will break upgrade paths from old UUPS implementation to new ones.\n        if (StorageSlot.getBooleanSlot(_ROLLBACK_SLOT).value) {\n            _setImplementation(newImplementation);\n        } else {\n            try IERC1822Proxiable(newImplementation).proxiableUUID() returns (bytes32 slot) {\n                require(slot == _IMPLEMENTATION_SLOT, \"ERC1967Upgrade: unsupported proxiableUUID\");\n            } catch {\n                revert(\"ERC1967Upgrade: new implementation is not UUPS\");\n            }\n            _upgradeToAndCall(newImplementation, data, forceCall);\n        }\n    }\n\n    /**\n     * @dev Storage slot with the admin of the contract.\n     * This is the keccak-256 hash of \"eip1967.proxy.admin\" subtracted by 1, and is\n     * validated in the constructor.\n     */\n    bytes32 internal constant _ADMIN_SLOT = 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103;\n\n    /**\n     * @dev Emitted when the admin account has changed.\n     */\n    event AdminChanged(address previousAdmin, address newAdmin);\n\n    /**\n     * @dev Returns the current admin.\n     */\n    function _getAdmin() internal view returns (address) {\n        return StorageSlot.getAddressSlot(_ADMIN_SLOT).value;\n    }\n\n    /**\n     * @dev Stores a new address in the EIP1967 admin slot.\n     */\n    function _setAdmin(address newAdmin) private {\n        require(newAdmin != address(0), \"ERC1967: new admin is the zero address\");\n        StorageSlot.getAddressSlot(_ADMIN_SLOT).value = newAdmin;\n    }\n\n    /**\n     * @dev Changes the admin of the proxy.\n     *\n     * Emits an {AdminChanged} event.\n     */\n    function _changeAdmin(address newAdmin) internal {\n        emit AdminChanged(_getAdmin(), newAdmin);\n        _setAdmin(newAdmin);\n    }\n\n    /**\n     * @dev The storage slot of the UpgradeableBeacon contract which defines the implementation for this proxy.\n     * This is bytes32(uint256(keccak256('eip1967.proxy.beacon')) - 1)) and is validated in the constructor.\n     */\n    bytes32 internal constant _BEACON_SLOT = 0xa3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6cb3582b35133d50;\n\n    /**\n     * @dev Emitted when the beacon is upgraded.\n     */\n    event BeaconUpgraded(address indexed beacon);\n\n    /**\n     * @dev Returns the current beacon.\n     */\n    function _getBeacon() internal view returns (address) {\n        return StorageSlot.getAddressSlot(_BEACON_SLOT).value;\n    }\n\n    /**\n     * @dev Stores a new beacon in the EIP1967 beacon slot.\n     */\n    function _setBeacon(address newBeacon) private {\n        require(Address.isContract(newBeacon), \"ERC1967: new beacon is not a contract\");\n        require(\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(\n        address newBeacon,\n        bytes memory data,\n        bool forceCall\n    ) internal {\n        _setBeacon(newBeacon);\n        emit BeaconUpgraded(newBeacon);\n        if (data.length > 0 || forceCall) {\n            Address.functionDelegateCall(IBeacon(newBeacon).implementation(), data);\n        }\n    }\n}\n"},{"file_path":"lib/native-token-transfers/evm/src/interfaces/INttToken.sol","source_code":"// SPDX-License-Identifier: Apache 2\npragma solidity >=0.8.8 <0.9.0;\n\ninterface INttToken {\n    /// @notice Error when the caller is not the minter.\n    /// @dev Selector 0x5fb5729e.\n    /// @param caller The caller of the function.\n    error CallerNotMinter(address caller);\n\n    /// @notice Error when the minter is the zero address.\n    /// @dev Selector 0x04a208c7.\n    error InvalidMinterZeroAddress();\n\n    /// @notice Error when insufficient balance to burn the amount.\n    /// @dev Selector 0xcf479181.\n    /// @param balance The balance of the account.\n    /// @param amount The amount to burn.\n    error InsufficientBalance(uint256 balance, uint256 amount);\n\n    /// @notice The minter has been changed.\n    /// @dev Topic0\n    ///      0x0b5e7be615a67a819aff3f47c967d1535cead1b98db60fafdcbf22dcaa8fa5a9.\n    /// @param newMinter The new minter.\n    event NewMinter(address previousMinter, address newMinter);\n\n    // NOTE: the `mint` method is not present in the standard ERC20 interface.\n    function mint(address account, uint256 amount) external;\n\n    // NOTE: the `setMinter` method is not present in the standard ERC20 interface.\n    function setMinter(\n        address newMinter\n    ) external;\n\n    // NOTE: NttTokens in `burn` mode require the `burn` method to be present.\n    //       This method is not present in the standard ERC20 interface, but is\n    //       found in the `ERC20Burnable` interface.\n    function burn(\n        uint256 amount\n    ) external;\n}\n"},{"file_path":"lib/native-token-transfers/evm/src/libraries/TransceiverHelpers.sol","source_code":"// SPDX-License-Identifier: Apache 2\npragma solidity >=0.8.8 <0.9.0;\n\nerror InvalidFork(uint256 evmChainId, uint256 blockChainId);\n\nfunction checkFork(\n    uint256 evmChainId\n) view {\n    if (isFork(evmChainId)) {\n        revert InvalidFork(evmChainId, block.chainid);\n    }\n}\n\nfunction isFork(\n    uint256 evmChainId\n) view returns (bool) {\n    return evmChainId != block.chainid;\n}\n\nfunction min(uint256 a, uint256 b) pure returns (uint256) {\n    return a < b ? a : b;\n}\n\n// @dev Count the number of set bits in a uint64\nfunction countSetBits(\n    uint64 x\n) pure returns (uint8 count) {\n    while (x != 0) {\n        x &= x - 1;\n        count++;\n    }\n\n    return count;\n}\n"},{"file_path":"lib/native-token-transfers/evm/src/libraries/TrimmedAmount.sol","source_code":"// SPDX-License-Identifier: Apache 2\n/// @dev TrimmedAmount is a utility library to handle token amounts with different decimals\npragma solidity >=0.8.8 <0.9.0;\n\nimport \"openzeppelin-contracts/contracts/utils/math/SafeCast.sol\";\n\n/// @dev TrimmedAmount is a bit-packed representation of a token amount and its decimals.\n/// @dev 64 bits: [0 - 64] amount\n/// @dev 8 bits: [64 - 72] decimals\ntype TrimmedAmount is uint72;\n\nusing {gt as >, lt as <, sub as -, add as +, eq as ==, min, unwrap} for TrimmedAmount global;\n\nfunction minUint8(uint8 a, uint8 b) pure returns (uint8) {\n    return a < b ? a : b;\n}\n\n/// @notice Error when the decimals of two TrimmedAmounts are not equal\n/// @dev Selector. b9cdb6c2\n/// @param decimals the decimals of the first TrimmedAmount\n/// @param decimalsOther the decimals of the second TrimmedAmount\nerror NumberOfDecimalsNotEqual(uint8 decimals, uint8 decimalsOther);\n\nuint8 constant TRIMMED_DECIMALS = 8;\n\nfunction unwrap(\n    TrimmedAmount a\n) pure returns (uint72) {\n    return TrimmedAmount.unwrap(a);\n}\n\nfunction packTrimmedAmount(uint64 amt, uint8 decimals) pure returns (TrimmedAmount) {\n    // cast to u72 first to prevent overflow\n    uint72 amount = uint72(amt);\n    uint72 dec = uint72(decimals);\n\n    // shift the amount to the left 8 bits\n    amount <<= 8;\n\n    return TrimmedAmount.wrap(amount | dec);\n}\n\nfunction eq(TrimmedAmount a, TrimmedAmount b) pure returns (bool) {\n    return TrimmedAmountLib.getAmount(a) == TrimmedAmountLib.getAmount(b)\n        && TrimmedAmountLib.getDecimals(a) == TrimmedAmountLib.getDecimals(b);\n}\n\nfunction checkDecimals(TrimmedAmount a, TrimmedAmount b) pure {\n    uint8 aDecimals = TrimmedAmountLib.getDecimals(a);\n    uint8 bDecimals = TrimmedAmountLib.getDecimals(b);\n    if (aDecimals != bDecimals) {\n        revert NumberOfDecimalsNotEqual(aDecimals, bDecimals);\n    }\n}\n\nfunction gt(TrimmedAmount a, TrimmedAmount b) pure returns (bool) {\n    checkDecimals(a, b);\n\n    return TrimmedAmountLib.getAmount(a) > TrimmedAmountLib.getAmount(b);\n}\n\nfunction lt(TrimmedAmount a, TrimmedAmount b) pure returns (bool) {\n    checkDecimals(a, b);\n\n    return TrimmedAmountLib.getAmount(a) < TrimmedAmountLib.getAmount(b);\n}\n\nfunction sub(TrimmedAmount a, TrimmedAmount b) pure returns (TrimmedAmount) {\n    checkDecimals(a, b);\n\n    return packTrimmedAmount(\n        TrimmedAmountLib.getAmount(a) - TrimmedAmountLib.getAmount(b),\n        TrimmedAmountLib.getDecimals(a)\n    );\n}\n\nfunction add(TrimmedAmount a, TrimmedAmount b) pure returns (TrimmedAmount) {\n    checkDecimals(a, b);\n\n    return packTrimmedAmount(\n        TrimmedAmountLib.getAmount(a) + TrimmedAmountLib.getAmount(b),\n        TrimmedAmountLib.getDecimals(b)\n    );\n}\n\nfunction min(TrimmedAmount a, TrimmedAmount b) pure returns (TrimmedAmount) {\n    checkDecimals(a, b);\n\n    return TrimmedAmountLib.getAmount(a) < TrimmedAmountLib.getAmount(b) ? a : b;\n}\n\nlibrary TrimmedAmountLib {\n    /// @notice Error when the amount to be trimmed is greater than u64MAX.\n    /// @dev Selector 0x08083b2a.\n    /// @param amount The amount to be trimmed.\n    error AmountTooLarge(uint256 amount);\n\n    function getAmount(\n        TrimmedAmount a\n    ) internal pure returns (uint64) {\n        // Extract the raw integer value from TrimmedAmount\n        uint72 rawValue = TrimmedAmount.unwrap(a);\n\n        // Right shift to keep only the higher 64 bits\n        uint64 result = uint64(rawValue >> 8);\n        return result;\n    }\n\n    function getDecimals(\n        TrimmedAmount a\n    ) internal pure returns (uint8) {\n        return uint8(TrimmedAmount.unwrap(a) & 0xFF);\n    }\n\n    /// @dev Set the decimals of the TrimmedAmount.\n    ///      This function should only be used for testing purposes, as it\n    ///      should not be necessary to change the decimals of a TrimmedAmount\n    ///      under normal circumstances.\n    function setDecimals(TrimmedAmount a, uint8 decimals) internal pure returns (TrimmedAmount) {\n        return TrimmedAmount.wrap((TrimmedAmount.unwrap(a) & ~uint72(0xFF)) | decimals);\n    }\n\n    function isNull(\n        TrimmedAmount a\n    ) internal pure returns (bool) {\n        return (getAmount(a) == 0 && getDecimals(a) == 0);\n    }\n\n    function saturatingAdd(\n        TrimmedAmount a,\n        TrimmedAmount b\n    ) internal pure returns (TrimmedAmount) {\n        checkDecimals(a, b);\n\n        uint256 saturatedSum;\n        uint64 aAmount = getAmount(a);\n        uint64 bAmount = getAmount(b);\n        unchecked {\n            saturatedSum = uint256(aAmount) + uint256(bAmount);\n            saturatedSum = saturatedSum > type(uint64).max ? type(uint64).max : saturatedSum;\n        }\n\n        return packTrimmedAmount(SafeCast.toUint64(saturatedSum), getDecimals(a));\n    }\n\n    /// @dev scale the amount from original decimals to target decimals (base 10)\n    function scale(\n        uint256 amount,\n        uint8 fromDecimals,\n        uint8 toDecimals\n    ) internal pure returns (uint256) {\n        if (fromDecimals == toDecimals) {\n            return amount;\n        }\n\n        if (fromDecimals > toDecimals) {\n            return amount / (10 ** (fromDecimals - toDecimals));\n        } else {\n            return amount * (10 ** (toDecimals - fromDecimals));\n        }\n    }\n\n    function shift(TrimmedAmount amount, uint8 toDecimals) internal pure returns (TrimmedAmount) {\n        uint8 actualToDecimals = minUint8(TRIMMED_DECIMALS, toDecimals);\n        return packTrimmedAmount(\n            SafeCast.toUint64(scale(getAmount(amount), getDecimals(amount), actualToDecimals)),\n            actualToDecimals\n        );\n    }\n\n    function max(\n        uint8 decimals\n    ) internal pure returns (TrimmedAmount) {\n        uint8 actualDecimals = minUint8(TRIMMED_DECIMALS, decimals);\n        return packTrimmedAmount(type(uint64).max, actualDecimals);\n    }\n\n    /// @dev trim the amount to target decimals.\n    ///      The actual resulting decimals is the minimum of TRIMMED_DECIMALS,\n    ///      fromDecimals, and toDecimals. This ensures that no dust is\n    ///      destroyed on either side of the transfer.\n    /// @param amt the amount to be trimmed\n    /// @param fromDecimals the original decimals of the amount\n    /// @param toDecimals the target decimals of the amount\n    /// @return TrimmedAmount uint72 value type bit-packed with decimals\n    function trim(\n        uint256 amt,\n        uint8 fromDecimals,\n        uint8 toDecimals\n    ) internal pure returns (TrimmedAmount) {\n        uint8 actualToDecimals = minUint8(minUint8(TRIMMED_DECIMALS, fromDecimals), toDecimals);\n        uint256 amountScaled = scale(amt, fromDecimals, actualToDecimals);\n\n        // NOTE: amt after trimming must fit into uint64 (that's the point of\n        // trimming, as Solana only supports uint64 for token amts)\n        return packTrimmedAmount(SafeCast.toUint64(amountScaled), actualToDecimals);\n    }\n\n    function untrim(TrimmedAmount amt, uint8 toDecimals) internal pure returns (uint256) {\n        uint256 deNorm = uint256(getAmount(amt));\n        uint8 fromDecimals = getDecimals(amt);\n        uint256 amountScaled = scale(deNorm, fromDecimals, toDecimals);\n\n        return amountScaled;\n    }\n}\n"},{"file_path":"lib/native-token-transfers/evm/src/libraries/external/Initializable.sol","source_code":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.0.0) (proxy/utils/Initializable.sol)\n\n// COPIED FROM OPENZEPPELIN v5.0.1\n// COPIED TO CHANGE SOLC FROM ^0.8.20 TO ^0.8.19\n\npragma solidity ^0.8.19;\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 Storage of the initializable contract.\n     *\n     * It's implemented on a custom ERC-7201 namespace to reduce the risk of storage collisions\n     * when using with upgradeable contracts.\n     *\n     * @custom:storage-location erc7201:openzeppelin.storage.Initializable\n     */\n    struct InitializableStorage {\n        /**\n         * @dev Indicates that the contract has been initialized.\n         */\n        uint64 _initialized;\n        /**\n         * @dev Indicates that the contract is in the process of being initialized.\n         */\n        bool _initializing;\n    }\n\n    // keccak256(abi.encode(uint256(keccak256(\"openzeppelin.storage.Initializable\")) - 1)) & ~bytes32(uint256(0xff))\n    bytes32 private constant INITIALIZABLE_STORAGE =\n        0xf0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a00;\n\n    /**\n     * @dev The contract is already initialized.\n     */\n    error InvalidInitialization();\n\n    /**\n     * @dev The contract is not initializing.\n     */\n    error NotInitializing();\n\n    /**\n     * @dev Triggered when the contract has been initialized or reinitialized.\n     */\n    event Initialized(uint64 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 in the context of a constructor an `initializer` may be invoked any\n     * number of times. This behavior in the constructor can be useful during testing and is not expected to be used in\n     * production.\n     *\n     * Emits an {Initialized} event.\n     */\n    modifier initializer() {\n        // solhint-disable-next-line var-name-mixedcase\n        InitializableStorage storage $ = _getInitializableStorage();\n\n        // Cache values to avoid duplicated sloads\n        bool isTopLevelCall = !$._initializing;\n        uint64 initialized = $._initialized;\n\n        // Allowed calls:\n        // - initialSetup: the contract is not in the initializing state and no previous version was\n        //                 initialized\n        // - construction: the contract is initialized at version 1 (no reininitialization) and the\n        //                 current contract is just being deployed\n        bool initialSetup = initialized == 0 && isTopLevelCall;\n        bool construction = initialized == 1 && address(this).code.length == 0;\n\n        if (!initialSetup && !construction) {\n            revert InvalidInitialization();\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 2**64 - 1 will prevent any future reinitialization.\n     *\n     * Emits an {Initialized} event.\n     */\n    modifier reinitializer(\n        uint64 version\n    ) {\n        // solhint-disable-next-line var-name-mixedcase\n        InitializableStorage storage $ = _getInitializableStorage();\n\n        if ($._initializing || $._initialized >= version) {\n            revert InvalidInitialization();\n        }\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        _checkInitializing();\n        _;\n    }\n\n    /**\n     * @dev Reverts if the contract is not in an initializing state. See {onlyInitializing}.\n     */\n    function _checkInitializing() internal view virtual {\n        if (!_isInitializing()) {\n            revert NotInitializing();\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        // solhint-disable-next-line var-name-mixedcase\n        InitializableStorage storage $ = _getInitializableStorage();\n\n        if ($._initializing) {\n            revert InvalidInitialization();\n        }\n        if ($._initialized != type(uint64).max) {\n            $._initialized = type(uint64).max;\n            emit Initialized(type(uint64).max);\n        }\n    }\n\n    /**\n     * @dev Returns the highest version that has been initialized. See {reinitializer}.\n     */\n    function _getInitializedVersion() internal view returns (uint64) {\n        return _getInitializableStorage()._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 _getInitializableStorage()._initializing;\n    }\n\n    /**\n     * @dev Returns a pointer to the storage namespace.\n     */\n    // solhint-disable-next-line var-name-mixedcase\n    function _getInitializableStorage() private pure returns (InitializableStorage storage $) {\n        assembly {\n            $.slot := INITIALIZABLE_STORAGE\n        }\n    }\n}\n"},{"file_path":"lib/native-token-transfers/evm/lib/openzeppelin-contracts/contracts/token/ERC20/IERC20.sol","source_code":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC20 standard as defined in the EIP.\n */\ninterface IERC20 {\n    /**\n     * @dev Emitted when `value` tokens are moved from one account (`from`) to\n     * another (`to`).\n     *\n     * Note that `value` may be zero.\n     */\n    event Transfer(address indexed from, address indexed to, uint256 value);\n\n    /**\n     * @dev Emitted when the allowance of a `spender` for an `owner` is set by\n     * a call to {approve}. `value` is the new allowance.\n     */\n    event Approval(address indexed owner, address indexed spender, uint256 value);\n\n    /**\n     * @dev Returns the amount of tokens in existence.\n     */\n    function totalSupply() external view returns (uint256);\n\n    /**\n     * @dev Returns the amount of tokens owned by `account`.\n     */\n    function balanceOf(address account) external view returns (uint256);\n\n    /**\n     * @dev Moves `amount` tokens from the caller's account to `to`.\n     *\n     * Returns a boolean value indicating whether the operation succeeded.\n     *\n     * Emits a {Transfer} event.\n     */\n    function transfer(address to, uint256 amount) external returns (bool);\n\n    /**\n     * @dev Returns the remaining number of tokens that `spender` will be\n     * allowed to spend on behalf of `owner` through {transferFrom}. This is\n     * zero by default.\n     *\n     * This value changes when {approve} or {transferFrom} are called.\n     */\n    function allowance(address owner, address spender) external view returns (uint256);\n\n    /**\n     * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\n     *\n     * Returns a boolean value indicating whether the operation succeeded.\n     *\n     * IMPORTANT: Beware that changing an allowance with this method brings the risk\n     * that someone may use both the old and the new allowance by unfortunate\n     * transaction ordering. One possible solution to mitigate this race\n     * condition is to first reduce the spender's allowance to 0 and set the\n     * desired value afterwards:\n     * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\n     *\n     * Emits an {Approval} event.\n     */\n    function approve(address spender, uint256 amount) external returns (bool);\n\n    /**\n     * @dev Moves `amount` tokens from `from` to `to` using the\n     * allowance mechanism. `amount` is then deducted from the caller's\n     * allowance.\n     *\n     * Returns a boolean value indicating whether the operation succeeded.\n     *\n     * Emits a {Transfer} event.\n     */\n    function transferFrom(\n        address from,\n        address to,\n        uint256 amount\n    ) external returns (bool);\n}\n"},{"file_path":"lib/native-token-transfers/evm/src/interfaces/INttManager.sol","source_code":"// SPDX-License-Identifier: Apache 2\npragma solidity >=0.8.8 <0.9.0;\n\nimport \"../libraries/TrimmedAmount.sol\";\nimport \"../libraries/TransceiverStructs.sol\";\n\nimport \"./IManagerBase.sol\";\n\ninterface INttManager is IManagerBase {\n    /// @dev The peer on another chain.\n    struct NttManagerPeer {\n        bytes32 peerAddress;\n        uint8 tokenDecimals;\n    }\n\n    /// @notice Emitted when a message is sent from the nttManager.\n    /// @dev Topic0\n    ///      0xe54e51e42099622516fa3b48e9733581c9dbdcb771cafb093f745a0532a35982.\n    /// @param recipient The recipient of the message.\n    /// @param refundAddress The address on the destination chain to which the\n    ///                      refund of unused gas will be paid\n    /// @param amount The amount transferred.\n    /// @param fee The amount of ether sent along with the tx to cover the delivery fee.\n    /// @param recipientChain The chain ID of the recipient.\n    /// @param msgSequence The unique sequence ID of the message.\n    event TransferSent(\n        bytes32 indexed recipient,\n        bytes32 indexed refundAddress,\n        uint256 amount,\n        uint256 fee,\n        uint16 recipientChain,\n        uint64 msgSequence\n    );\n\n    /// @notice Emitted when a message is sent from the nttManager.\n    /// @dev Topic0\n    ///      0x3e6ae56314c6da8b461d872f41c6d0bb69317b9d0232805aaccfa45df1a16fa0.\n    /// @param digest The digest of the message.\n    event TransferSent(bytes32 indexed digest);\n\n    /// @notice Emitted when the peer contract is updated.\n    /// @dev Topic0\n    ///      0x1456404e7f41f35c3daac941bb50bad417a66275c3040061b4287d787719599d.\n    /// @param chainId_ The chain ID of the peer contract.\n    /// @param oldPeerContract The old peer contract address.\n    /// @param oldPeerDecimals The old peer contract decimals.\n    /// @param peerContract The new peer contract address.\n    /// @param peerDecimals The new peer contract decimals.\n    event PeerUpdated(\n        uint16 indexed chainId_,\n        bytes32 oldPeerContract,\n        uint8 oldPeerDecimals,\n        bytes32 peerContract,\n        uint8 peerDecimals\n    );\n\n    /// @notice Emitted when a transfer has been redeemed\n    ///         (either minted or unlocked on the recipient chain).\n    /// @dev Topic0\n    ///      0x504e6efe18ab9eed10dc6501a417f5b12a2f7f2b1593aed9b89f9bce3cf29a91.\n    /// @param digest The digest of the message.\n    event TransferRedeemed(bytes32 indexed digest);\n\n    /// @notice Emitted when an outbound transfer has been cancelled\n    /// @dev Topic0\n    ///      0xf80e572ae1b63e2449629b6c7d783add85c36473926f216077f17ee002bcfd07.\n    /// @param sequence The sequence number being cancelled\n    /// @param recipient The canceller and recipient of the funds\n    /// @param amount The amount of the transfer being cancelled\n    event OutboundTransferCancelled(uint256 sequence, address recipient, uint256 amount);\n\n    /// @notice The transfer has some dust.\n    /// @dev Selector 0x71f0634a\n    /// @dev This is a security measure to prevent users from losing funds.\n    ///      This is the result of trimming the amount and then untrimming it.\n    /// @param  amount The amount to transfer.\n    error TransferAmountHasDust(uint256 amount, uint256 dust);\n\n    /// @notice The mode is invalid. It is neither in LOCKING or BURNING mode.\n    /// @dev Selector 0x66001a89\n    /// @param mode The mode.\n    error InvalidMode(uint8 mode);\n\n    /// @notice Error when trying to execute a message on an unintended target chain.\n    /// @dev Selector 0x3dcb204a.\n    /// @param targetChain The target chain.\n    /// @param thisChain The current chain.\n    error InvalidTargetChain(uint16 targetChain, uint16 thisChain);\n\n    /// @notice Error when the transfer amount is zero.\n    /// @dev Selector 0x9993626a.\n    error ZeroAmount();\n\n    /// @notice Error when the recipient is invalid.\n    /// @dev Selector 0x9c8d2cd2.\n    error InvalidRecipient();\n\n    /// @notice Error when the recipient is invalid.\n    /// @dev Selector 0xe2fe2726.\n    error InvalidRefundAddress();\n\n    /// @notice Error when the amount burned is different than the balance difference,\n    ///         since NTT does not support burn fees.\n    /// @dev Selector 0x02156a8f.\n    /// @param burnAmount The amount burned.\n    /// @param balanceDiff The balance after burning.\n    error BurnAmountDifferentThanBalanceDiff(uint256 burnAmount, uint256 balanceDiff);\n\n    /// @notice The caller is not the deployer.\n    error UnexpectedDeployer(address expectedOwner, address owner);\n\n    /// @notice Peer for the chain does not match the configuration.\n    /// @param chainId ChainId of the source chain.\n    /// @param peerAddress Address of the peer nttManager contract.\n    error InvalidPeer(uint16 chainId, bytes32 peerAddress);\n\n    /// @notice Peer chain ID cannot be zero.\n    error InvalidPeerChainIdZero();\n\n    /// @notice Peer cannot be the zero address.\n    error InvalidPeerZeroAddress();\n\n    /// @notice Peer cannot have zero decimals.\n    error InvalidPeerDecimals();\n\n    /// @notice Staticcall reverted\n    /// @dev Selector 0x1222cd83\n    error StaticcallFailed();\n\n    /// @notice Error when someone other than the original sender tries to cancel a queued outbound transfer.\n    /// @dev Selector 0xceb40a85.\n    /// @param canceller The address trying to cancel the transfer.\n    /// @param sender The original sender that initiated the transfer that was queued.\n    error CancellerNotSender(address canceller, address sender);\n\n    /// @notice An unexpected msg.value was passed with the call\n    /// @dev Selector 0xbd28e889.\n    error UnexpectedMsgValue();\n\n    /// @notice Peer cannot be on the same chain\n    /// @dev Selector 0x20371f2a.\n    error InvalidPeerSameChainId();\n\n    /// @notice Feature is not implemented.\n    error NotImplemented();\n\n    /// @notice Transfer a given amount to a recipient on a given chain. This function is called\n    ///         by the user to send the token cross-chain. This function will either lock or burn the\n    ///         sender's tokens. Finally, this function will call into registered `Endpoint` contracts\n    ///         to send a message with the incrementing sequence number and the token transfer payload.\n    /// @param amount The amount to transfer.\n    /// @param recipientChain The Wormhole chain ID for the destination.\n    /// @param recipient The recipient address.\n    /// @return msgId The resulting message ID of the transfer\n    function transfer(\n        uint256 amount,\n        uint16 recipientChain,\n        bytes32 recipient\n    ) external payable returns (uint64 msgId);\n\n    /// @notice Transfer a given amount to a recipient on a given chain. This function is called\n    ///         by the user to send the token cross-chain. This function will either lock or burn the\n    ///         sender's tokens. Finally, this function will call into registered `Endpoint` contracts\n    ///         to send a message with the incrementing sequence number and the token transfer payload.\n    /// @dev Transfers are queued if the outbound limit is hit and must be completed by the client.\n    /// @param amount The amount to transfer.\n    /// @param recipientChain The Wormhole chain ID for the destination.\n    /// @param recipient The recipient address.\n    /// @param refundAddress The address to which a refund for unussed gas is issued on the recipient chain.\n    /// @param shouldQueue Whether the transfer should be queued if the outbound limit is hit.\n    /// @param encodedInstructions Additional instructions to be forwarded to the recipient chain.\n    /// @return msgId The resulting message ID of the transfer\n    function transfer(\n        uint256 amount,\n        uint16 recipientChain,\n        bytes32 recipient,\n        bytes32 refundAddress,\n        bool shouldQueue,\n        bytes memory encodedInstructions\n    ) external payable returns (uint64 msgId);\n\n    /// @notice Complete an outbound transfer that's been queued.\n    /// @dev This method is called by the client to complete an outbound transfer that's been queued.\n    /// @param queueSequence The sequence of the message in the queue.\n    /// @return msgSequence The sequence of the message.\n    function completeOutboundQueuedTransfer(\n        uint64 queueSequence\n    ) external payable returns (uint64 msgSequence);\n\n    /// @notice Cancels an outbound transfer that's been queued.\n    /// @dev This method is called by the client to cancel an outbound transfer that's been queued.\n    /// @param queueSequence The sequence of the message in the queue.\n    function cancelOutboundQueuedTransfer(\n        uint64 queueSequence\n    ) external;\n\n    /// @notice Complete an inbound queued transfer.\n    /// @param digest The digest of the message to complete.\n    function completeInboundQueuedTransfer(\n        bytes32 digest\n    ) external;\n\n    /// @notice Called by an Endpoint contract to deliver a verified attestation.\n    /// @dev This function enforces attestation threshold and replay logic for messages. Once all\n    ///      validations are complete, this function calls `executeMsg` to execute the command specified\n    ///      by the message.\n    /// @param sourceChainId The Wormhole chain id of the sender.\n    /// @param sourceNttManagerAddress The address of the sender's NTT Manager contract.\n    /// @param payload The VAA payload.\n    function attestationReceived(\n        uint16 sourceChainId,\n        bytes32 sourceNttManagerAddress,\n        TransceiverStructs.NttManagerMessage memory payload\n    ) external;\n\n    /// @notice Called after a message has been sufficiently verified to execute\n    ///         the command in the message. This function will decode the payload\n    ///         as an NttManagerMessage to extract the sequence, msgType, and other parameters.\n    /// @dev This function is exposed as a fallback for when an `Transceiver` is deregistered\n    ///      when a message is in flight.\n    /// @param sourceChainId The Wormhole chain id of the sender.\n    /// @param sourceNttManagerAddress The address of the sender's nttManager contract.\n    /// @param message The message to execute.\n    function executeMsg(\n        uint16 sourceChainId,\n        bytes32 sourceNttManagerAddress,\n        TransceiverStructs.NttManagerMessage memory message\n    ) external;\n\n    /// @notice Returns the number of decimals of the token managed by the NttManager.\n    /// @return decimals The number of decimals of the token.\n    function tokenDecimals() external view returns (uint8);\n\n    /// @notice Returns registered peer contract for a given chain.\n    /// @param chainId_ Wormhole chain ID.\n    function getPeer(\n        uint16 chainId_\n    ) external view returns (NttManagerPeer memory);\n\n    /// @notice Sets the corresponding peer.\n    /// @dev The nttManager that executes the message sets the source nttManager as the peer.\n    /// @param peerChainId The Wormhole chain ID of the peer.\n    /// @param peerContract The address of the peer nttManager contract.\n    /// @param decimals The number of decimals of the token on the peer chain.\n    /// @param inboundLimit The inbound rate limit for the peer chain id. This is formatted in the normal\n    ///                     token representation. e.g. a limit of 100 for a token with 6 decimals = 100_000_000\n    function setPeer(\n        uint16 peerChainId,\n        bytes32 peerContract,\n        uint8 decimals,\n        uint256 inboundLimit\n    ) external;\n\n    /// @notice Sets the outbound transfer limit for a given chain.\n    /// @dev This method can only be executed by the `owner`.\n    /// @param limit The new outbound limit. This is formatted in the normal\n    ///              token representation. e.g. a limit of 100 for a token with 6 decimals = 100_000_000\n    function setOutboundLimit(\n        uint256 limit\n    ) external;\n\n    /// @notice Sets the inbound transfer limit for a given chain.\n    /// @dev This method can only be executed by the `owner`.\n    /// @param limit The new limit. This is formatted in the normal\n    ///              token representation. e.g. a limit of 100 for a token with 6 decimals = 100_000_000\n    /// @param chainId The Wormhole chain ID to set the limit for.\n    function setInboundLimit(uint256 limit, uint16 chainId) external;\n}\n"},{"file_path":"lib/native-token-transfers/evm/src/NttManager/ManagerBase.sol","source_code":"// SPDX-License-Identifier: Apache 2\npragma solidity >=0.8.8 <0.9.0;\n\nimport \"wormhole-solidity-sdk/Utils.sol\";\nimport \"wormhole-solidity-sdk/libraries/BytesParsing.sol\";\n\nimport \"../libraries/external/OwnableUpgradeable.sol\";\nimport \"../libraries/external/ReentrancyGuardUpgradeable.sol\";\nimport \"../libraries/TransceiverStructs.sol\";\nimport \"../libraries/TransceiverHelpers.sol\";\nimport \"../libraries/PausableOwnable.sol\";\nimport \"../libraries/Implementation.sol\";\n\nimport \"../interfaces/ITransceiver.sol\";\nimport \"../interfaces/IManagerBase.sol\";\n\nimport \"./TransceiverRegistry.sol\";\n\nabstract contract ManagerBase is\n    IManagerBase,\n    TransceiverRegistry,\n    PausableOwnable,\n    ReentrancyGuardUpgradeable,\n    Implementation\n{\n    // =============== Immutables ============================================================\n\n    /// @dev Address of the token that this NTT Manager is tied to\n    address public immutable token;\n    /// @dev Contract deployer address\n    address immutable deployer;\n    /// @dev Mode of the NTT Manager -- this is either LOCKING (Mode = 0) or BURNING (Mode = 1)\n    /// In LOCKING mode, tokens are locked/unlocked by the NTT Manager contract when sending/redeeming cross-chain transfers.\n    /// In BURNING mode, tokens are burned/minted by the NTT Manager contract when sending/redeeming cross-chain transfers.\n    Mode public immutable mode;\n    /// @dev Wormhole chain ID that the NTT Manager is deployed on.\n    /// This chain ID is formatted Wormhole Chain IDs -- https://docs.wormhole.com/wormhole/reference/constants\n    uint16 public immutable chainId;\n    /// @dev EVM chain ID that the NTT Manager is deployed on.\n    /// This chain ID is formatted based on standardized chain IDs, e.g. Ethereum mainnet is 1, Sepolia is 11155111, etc.\n    uint256 immutable evmChainId;\n\n    // =============== Setup =================================================================\n\n    constructor(address _token, Mode _mode, uint16 _chainId) {\n        token = _token;\n        mode = _mode;\n        chainId = _chainId;\n        evmChainId = block.chainid;\n        // save the deployer (check this on initialization)\n        deployer = msg.sender;\n    }\n\n    function _migrate() internal virtual override {\n        _checkThresholdInvariants();\n        _checkTransceiversInvariants();\n    }\n\n    // =============== Storage ==============================================================\n\n    bytes32 private constant MESSAGE_ATTESTATIONS_SLOT =\n        bytes32(uint256(keccak256(\"ntt.messageAttestations\")) - 1);\n\n    bytes32 private constant MESSAGE_SEQUENCE_SLOT =\n        bytes32(uint256(keccak256(\"ntt.messageSequence\")) - 1);\n\n    bytes32 private constant THRESHOLD_SLOT = bytes32(uint256(keccak256(\"ntt.threshold\")) - 1);\n\n    // =============== Storage Getters/Setters ==============================================\n\n    function _getThresholdStorage() private pure returns (_Threshold storage $) {\n        uint256 slot = uint256(THRESHOLD_SLOT);\n        assembly (\"memory-safe\") {\n            $.slot := slot\n        }\n    }\n\n    function _getMessageAttestationsStorage()\n        internal\n        pure\n        returns (mapping(bytes32 => AttestationInfo) storage $)\n    {\n        uint256 slot = uint256(MESSAGE_ATTESTATIONS_SLOT);\n        assembly (\"memory-safe\") {\n            $.slot := slot\n        }\n    }\n\n    function _getMessageSequenceStorage() internal pure returns (_Sequence storage $) {\n        uint256 slot = uint256(MESSAGE_SEQUENCE_SLOT);\n        assembly (\"memory-safe\") {\n            $.slot := slot\n        }\n    }\n\n    // =============== External Logic =============================================================\n\n    /// @inheritdoc IManagerBase\n    function quoteDeliveryPrice(\n        uint16 recipientChain,\n        bytes memory transceiverInstructions\n    ) public view returns (uint256[] memory, uint256) {\n        address[] memory enabledTransceivers = _getEnabledTransceiversStorage();\n\n        TransceiverStructs.TransceiverInstruction[] memory instructions = TransceiverStructs\n            .parseTransceiverInstructions(transceiverInstructions, enabledTransceivers.length);\n\n        return _quoteDeliveryPrice(recipientChain, instructions, enabledTransceivers);\n    }\n\n    // =============== Internal Logic ===========================================================\n\n    function _quoteDeliveryPrice(\n        uint16 recipientChain,\n        TransceiverStructs.TransceiverInstruction[] memory transceiverInstructions,\n        address[] memory enabledTransceivers\n    ) internal view returns (uint256[] memory, uint256) {\n        uint256 numEnabledTransceivers = enabledTransceivers.length;\n        mapping(address => TransceiverInfo) storage transceiverInfos = _getTransceiverInfosStorage();\n\n        uint256[] memory priceQuotes = new uint256[](numEnabledTransceivers);\n        uint256 totalPriceQuote = 0;\n        for (uint256 i = 0; i < numEnabledTransceivers; i++) {\n            address transceiverAddr = enabledTransceivers[i];\n            uint8 registeredTransceiverIndex = transceiverInfos[transceiverAddr].index;\n            uint256 transceiverPriceQuote = ITransceiver(transceiverAddr).quoteDeliveryPrice(\n                recipientChain, transceiverInstructions[registeredTransceiverIndex]\n            );\n            priceQuotes[i] = transceiverPriceQuote;\n            totalPriceQuote += transceiverPriceQuote;\n        }\n        return (priceQuotes, totalPriceQuote);\n    }\n\n    function _recordTransceiverAttestation(\n        uint16 sourceChainId,\n        TransceiverStructs.NttManagerMessage memory payload\n    ) internal returns (bytes32) {\n        bytes32 nttManagerMessageHash =\n            TransceiverStructs.nttManagerMessageDigest(sourceChainId, payload);\n\n        // set the attested flag for this transceiver.\n        // NOTE: Attestation is idempotent (bitwise or 1), but we revert\n        // anyway to ensure that the client does not continue to initiate calls\n        // to receive the same message through the same transceiver.\n        if (\n            transceiverAttestedToMessage(\n                nttManagerMessageHash, _getTransceiverInfosStorage()[msg.sender].index\n            )\n        ) {\n            revert TransceiverAlreadyAttestedToMessage(nttManagerMessageHash);\n        }\n        _setTransceiverAttestedToMessage(nttManagerMessageHash, msg.sender);\n\n        return nttManagerMessageHash;\n    }\n\n    function _isMessageExecuted(\n        uint16 sourceChainId,\n        bytes32 sourceNttManagerAddress,\n        TransceiverStructs.NttManagerMessage memory message\n    ) internal returns (bytes32, bool) {\n        bytes32 digest = TransceiverStructs.nttManagerMessageDigest(sourceChainId, message);\n\n        if (!isMessageApproved(digest)) {\n            revert MessageNotApproved(digest);\n        }\n\n        bool msgAlreadyExecuted = _replayProtect(digest);\n        if (msgAlreadyExecuted) {\n            // end execution early to mitigate the possibility of race conditions from transceivers\n            // attempting to deliver the same message when (threshold < number of transceiver messages)\n            // notify client (off-chain process) so they don't attempt redundant msg delivery\n            emit MessageAlreadyExecuted(sourceNttManagerAddress, digest);\n            return (bytes32(0), msgAlreadyExecuted);\n        }\n\n        return (digest, msgAlreadyExecuted);\n    }\n\n    function _sendMessageToTransceivers(\n        uint16 recipientChain,\n        bytes32 refundAddress,\n        bytes32 peerAddress,\n        uint256[] memory priceQuotes,\n        TransceiverStructs.TransceiverInstruction[] memory transceiverInstructions,\n        address[] memory enabledTransceivers,\n        bytes memory nttManagerMessage\n    ) internal {\n        uint256 numEnabledTransceivers = enabledTransceivers.length;\n        mapping(address => TransceiverInfo) storage transceiverInfos = _getTransceiverInfosStorage();\n\n        if (peerAddress == bytes32(0)) {\n            revert PeerNotRegistered(recipientChain);\n        }\n\n        // push onto the stack again to avoid stack too deep error\n        bytes32 refundRecipient = refundAddress;\n\n        // call into transceiver contracts to send the message\n        for (uint256 i = 0; i < numEnabledTransceivers; i++) {\n            address transceiverAddr = enabledTransceivers[i];\n\n            // send it to the recipient nttManager based on the chain\n            ITransceiver(transceiverAddr).sendMessage{value: priceQuotes[i]}(\n                recipientChain,\n                transceiverInstructions[transceiverInfos[transceiverAddr].index],\n                nttManagerMessage,\n                peerAddress,\n                refundRecipient\n            );\n        }\n    }\n\n    function _prepareForTransfer(\n        uint16 recipientChain,\n        bytes memory transceiverInstructions\n    )\n        internal\n        returns (\n            address[] memory,\n            TransceiverStructs.TransceiverInstruction[] memory,\n            uint256[] memory,\n            uint256\n        )\n    {\n        // cache enabled transceivers to avoid multiple storage reads\n        address[] memory enabledTransceivers = _getEnabledTransceiversStorage();\n\n        TransceiverStructs.TransceiverInstruction[] memory instructions;\n\n        {\n            uint256 numRegisteredTransceivers = _getRegisteredTransceiversStorage().length;\n            uint256 numEnabledTransceivers = enabledTransceivers.length;\n\n            if (numEnabledTransceivers == 0) {\n                revert NoEnabledTransceivers();\n            }\n\n            instructions = TransceiverStructs.parseTransceiverInstructions(\n                transceiverInstructions, numRegisteredTransceivers\n            );\n        }\n\n        (uint256[] memory priceQuotes, uint256 totalPriceQuote) =\n            _quoteDeliveryPrice(recipientChain, instructions, enabledTransceivers);\n        {\n            // check up front that msg.value will cover the delivery price\n            if (msg.value < totalPriceQuote) {\n                revert DeliveryPaymentTooLow(totalPriceQuote, msg.value);\n            }\n\n            // refund user extra excess value from msg.value\n            uint256 excessValue = msg.value - totalPriceQuote;\n            if (excessValue > 0) {\n                _refundToSender(excessValue);\n            }\n        }\n\n        return (enabledTransceivers, instructions, priceQuotes, totalPriceQuote);\n    }\n\n    function _refundToSender(\n        uint256 refundAmount\n    ) internal {\n        // refund the price quote back to sender\n        (bool refundSuccessful,) = payable(msg.sender).call{value: refundAmount}(\"\");\n\n        // check success\n        if (!refundSuccessful) {\n            revert RefundFailed(refundAmount);\n        }\n    }\n\n    // =============== Public Getters ========================================================\n\n    /// @inheritdoc IManagerBase\n    function getMode() public view returns (uint8) {\n        return uint8(mode);\n    }\n\n    /// @inheritdoc IManagerBase\n    function getThreshold() public view returns (uint8) {\n        return _getThresholdStorage().num;\n    }\n\n    /// @inheritdoc IManagerBase\n    function isMessageApproved(\n        bytes32 digest\n    ) public view returns (bool) {\n        uint8 threshold = getThreshold();\n        return messageAttestations(digest) >= threshold && threshold > 0;\n    }\n\n    /// @inheritdoc IManagerBase\n    function nextMessageSequence() external view returns (uint64) {\n        return _getMessageSequenceStorage().num;\n    }\n\n    /// @inheritdoc IManagerBase\n    function isMessageExecuted(\n        bytes32 digest\n    ) public view returns (bool) {\n        return _getMessageAttestationsStorage()[digest].executed;\n    }\n\n    /// @inheritdoc IManagerBase\n    function transceiverAttestedToMessage(bytes32 digest, uint8 index) public view returns (bool) {\n        return\n            _getMessageAttestationsStorage()[digest].attestedTransceivers & uint64(1 << index) > 0;\n    }\n\n    /// @inheritdoc IManagerBase\n    function messageAttestations(\n        bytes32 digest\n    ) public view returns (uint8 count) {\n        return countSetBits(_getMessageAttestations(digest));\n    }\n\n    // =============== Admin ==============================================================\n\n    /// @inheritdoc IManagerBase\n    function upgrade(\n        address newImplementation\n    ) external onlyOwner {\n        _upgrade(newImplementation);\n    }\n\n    /// @inheritdoc IManagerBase\n    function pause() public onlyOwnerOrPauser {\n        _pause();\n    }\n\n    function unpause() public onlyOwner {\n        _unpause();\n    }\n\n    /// @notice Transfer ownership of the Manager contract and all Transceiver contracts to a new owner.\n    function transferOwnership(\n        address newOwner\n    ) public override onlyOwner {\n        super.transferOwnership(newOwner);\n        // loop through all the registered transceivers and set the new owner of each transceiver to the newOwner\n        address[] storage _registeredTransceivers = _getRegisteredTransceiversStorage();\n        _checkRegisteredTransceiversInvariants();\n\n        for (uint256 i = 0; i < _registeredTransceivers.length; i++) {\n            ITransceiver(_registeredTransceivers[i]).transferTransceiverOwnership(newOwner);\n        }\n    }\n\n    /// @inheritdoc IManagerBase\n    function setTransceiver(\n        address transceiver\n    ) external onlyOwner {\n        _setTransceiver(transceiver);\n\n        _Threshold storage _threshold = _getThresholdStorage();\n        // We do not automatically increase the threshold here.\n        // Automatically increasing the threshold can result in a scenario\n        // where in-flight messages can't be redeemed.\n        // For example: Assume there is 1 Transceiver and the threshold is 1.\n        // If we were to add a new Transceiver, the threshold would increase to 2.\n        // However, all messages that are either in-flight or that are sent on\n        // a source chain that does not yet have 2 Transceivers will only have been\n        // sent from a single transceiver, so they would never be able to get\n        // redeemed.\n        // Instead, we leave it up to the owner to manually update the threshold\n        // after some period of time, ideally once all chains have the new Transceiver\n        // and transfers that were sent via the old configuration are all complete.\n        // However if the threshold is 0 (the initial case) we do increment to 1.\n        if (_threshold.num == 0) {\n            _threshold.num = 1;\n        }\n\n        emit TransceiverAdded(transceiver, _getNumTransceiversStorage().enabled, _threshold.num);\n\n        _checkThresholdInvariants();\n    }\n\n    /// @inheritdoc IManagerBase\n    function removeTransceiver(\n        address transceiver\n    ) external onlyOwner {\n        _removeTransceiver(transceiver);\n\n        _Threshold storage _threshold = _getThresholdStorage();\n        uint8 numEnabledTransceivers = _getNumTransceiversStorage().enabled;\n\n        if (numEnabledTransceivers < _threshold.num) {\n            _threshold.num = numEnabledTransceivers;\n        }\n\n        emit TransceiverRemoved(transceiver, _threshold.num);\n\n        _checkThresholdInvariants();\n    }\n\n    /// @inheritdoc IManagerBase\n    function setThreshold(\n        uint8 threshold\n    ) external onlyOwner {\n        if (threshold == 0) {\n            revert ZeroThreshold();\n        }\n\n        _Threshold storage _threshold = _getThresholdStorage();\n        uint8 oldThreshold = _threshold.num;\n\n        _threshold.num = threshold;\n        _checkThresholdInvariants();\n\n        emit ThresholdChanged(oldThreshold, threshold);\n    }\n\n    // =============== Internal ==============================================================\n\n    function _setTransceiverAttestedToMessage(bytes32 digest, uint8 index) internal {\n        _getMessageAttestationsStorage()[digest].attestedTransceivers |= uint64(1 << index);\n    }\n\n    function _setTransceiverAttestedToMessage(bytes32 digest, address transceiver) internal {\n        _setTransceiverAttestedToMessage(digest, _getTransceiverInfosStorage()[transceiver].index);\n\n        emit MessageAttestedTo(\n            digest, transceiver, _getTransceiverInfosStorage()[transceiver].index\n        );\n    }\n\n    /// @dev Returns the bitmap of attestations from enabled transceivers for a given message.\n    function _getMessageAttestations(\n        bytes32 digest\n    ) internal view returns (uint64) {\n        uint64 enabledTransceiverBitmap = _getEnabledTransceiversBitmap();\n        return\n            _getMessageAttestationsStorage()[digest].attestedTransceivers & enabledTransceiverBitmap;\n    }\n\n    function _getEnabledTransceiverAttestedToMessage(\n        bytes32 digest,\n        uint8 index\n    ) internal view returns (bool) {\n        return _getMessageAttestations(digest) & uint64(1 << index) != 0;\n    }\n\n    // @dev Mark a message as executed.\n    // This function will retuns `true` if the message has already been executed.\n    function _replayProtect(\n        bytes32 digest\n    ) internal returns (bool) {\n        // check if this message has already been executed\n        if (isMessageExecuted(digest)) {\n            return true;\n        }\n\n        // mark this message as executed\n        _getMessageAttestationsStorage()[digest].executed = true;\n\n        return false;\n    }\n\n    function _useMessageSequence() internal returns (uint64 currentSequence) {\n        currentSequence = _getMessageSequenceStorage().num;\n        _getMessageSequenceStorage().num++;\n    }\n\n    /// ============== Invariants =============================================\n\n    /// @dev When we add new immutables, this function should be updated\n    function _checkImmutables() internal view virtual override {\n        assert(this.token() == token);\n        assert(this.mode() == mode);\n        assert(this.chainId() == chainId);\n    }\n\n    function _checkRegisteredTransceiversInvariants() internal view {\n        if (_getRegisteredTransceiversStorage().length != _getNumTransceiversStorage().registered) {\n            revert RetrievedIncorrectRegisteredTransceivers(\n                _getRegisteredTransceiversStorage().length, _getNumTransceiversStorage().registered\n            );\n        }\n    }\n\n    function _checkThresholdInvariants() internal view {\n        uint8 threshold = _getThresholdStorage().num;\n        _NumTransceivers memory numTransceivers = _getNumTransceiversStorage();\n\n        // invariant: threshold <= enabledTransceivers.length\n        if (threshold > numTransceivers.enabled) {\n            revert ThresholdTooHigh(threshold, numTransceivers.enabled);\n        }\n\n        if (numTransceivers.registered > 0) {\n            if (threshold == 0) {\n                revert ZeroThreshold();\n            }\n        }\n    }\n}\n"},{"file_path":"lib/native-token-transfers/evm/src/interfaces/IRateLimiter.sol","source_code":"// SPDX-License-Identifier: Apache 2\npragma solidity >=0.8.8 <0.9.0;\n\nimport \"../libraries/TrimmedAmount.sol\";\nimport \"../libraries/TransceiverStructs.sol\";\n\ninterface IRateLimiter {\n    /// @notice Not enough capacity to send the transfer.\n    /// @dev Selector 0x26fb55dd.\n    /// @param currentCapacity The current capacity.\n    /// @param amount The amount of the transfer.\n    error NotEnoughCapacity(uint256 currentCapacity, uint256 amount);\n\n    /// @notice Outbound transfer is not longer queued.\n    /// @dev Selector 0xbfd5f462.\n    /// @param queueSequence The sequence of the queue.\n    error OutboundQueuedTransferNotFound(uint64 queueSequence);\n\n    /// @notice Cannot complete the outbound transfer, the transfer is still queued.\n    /// @dev Selector 0xc06cf05f.\n    /// @param queueSequence The sequence of the queue.\n    /// @param transferTimestamp The timestamp of when the transfer was queued.\n    error OutboundQueuedTransferStillQueued(uint64 queueSequence, uint256 transferTimestamp);\n\n    /// @notice The inbound transfer is not longer queued.\n    /// @dev Selector 0xc06f2bc0.\n    /// @param digest The digest of the transfer.\n    error InboundQueuedTransferNotFound(bytes32 digest);\n\n    /// @notice The transfer is still queued.\n    /// @dev Selector 0xe5b9ce80.\n    /// @param digest The digest of the transfer.\n    /// @param transferTimestamp The timestamp of the transfer.\n    error InboundQueuedTransferStillQueued(bytes32 digest, uint256 transferTimestamp);\n\n    /// @notice The new capacity cannot exceed the limit.\n    /// @dev Selector 0x0f85ba52.\n    /// @param newCurrentCapacity The new current capacity.\n    /// @param newLimit The new limit.\n    error CapacityCannotExceedLimit(TrimmedAmount newCurrentCapacity, TrimmedAmount newLimit);\n\n    /// @notice If the rate limiting behaviour isn't explicitly defined in the constructor.\n    /// @dev Selector 0xe543ef05.\n    error UndefinedRateLimiting();\n\n    /// @notice Parameters used in determining rate limits and queuing.\n    /// @dev\n    ///    - limit: current rate limit value.\n    ///    - currentCapacity: the current capacity left.\n    ///    - lastTxTimestamp: the timestamp of when the\n    ///                       capacity was previously consumption.\n    struct RateLimitParams {\n        TrimmedAmount limit;\n        TrimmedAmount currentCapacity;\n        uint64 lastTxTimestamp;\n    }\n\n    /// @notice Parameters for an outbound queued transfer.\n    /// @dev\n    ///    - recipient: the recipient of the transfer.\n    ///    - amount: the amount of the transfer, trimmed.\n    ///    - txTimestamp: the timestamp of the transfer.\n    ///    - recipientChain: the chain of the recipient.\n    ///    - sender: the sender of the transfer.\n    ///    - transceiverInstructions: additional instructions to be forwarded to the recipient chain.\n    struct OutboundQueuedTransfer {\n        bytes32 recipient;\n        bytes32 refundAddress;\n        TrimmedAmount amount;\n        uint64 txTimestamp;\n        uint16 recipientChain;\n        address sender;\n        bytes transceiverInstructions;\n    }\n\n    /// @notice Parameters for an inbound queued transfer.\n    /// @dev\n    ///   - amount: the amount of the transfer, trimmed.\n    ///   - txTimestamp: the timestamp of the transfer.\n    ///   - recipient: the recipient of the transfer.\n    struct InboundQueuedTransfer {\n        TrimmedAmount amount;\n        uint64 txTimestamp;\n        address recipient;\n    }\n\n    /// @notice Returns the currently remaining outbound capacity allowed\n    ///         before transfers are queued (if desired)\n    function getCurrentOutboundCapacity() external view returns (uint256);\n\n    /// @notice Returns the queued transfer details for a given sequence in the outbound queue\n    /// @param queueSequence The position of the transfer in the outbound queue\n    function getOutboundQueuedTransfer(\n        uint64 queueSequence\n    ) external view returns (OutboundQueuedTransfer memory);\n\n    /// @notice Returns the currently remaining inbound capacity allowed from a given chain\n    ///         before transfers are queued auutomatically\n    /// @param chainId The Wormhole chain ID of the peer\n    function getCurrentInboundCapacity(\n        uint16 chainId\n    ) external view returns (uint256);\n\n    /// @notice Returns the queued transfer details for a given message digest in the inbound queue\n    /// @param digest The digest of the transfer in the inbound queue\n    function getInboundQueuedTransfer(\n        bytes32 digest\n    ) external view returns (InboundQueuedTransfer memory);\n}\n"},{"file_path":"lib/native-token-transfers/evm/src/interfaces/IManagerBase.sol","source_code":"// SPDX-License-Identifier: Apache 2\npragma solidity >=0.8.8 <0.9.0;\n\nimport \"../libraries/TransceiverStructs.sol\";\n\ninterface IManagerBase {\n    /// @notice The mode is either LOCKING or BURNING. In LOCKING mode, the NttManager locks the\n    ///         tokens of the sender and mints an equivalent amount on the target chain. In BURNING\n    ///         mode, the NttManager burns the tokens of the sender and mints an equivalent amount\n    ///         on the target chain.LOCKING mode preserves the total supply of the tokens.\n    enum Mode {\n        LOCKING,\n        BURNING\n    }\n\n    /// @notice Information about attestations for a given message.\n    /// @dev The fields are as follows:\n    ///      - executed: whether the message has been executed.\n    ///      - attested: bitmap of transceivers that have attested to this message.\n    ///                  (NOTE: might contain disabled transceivers)\n    struct AttestationInfo {\n        bool executed;\n        uint64 attestedTransceivers;\n    }\n\n    struct _Sequence {\n        uint64 num;\n    }\n\n    struct _Threshold {\n        uint8 num;\n    }\n\n    /// @notice Emitted when a message has been attested to.\n    /// @dev Topic0\n    ///      0x35a2101eaac94b493e0dfca061f9a7f087913fde8678e7cde0aca9897edba0e5.\n    /// @param digest The digest of the message.\n    /// @param transceiver The address of the transceiver.\n    /// @param index The index of the transceiver in the bitmap.\n    event MessageAttestedTo(bytes32 digest, address transceiver, uint8 index);\n\n    /// @notice Emmitted when the threshold required transceivers is changed.\n    /// @dev Topic0\n    ///      0x2a855b929b9a53c6fb5b5ed248b27e502b709c088e036a5aa17620c8fc5085a9.\n    /// @param oldThreshold The old threshold.\n    /// @param threshold The new threshold.\n    event ThresholdChanged(uint8 oldThreshold, uint8 threshold);\n\n    /// @notice Emitted when an transceiver is removed from the nttManager.\n    /// @dev Topic0\n    ///      0xf05962b5774c658e85ed80c91a75af9d66d2af2253dda480f90bce78aff5eda5.\n    /// @param transceiver The address of the transceiver.\n    /// @param transceiversNum The current number of transceivers.\n    /// @param threshold The current threshold of transceivers.\n    event TransceiverAdded(address transceiver, uint256 transceiversNum, uint8 threshold);\n\n    /// @notice Emitted when an transceiver is removed from the nttManager.\n    /// @dev Topic0\n    ///     0x697a3853515b88013ad432f29f53d406debc9509ed6d9313dcfe115250fcd18f.\n    /// @param transceiver The address of the transceiver.\n    /// @param threshold The current threshold of transceivers.\n    event TransceiverRemoved(address transceiver, uint8 threshold);\n\n    /// @notice payment for a transfer is too low.\n    /// @param requiredPayment The required payment.\n    /// @param providedPayment The provided payment.\n    error DeliveryPaymentTooLow(uint256 requiredPayment, uint256 providedPayment);\n\n    /// @notice Error when the refund to the sender fails.\n    /// @dev Selector 0x2ca23714.\n    /// @param refundAmount The refund amount.\n    error RefundFailed(uint256 refundAmount);\n\n    /// @notice The number of thresholds should not be zero.\n    error ZeroThreshold();\n\n    error RetrievedIncorrectRegisteredTransceivers(uint256 retrieved, uint256 registered);\n\n    /// @notice The threshold for transceiver attestations is too high.\n    /// @param threshold The threshold.\n    /// @param transceivers The number of transceivers.\n    error ThresholdTooHigh(uint256 threshold, uint256 transceivers);\n\n    /// @notice Error when the tranceiver already attested to the message.\n    ///         To ensure the client does not continue to initiate calls to the attestationReceived function.\n    /// @dev Selector 0x2113894.\n    /// @param nttManagerMessageHash The hash of the message.\n    error TransceiverAlreadyAttestedToMessage(bytes32 nttManagerMessageHash);\n\n    /// @notice Error when the message is not approved.\n    /// @dev Selector 0x451c4fb0.\n    /// @param msgHash The hash of the message.\n    error MessageNotApproved(bytes32 msgHash);\n\n    /// @notice Emitted when a message has already been executed to\n    ///         notify client of against retries.\n    /// @dev Topic0\n    ///      0x4069dff8c9df7e38d2867c0910bd96fd61787695e5380281148c04932d02bef2.\n    /// @param sourceNttManager The address of the source nttManager.\n    /// @param msgHash The keccak-256 hash of the message.\n    event MessageAlreadyExecuted(bytes32 indexed sourceNttManager, bytes32 indexed msgHash);\n\n    /// @notice There are no transceivers enabled with the Manager\n    /// @dev Selector 0x69cf632a\n    error NoEnabledTransceivers();\n\n    /// @notice Error when the manager doesn't have a peer registered for the destination chain\n    /// @dev Selector 0x3af256bc.\n    /// @param chainId The target Wormhole chain id\n    error PeerNotRegistered(uint16 chainId);\n\n    /// @notice Fetch the delivery price for a given recipient chain transfer.\n    /// @param recipientChain The Wormhole chain ID of the transfer destination.\n    /// @param transceiverInstructions The transceiver specific instructions for quoting and sending\n    /// @return - The delivery prices associated with each enabled endpoint and the total price.\n    function quoteDeliveryPrice(\n        uint16 recipientChain,\n        bytes memory transceiverInstructions\n    ) external view returns (uint256[] memory, uint256);\n\n    /// @notice Sets the threshold for the number of attestations required for a message\n    /// to be considered valid.\n    /// @param threshold The new threshold (number of attestations).\n    /// @dev This method can only be executed by the `owner`.\n    function setThreshold(\n        uint8 threshold\n    ) external;\n\n    /// @notice Sets the transceiver for the given chain.\n    /// @param transceiver The address of the transceiver.\n    /// @dev This method can only be executed by the `owner`.\n    function setTransceiver(\n        address transceiver\n    ) external;\n\n    /// @notice Removes the transceiver for the given chain.\n    /// @param transceiver The address of the transceiver.\n    /// @dev This method can only be executed by the `owner`.\n    function removeTransceiver(\n        address transceiver\n    ) external;\n\n    /// @notice Checks if a message has been approved. The message should have at least\n    /// the minimum threshold of attestations from distinct endpoints.\n    /// @param digest The digest of the message.\n    /// @return - Boolean indicating if message has been approved.\n    function isMessageApproved(\n        bytes32 digest\n    ) external view returns (bool);\n\n    /// @notice Checks if a message has been executed.\n    /// @param digest The digest of the message.\n    /// @return - Boolean indicating if message has been executed.\n    function isMessageExecuted(\n        bytes32 digest\n    ) external view returns (bool);\n\n    /// @notice Returns the next message sequence.\n    function nextMessageSequence() external view returns (uint64);\n\n    /// @notice Upgrades to a new manager implementation.\n    /// @dev This is upgraded via a proxy, and can only be executed\n    /// by the `owner`.\n    /// @param newImplementation The address of the new implementation.\n    function upgrade(\n        address newImplementation\n    ) external;\n\n    /// @notice Pauses the manager.\n    function pause() external;\n\n    /// @notice Returns the mode (locking or burning) of the NttManager.\n    /// @return mode A uint8 corresponding to the mode\n    function getMode() external view returns (uint8);\n\n    /// @notice Returns the number of Transceivers that must attest to a msgId for\n    /// it to be considered valid and acted upon.\n    function getThreshold() external view returns (uint8);\n\n    /// @notice Returns a boolean indicating if the transceiver has attested to the message.\n    /// @param digest The digest of the message.\n    /// @param index The index of the transceiver\n    /// @return - Boolean indicating whether the transceiver at index `index` attested to a message digest\n    function transceiverAttestedToMessage(\n        bytes32 digest,\n        uint8 index\n    ) external view returns (bool);\n\n    /// @notice Returns the number of attestations for a given message.\n    /// @param digest The digest of the message.\n    /// @return count The number of attestations received for the given message digest\n    function messageAttestations(\n        bytes32 digest\n    ) external view returns (uint8 count);\n\n    /// @notice Returns of the address of the token managed by this contract.\n    function token() external view returns (address);\n\n    /// @notice Returns the chain ID.\n    function chainId() external view returns (uint16);\n}\n"}],"certified":false,"conflicting_implementations":null,"abi":[{"inputs":[{"internalType":"address","name":"_token","type":"address"},{"internalType":"enum IManagerBase.Mode","name":"_mode","type":"uint8"},{"internalType":"uint16","name":"_chainId","type":"uint16"},{"internalType":"uint64","name":"_rateLimitDuration","type":"uint64"},{"internalType":"bool","name":"_skipRateLimiting","type":"bool"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[{"internalType":"uint256","name":"burnAmount","type":"uint256"},{"internalType":"uint256","name":"balanceDiff","type":"uint256"}],"name":"BurnAmountDifferentThanBalanceDiff","type":"error"},{"inputs":[{"internalType":"address","name":"caller","type":"address"}],"name":"CallerNotTransceiver","type":"error"},{"inputs":[{"internalType":"address","name":"canceller","type":"address"},{"internalType":"address","name":"sender","type":"address"}],"name":"CancellerNotSender","type":"error"},{"inputs":[{"internalType":"TrimmedAmount","name":"newCurrentCapacity","type":"uint72"},{"internalType":"TrimmedAmount","name":"newLimit","type":"uint72"}],"name":"CapacityCannotExceedLimit","type":"error"},{"inputs":[{"internalType":"uint256","name":"requiredPayment","type":"uint256"},{"internalType":"uint256","name":"providedPayment","type":"uint256"}],"name":"DeliveryPaymentTooLow","type":"error"},{"inputs":[{"internalType":"address","name":"transceiver","type":"address"}],"name":"DisabledTransceiver","type":"error"},{"inputs":[{"internalType":"bytes32","name":"digest","type":"bytes32"}],"name":"InboundQueuedTransferNotFound","type":"error"},{"inputs":[{"internalType":"bytes32","name":"digest","type":"bytes32"},{"internalType":"uint256","name":"transferTimestamp","type":"uint256"}],"name":"InboundQueuedTransferStillQueued","type":"error"},{"inputs":[{"internalType":"uint256","name":"evmChainId","type":"uint256"},{"internalType":"uint256","name":"blockChainId","type":"uint256"}],"name":"InvalidFork","type":"error"},{"inputs":[],"name":"InvalidInitialization","type":"error"},{"inputs":[{"internalType":"uint8","name":"mode","type":"uint8"}],"name":"InvalidMode","type":"error"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"InvalidPauser","type":"error"},{"inputs":[{"internalType":"uint16","name":"chainId","type":"uint16"},{"internalType":"bytes32","name":"peerAddress","type":"bytes32"}],"name":"InvalidPeer","type":"error"},{"inputs":[],"name":"InvalidPeerChainIdZero","type":"error"},{"inputs":[],"name":"InvalidPeerDecimals","type":"error"},{"inputs":[],"name":"InvalidPeerSameChainId","type":"error"},{"inputs":[],"name":"InvalidPeerZeroAddress","type":"error"},{"inputs":[],"name":"InvalidRecipient","type":"error"},{"inputs":[],"name":"InvalidRefundAddress","type":"error"},{"inputs":[{"internalType":"uint16","name":"targetChain","type":"uint16"},{"internalType":"uint16","name":"thisChain","type":"uint16"}],"name":"InvalidTargetChain","type":"error"},{"inputs":[],"name":"InvalidTransceiverZeroAddress","type":"error"},{"inputs":[{"internalType":"bytes32","name":"msgHash","type":"bytes32"}],"name":"MessageNotApproved","type":"error"},{"inputs":[],"name":"NoEnabledTransceivers","type":"error"},{"inputs":[{"internalType":"address","name":"transceiver","type":"address"}],"name":"NonRegisteredTransceiver","type":"error"},{"inputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"name":"NotAnEvmAddress","type":"error"},{"inputs":[{"internalType":"uint256","name":"currentCapacity","type":"uint256"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"NotEnoughCapacity","type":"error"},{"inputs":[],"name":"NotImplemented","type":"error"},{"inputs":[],"name":"NotInitializing","type":"error"},{"inputs":[],"name":"NotMigrating","type":"error"},{"inputs":[{"internalType":"uint8","name":"decimals","type":"uint8"},{"internalType":"uint8","name":"decimalsOther","type":"uint8"}],"name":"NumberOfDecimalsNotEqual","type":"error"},{"inputs":[],"name":"OnlyDelegateCall","type":"error"},{"inputs":[{"internalType":"uint64","name":"queueSequence","type":"uint64"}],"name":"OutboundQueuedTransferNotFound","type":"error"},{"inputs":[{"internalType":"uint64","name":"queueSequence","type":"uint64"},{"internalType":"uint256","name":"transferTimestamp","type":"uint256"}],"name":"OutboundQueuedTransferStillQueued","type":"error"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"OwnableInvalidOwner","type":"error"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"OwnableUnauthorizedAccount","type":"error"},{"inputs":[{"internalType":"uint16","name":"chainId","type":"uint16"}],"name":"PeerNotRegistered","type":"error"},{"inputs":[],"name":"ReentrancyGuardReentrantCall","type":"error"},{"inputs":[{"internalType":"uint256","name":"refundAmount","type":"uint256"}],"name":"RefundFailed","type":"error"},{"inputs":[],"name":"RequireContractIsNotPaused","type":"error"},{"inputs":[],"name":"RequireContractIsPaused","type":"error"},{"inputs":[{"internalType":"uint256","name":"retrieved","type":"uint256"},{"internalType":"uint256","name":"registered","type":"uint256"}],"name":"RetrievedIncorrectRegisteredTransceivers","type":"error"},{"inputs":[],"name":"StaticcallFailed","type":"error"},{"inputs":[{"internalType":"uint256","name":"threshold","type":"uint256"},{"internalType":"uint256","name":"transceivers","type":"uint256"}],"name":"ThresholdTooHigh","type":"error"},{"inputs":[],"name":"TooManyTransceivers","type":"error"},{"inputs":[{"internalType":"bytes32","name":"nttManagerMessageHash","type":"bytes32"}],"name":"TransceiverAlreadyAttestedToMessage","type":"error"},{"inputs":[{"internalType":"address","name":"transceiver","type":"address"}],"name":"TransceiverAlreadyEnabled","type":"error"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256","name":"dust","type":"uint256"}],"name":"TransferAmountHasDust","type":"error"},{"inputs":[],"name":"UndefinedRateLimiting","type":"error"},{"inputs":[{"internalType":"address","name":"expectedOwner","type":"address"},{"internalType":"address","name":"owner","type":"address"}],"name":"UnexpectedDeployer","type":"error"},{"inputs":[],"name":"UnexpectedMsgValue","type":"error"},{"inputs":[],"name":"ZeroAmount","type":"error"},{"inputs":[],"name":"ZeroThreshold","type":"error"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"previousAdmin","type":"address"},{"indexed":false,"internalType":"address","name":"newAdmin","type":"address"}],"name":"AdminChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"beacon","type":"address"}],"name":"BeaconUpgraded","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint16","name":"chainId","type":"uint16"},{"indexed":false,"internalType":"uint256","name":"oldLimit","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"newLimit","type":"uint256"}],"name":"InboundTransferLimitUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bytes32","name":"digest","type":"bytes32"}],"name":"InboundTransferQueued","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint64","name":"version","type":"uint64"}],"name":"Initialized","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"sourceNttManager","type":"bytes32"},{"indexed":true,"internalType":"bytes32","name":"msgHash","type":"bytes32"}],"name":"MessageAlreadyExecuted","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bytes32","name":"digest","type":"bytes32"},{"indexed":false,"internalType":"address","name":"transceiver","type":"address"},{"indexed":false,"internalType":"uint8","name":"index","type":"uint8"}],"name":"MessageAttestedTo","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bool","name":"notPaused","type":"bool"}],"name":"NotPaused","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"sequence","type":"uint256"},{"indexed":false,"internalType":"address","name":"recipient","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"OutboundTransferCancelled","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"oldLimit","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"newLimit","type":"uint256"}],"name":"OutboundTransferLimitUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint64","name":"queueSequence","type":"uint64"}],"name":"OutboundTransferQueued","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"sender","type":"address"},{"indexed":false,"internalType":"uint64","name":"sequence","type":"uint64"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"currentCapacity","type":"uint256"}],"name":"OutboundTransferRateLimited","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bool","name":"paused","type":"bool"}],"name":"Paused","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"oldPauser","type":"address"},{"indexed":true,"internalType":"address","name":"newPauser","type":"address"}],"name":"PauserTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint16","name":"chainId_","type":"uint16"},{"indexed":false,"internalType":"bytes32","name":"oldPeerContract","type":"bytes32"},{"indexed":false,"internalType":"uint8","name":"oldPeerDecimals","type":"uint8"},{"indexed":false,"internalType":"bytes32","name":"peerContract","type":"bytes32"},{"indexed":false,"internalType":"uint8","name":"peerDecimals","type":"uint8"}],"name":"PeerUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint8","name":"oldThreshold","type":"uint8"},{"indexed":false,"internalType":"uint8","name":"threshold","type":"uint8"}],"name":"ThresholdChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"transceiver","type":"address"},{"indexed":false,"internalType":"uint256","name":"transceiversNum","type":"uint256"},{"indexed":false,"internalType":"uint8","name":"threshold","type":"uint8"}],"name":"TransceiverAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"transceiver","type":"address"},{"indexed":false,"internalType":"uint8","name":"threshold","type":"uint8"}],"name":"TransceiverRemoved","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"digest","type":"bytes32"}],"name":"TransferRedeemed","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"recipient","type":"bytes32"},{"indexed":true,"internalType":"bytes32","name":"refundAddress","type":"bytes32"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"fee","type":"uint256"},{"indexed":false,"internalType":"uint16","name":"recipientChain","type":"uint16"},{"indexed":false,"internalType":"uint64","name":"msgSequence","type":"uint64"}],"name":"TransferSent","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"digest","type":"bytes32"}],"name":"TransferSent","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"implementation","type":"address"}],"name":"Upgraded","type":"event"},{"inputs":[],"name":"NTT_MANAGER_VERSION","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint16","name":"sourceChainId","type":"uint16"},{"internalType":"bytes32","name":"sourceNttManagerAddress","type":"bytes32"},{"components":[{"internalType":"bytes32","name":"id","type":"bytes32"},{"internalType":"bytes32","name":"sender","type":"bytes32"},{"internalType":"bytes","name":"payload","type":"bytes"}],"internalType":"struct TransceiverStructs.NttManagerMessage","name":"payload","type":"tuple"}],"name":"attestationReceived","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint64","name":"messageSequence","type":"uint64"}],"name":"cancelOutboundQueuedTransfer","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"chainId","outputs":[{"internalType":"uint16","name":"","type":"uint16"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"digest","type":"bytes32"}],"name":"completeInboundQueuedTransfer","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint64","name":"messageSequence","type":"uint64"}],"name":"completeOutboundQueuedTransfer","outputs":[{"internalType":"uint64","name":"","type":"uint64"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint16","name":"sourceChainId","type":"uint16"},{"internalType":"bytes32","name":"sourceNttManagerAddress","type":"bytes32"},{"components":[{"internalType":"bytes32","name":"id","type":"bytes32"},{"internalType":"bytes32","name":"sender","type":"bytes32"},{"internalType":"bytes","name":"payload","type":"bytes"}],"internalType":"struct TransceiverStructs.NttManagerMessage","name":"message","type":"tuple"}],"name":"executeMsg","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint16","name":"chainId_","type":"uint16"}],"name":"getCurrentInboundCapacity","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getCurrentOutboundCapacity","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint16","name":"chainId_","type":"uint16"}],"name":"getInboundLimitParams","outputs":[{"components":[{"internalType":"TrimmedAmount","name":"limit","type":"uint72"},{"internalType":"TrimmedAmount","name":"currentCapacity","type":"uint72"},{"internalType":"uint64","name":"lastTxTimestamp","type":"uint64"}],"internalType":"struct IRateLimiter.RateLimitParams","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"digest","type":"bytes32"}],"name":"getInboundQueuedTransfer","outputs":[{"components":[{"internalType":"TrimmedAmount","name":"amount","type":"uint72"},{"internalType":"uint64","name":"txTimestamp","type":"uint64"},{"internalType":"address","name":"recipient","type":"address"}],"internalType":"struct IRateLimiter.InboundQueuedTransfer","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getMigratesImmutables","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getMode","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getOutboundLimitParams","outputs":[{"components":[{"internalType":"TrimmedAmount","name":"limit","type":"uint72"},{"internalType":"TrimmedAmount","name":"currentCapacity","type":"uint72"},{"internalType":"uint64","name":"lastTxTimestamp","type":"uint64"}],"internalType":"struct IRateLimiter.RateLimitParams","name":"","type":"tuple"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"uint64","name":"queueSequence","type":"uint64"}],"name":"getOutboundQueuedTransfer","outputs":[{"components":[{"internalType":"bytes32","name":"recipient","type":"bytes32"},{"internalType":"bytes32","name":"refundAddress","type":"bytes32"},{"internalType":"TrimmedAmount","name":"amount","type":"uint72"},{"internalType":"uint64","name":"txTimestamp","type":"uint64"},{"internalType":"uint16","name":"recipientChain","type":"uint16"},{"internalType":"address","name":"sender","type":"address"},{"internalType":"bytes","name":"transceiverInstructions","type":"bytes"}],"internalType":"struct IRateLimiter.OutboundQueuedTransfer","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint16","name":"chainId_","type":"uint16"}],"name":"getPeer","outputs":[{"components":[{"internalType":"bytes32","name":"peerAddress","type":"bytes32"},{"internalType":"uint8","name":"tokenDecimals","type":"uint8"}],"internalType":"struct INttManager.NttManagerPeer","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getThreshold","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getTransceiverInfo","outputs":[{"components":[{"internalType":"bool","name":"registered","type":"bool"},{"internalType":"bool","name":"enabled","type":"bool"},{"internalType":"uint8","name":"index","type":"uint8"}],"internalType":"struct TransceiverRegistry.TransceiverInfo[]","name":"","type":"tuple[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getTransceivers","outputs":[{"internalType":"address[]","name":"result","type":"address[]"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"initialize","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"digest","type":"bytes32"}],"name":"isMessageApproved","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"digest","type":"bytes32"}],"name":"isMessageExecuted","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"isPaused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"digest","type":"bytes32"}],"name":"messageAttestations","outputs":[{"internalType":"uint8","name":"count","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"migrate","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"mode","outputs":[{"internalType":"enum IManagerBase.Mode","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"nextMessageSequence","outputs":[{"internalType":"uint64","name":"","type":"uint64"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"pauser","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint16","name":"recipientChain","type":"uint16"},{"internalType":"bytes","name":"transceiverInstructions","type":"bytes"}],"name":"quoteDeliveryPrice","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"},{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"rateLimitDuration","outputs":[{"internalType":"uint64","name":"","type":"uint64"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"transceiver","type":"address"}],"name":"removeTransceiver","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"limit","type":"uint256"},{"internalType":"uint16","name":"chainId_","type":"uint16"}],"name":"setInboundLimit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"limit","type":"uint256"}],"name":"setOutboundLimit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint16","name":"peerChainId","type":"uint16"},{"internalType":"bytes32","name":"peerContract","type":"bytes32"},{"internalType":"uint8","name":"decimals","type":"uint8"},{"internalType":"uint256","name":"inboundLimit","type":"uint256"}],"name":"setPeer","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint8","name":"threshold","type":"uint8"}],"name":"setThreshold","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"transceiver","type":"address"}],"name":"setTransceiver","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"token","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"tokenDecimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"digest","type":"bytes32"},{"internalType":"uint8","name":"index","type":"uint8"}],"name":"transceiverAttestedToMessage","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint16","name":"recipientChain","type":"uint16"},{"internalType":"bytes32","name":"recipient","type":"bytes32"}],"name":"transfer","outputs":[{"internalType":"uint64","name":"","type":"uint64"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint16","name":"recipientChain","type":"uint16"},{"internalType":"bytes32","name":"recipient","type":"bytes32"},{"internalType":"bytes32","name":"refundAddress","type":"bytes32"},{"internalType":"bool","name":"shouldQueue","type":"bool"},{"internalType":"bytes","name":"transceiverInstructions","type":"bytes"}],"name":"transfer","outputs":[{"internalType":"uint64","name":"","type":"uint64"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newPauser","type":"address"}],"name":"transferPauserCapability","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"unpause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newImplementation","type":"address"}],"name":"upgrade","outputs":[],"stateMutability":"nonpayable","type":"function"}],"is_changed_bytecode":false,"is_partially_verified":true,"constructor_args":"0000000000000000000000008d58c0c60b8d6b88fa98b291a646db34d0f982580000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000001e00000000000000000000000000000000000000000000000000000000000151800000000000000000000000000000000000000000000000000000000000000000"}