creation_sourcecode: {{
    "language": "Solidity",
    "sources": {
      "contracts/BL/messaging/BLCrossDomainMessenger.sol": {
        "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.9;\n\n/* Library Imports */\nimport { AddressAliasHelper } from \"../../standards/AddressAliasHelper.sol\";\nimport { Lib_AddressResolver } from \"../../libraries/resolver/Lib_AddressResolver.sol\";\nimport { Lib_NVMCodec } from \"../../libraries/codec/Lib_NVMCodec.sol\";\nimport { Lib_AddressManager } from \"../../libraries/resolver/Lib_AddressManager.sol\";\nimport { Lib_SecureMerkleTrie } from \"../../libraries/trie/Lib_SecureMerkleTrie.sol\";\nimport { Lib_DefaultValues } from \"../../libraries/constants/Lib_DefaultValues.sol\";\nimport { Lib_PredeployAddresses } from \"../../libraries/constants/Lib_PredeployAddresses.sol\";\nimport { Lib_CrossDomainUtils } from \"../../libraries/bridge/Lib_CrossDomainUtils.sol\";\nimport { Lib_Receipt } from \"../../libraries/codec/Lib_Receipt.sol\";\n\n/* Interface Imports */\nimport { IBLCrossDomainMessenger } from \"./IBLCrossDomainMessenger.sol\";\nimport { IMessageQueue } from \"../rollup/IMessageQueue.sol\";\nimport { IFaultProofTimer } from \"../rollup/IFaultProofTimer.sol\";\n\n/* External Imports */\nimport {\n    OwnableUpgradeable\n} from \"@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol\";\nimport {\n    PausableUpgradeable\n} from \"@openzeppelin/contracts-upgradeable/security/PausableUpgradeable.sol\";\nimport {\n    ReentrancyGuardUpgradeable\n} from \"@openzeppelin/contracts-upgradeable/security/ReentrancyGuardUpgradeable.sol\";\n\n/**\n * @title BLCrossDomainMessenger\n * @dev The BL Cross Domain Messenger contract sends messages from BL to SL, and relays messages\n * from SL onto BL. In the event that a message sent from BL to SL is rejected for exceeding the SL\n * epoch gas limit, it can be resubmitted via this contract's replay function.\n *\n */\ncontract BLCrossDomainMessenger is\n    IBLCrossDomainMessenger,\n    Lib_AddressResolver,\n    OwnableUpgradeable,\n    PausableUpgradeable,\n    ReentrancyGuardUpgradeable\n{\n    /**********\n     * Events *\n     **********/\n\n    event MessageBlocked(bytes32 indexed _xDomainCalldataHash);\n\n    event MessageAllowed(bytes32 indexed _xDomainCalldataHash);\n\n    // solhint-disable-next-line max-line-length\n    // event SentMessage(address _target, address sender, bytes memory _message, uint40 nonce, uint32 _gasLimit)\n\n    /**********\n     * Errors *\n     **********/\n\n    error StateRootMismatch(bytes32 receiptStateRoot, bytes32 proofStateRoot);\n    error OperatorHashMismatch(bytes32 receiptTransactionHash, bytes32 localTransactionHash);\n    error OperatorAddressMismatch(\n        address resolvedOperatorAddress,\n        address recoveredOperatorAddress\n    );\n    error FaultProofWindowViolation(uint256 windowExpiryTimestamp, uint256 blockTimeStamp);\n    error StateValueMissing(bytes key, bytes proof, bytes32 root);\n    error StorageProofInvalid(bytes key, bytes value, bytes proof, bytes32 root);\n\n    /**********************\n     * Contract Variables *\n     **********************/\n\n    mapping(bytes32 => bool) public blockedMessages;\n    mapping(bytes32 => bool) public relayedMessages;\n    mapping(bytes32 => bool) public successfulMessages;\n\n    address internal xDomainMsgSender = Lib_DefaultValues.DEFAULT_XDOMAIN_SENDER;\n\n    /***************\n     * Constructor *\n     ***************/\n\n    /**\n     * This contract is intended to be behind a delegate proxy.\n     * We pass the zero address to the address resolver just to satisfy the constructor.\n     * We still need to set this value in initialize().\n     */\n    constructor() Lib_AddressResolver(address(0)) {}\n\n    /********************\n     * Public Functions *\n     ********************/\n\n    /**\n     * @param _libAddressManager Address of the Address Manager.\n     */\n    // slither-disable-next-line external-function\n    function initialize(address _libAddressManager) public initializer {\n        require(\n            address(libAddressManager) == address(0),\n            \"BLCrossDomainMessenger already intialized.\"\n        );\n        libAddressManager = Lib_AddressManager(_libAddressManager);\n        xDomainMsgSender = Lib_DefaultValues.DEFAULT_XDOMAIN_SENDER;\n\n        // Initialize upgradable OZ contracts\n        __Context_init_unchained();\n        // Context is a dependency for both Ownable and Pausable\n        __Ownable_init_unchained();\n        __Pausable_init_unchained();\n        __ReentrancyGuard_init_unchained();\n    }\n\n    /**\n     * Pause relaying.\n     */\n    function pause() external onlyOwner {\n        _pause();\n    }\n\n    /**\n     * Block a message.\n     * @param _xDomainCalldataHash Hash of the message to block.\n     */\n    function blockMessage(bytes32 _xDomainCalldataHash) external onlyOwner {\n        blockedMessages[_xDomainCalldataHash] = true;\n        emit MessageBlocked(_xDomainCalldataHash);\n    }\n\n    /**\n     * Allow a message.\n     * @param _xDomainCalldataHash Hash of the message to block.\n     */\n    function allowMessage(bytes32 _xDomainCalldataHash) external onlyOwner {\n        blockedMessages[_xDomainCalldataHash] = false;\n        emit MessageAllowed(_xDomainCalldataHash);\n    }\n\n    // slither-disable-next-line external-function\n    function xDomainMessageSender() public view returns (address) {\n        require(\n            xDomainMsgSender != Lib_DefaultValues.DEFAULT_XDOMAIN_SENDER,\n            \"xDomainMessageSender is not set\"\n        );\n        return xDomainMsgSender;\n    }\n\n    /**\n     * Sends a cross domain message to the target messenger.\n     * @param _target Target contract address.\n     * @param _message Message to send to the target.\n     * @param _gasLimit Gas limit for the provided message.\n     */\n    // slither-disable-next-line external-function\n    function sendMessage(\n        address _target,\n        bytes memory _message,\n        uint32 _gasLimit\n    ) public {\n        address messageQueue = resolve(\"MessageQueue\");\n        // Use the MQ queue length as nonce\n        uint40 nonce = IMessageQueue(messageQueue).getQueueLength();\n\n        bytes memory xDomainCalldata = Lib_CrossDomainUtils.encodeXDomainCalldata(\n            _target,\n            msg.sender,\n            _message,\n            nonce\n        );\n\n        // slither-disable-next-line reentrancy-events\n        _sendXDomainMessage(messageQueue, xDomainCalldata, _gasLimit);\n\n        // slither-disable-next-line reentrancy-events\n        emit SentMessage(_target, msg.sender, _message, nonce, _gasLimit);\n    }\n\n    /**\n     * Relays a cross domain message to a contract.\n     * @inheritdoc IBLCrossDomainMessenger\n     */\n    // slither-disable-next-line external-function\n    function relayMessage(\n        address _target,\n        address _sender,\n        bytes memory _message,\n        uint256 _messageNonce,\n        Lib_NVMCodec.Transaction memory _transaction,\n        Lib_NVMCodec.Receipt memory _receipt,\n        SLMessageInclusionProof memory _proof\n    ) public nonReentrant whenNotPaused {\n        bytes memory xDomainCalldata = Lib_CrossDomainUtils.encodeXDomainCalldata(\n            _target,\n            _sender,\n            _message,\n            _messageNonce\n        );\n\n        require(\n            _target != resolve(\"MessageQueue\"),\n            \"Cannot send SL->BL messages to BL system contracts.\"\n        );\n\n        require(_verifyXDomainMessage(xDomainCalldata, _transaction, _receipt, _proof));\n\n        bytes32 xDomainCalldataHash = keccak256(xDomainCalldata);\n\n        require(\n            successfulMessages[xDomainCalldataHash] == false,\n            \"Provided message has already been received.\"\n        );\n\n        require(\n            blockedMessages[xDomainCalldataHash] == false,\n            \"Provided message has been blocked.\"\n        );\n\n        xDomainMsgSender = _sender;\n        // slither-disable-next-line reentrancy-no-eth, reentrancy-events, reentrancy-benign\n        (bool success, ) = _target.call(_message);\n        // slither-disable-next-line reentrancy-benign\n        xDomainMsgSender = Lib_DefaultValues.DEFAULT_XDOMAIN_SENDER;\n\n        // Mark the message as received if the call was successful. Ensures that a message can be\n        // relayed multiple times in the case that the call reverted.\n        if (success == true) {\n            // slither-disable-next-line reentrancy-no-eth\n            successfulMessages[xDomainCalldataHash] = true;\n            // slither-disable-next-line reentrancy-events\n            emit RelayedMessage(xDomainCalldataHash);\n        } else {\n            // slither-disable-next-line reentrancy-events\n            emit FailedRelayedMessage(xDomainCalldataHash);\n        }\n\n        // Store an identifier that can be used to prove that the given message was relayed by some\n        // user. Gives us an easy way to pay relayers for their work.\n        bytes32 relayId = keccak256(abi.encodePacked(xDomainCalldata, msg.sender, block.number));\n        // slither-disable-next-line reentrancy-benign\n        relayedMessages[relayId] = true;\n    }\n\n    /**\n     * Replays a cross domain message to the target messenger.\n     * @inheritdoc IBLCrossDomainMessenger\n     */\n    // slither-disable-next-line external-function\n    function replayMessage(\n        address _target,\n        address _sender,\n        bytes memory _message,\n        uint256 _queueIndex,\n        uint32 _oldGasLimit,\n        uint32 _newGasLimit\n    ) public {\n        // Verify that the message is in the queue:\n        address messageQueue = resolve(\"MessageQueue\");\n        Lib_NVMCodec.QueueElement memory element = IMessageQueue(messageQueue).getQueueElement(\n            _queueIndex\n        );\n\n        // Compute the calldata that was originally used to send the message.\n        bytes memory xDomainCalldata = Lib_CrossDomainUtils.encodeXDomainCalldata(\n            _target,\n            _sender,\n            _message,\n            _queueIndex\n        );\n\n        // Compute the transactionHash\n        bytes32 transactionHash = keccak256(\n            abi.encode(\n                AddressAliasHelper.applyBLToSLAlias(address(this)),\n                Lib_PredeployAddresses.SL_CROSS_DOMAIN_MESSENGER,\n                _oldGasLimit,\n                xDomainCalldata\n            )\n        );\n\n        // Now check that the provided message data matches the one in the queue element.\n        require(\n            transactionHash == element.transactionHash,\n            \"Provided message has not been enqueued.\"\n        );\n\n        // Send the same message but with the new gas limit.\n        _sendXDomainMessage(messageQueue, xDomainCalldata, _newGasLimit);\n    }\n\n    /**********************\n     * Internal Functions *\n     **********************/\n\n    /**\n     * Verifies that the given message is valid.\n     * @param _xDomainCalldata Calldata to verify.\n     * @param _transaction Message transaction.\n     * @param _receipt Message receipt.\n     * @param _proof Inclusion proof for the message.\n     * @return Whether or not the provided message is valid.\n     */\n    function _verifyXDomainMessage(\n        bytes memory _xDomainCalldata,\n        Lib_NVMCodec.Transaction memory _transaction,\n        Lib_NVMCodec.Receipt memory _receipt,\n        SLMessageInclusionProof memory _proof\n    ) internal view returns (bool) {\n        return\n            _verifyStateRootProof(_transaction, _receipt, _proof) &&\n            _verifyStorageProof(_xDomainCalldata, _proof);\n    }\n\n    /**\n     * Verifies that the state root within an inclusion proof is valid.\n     * @param _transaction Message transaction.\n     * @param _receipt Message receipt.\n     * @param _proof Message inclusion proof.\n     * @return Whether or not the provided proof is valid.\n     */\n    function _verifyStateRootProof(\n        Lib_NVMCodec.Transaction memory _transaction,\n        Lib_NVMCodec.Receipt memory _receipt,\n        SLMessageInclusionProof memory _proof\n    ) internal view returns (bool) {\n        IFaultProofTimer faultProofTimer = IFaultProofTimer(resolve(\"FaultProofTimer\"));\n\n        if (_receipt.stateRoot != _proof.stateRoot) {\n            revert StateRootMismatch(_receipt.stateRoot, _proof.stateRoot);\n        }\n\n        if (_receipt.operatorHash != Lib_NVMCodec.hashTransaction(_transaction)) {\n            revert OperatorHashMismatch(\n                _receipt.operatorHash,\n                Lib_NVMCodec.hashTransaction(_transaction)\n            );\n        }\n\n        if (resolve(\"NVM_Sequencer\") != Lib_Receipt.recoverOperatorAddress(_receipt)) {\n            revert OperatorAddressMismatch(\n                resolve(\"NVM_Sequencer\"),\n                Lib_Receipt.recoverOperatorAddress(_receipt)\n            );\n        }\n\n        if (faultProofTimer.insideFaultProofWindow(_transaction)) {\n            revert FaultProofWindowViolation(\n                _transaction.blTimestamp + faultProofTimer.getFaultProofWindow(),\n                block.timestamp\n            );\n        }\n\n        return true;\n    }\n\n    /**\n     * Verifies that the storage proof within an inclusion proof is valid.\n     * @param _xDomainCalldata Encoded message calldata.\n     * @param _proof Message inclusion proof.\n     * @return Whether or not the provided proof is valid.\n     */\n    function _verifyStorageProof(\n        bytes memory _xDomainCalldata,\n        SLMessageInclusionProof memory _proof\n    ) internal view returns (bool) {\n        bytes32 storageKey = keccak256(\n            abi.encodePacked(\n                keccak256(\n                    abi.encodePacked(\n                        _xDomainCalldata,\n                        Lib_PredeployAddresses.SL_CROSS_DOMAIN_MESSENGER\n                    )\n                ),\n                uint256(0)\n            )\n        );\n\n        (bool exists, bytes memory encodedMessagePassingAccount) = Lib_SecureMerkleTrie.get(\n            abi.encodePacked(Lib_PredeployAddresses.SL_TO_BL_MESSAGE_PASSER),\n            _proof.stateTrieWitness,\n            _proof.stateRoot\n        );\n\n        if (!exists) {\n            revert StateValueMissing(\n                abi.encodePacked(Lib_PredeployAddresses.SL_TO_BL_MESSAGE_PASSER),\n                _proof.stateTrieWitness,\n                _proof.stateRoot\n            );\n        }\n\n        Lib_NVMCodec.EVMAccount memory account = Lib_NVMCodec.decodeEVMAccount(\n            encodedMessagePassingAccount\n        );\n\n        if (\n            !Lib_SecureMerkleTrie.verifyInclusionProof(\n                abi.encodePacked(storageKey),\n                abi.encodePacked(uint8(1)),\n                _proof.storageTrieWitness,\n                account.storageRoot\n            )\n        ) {\n            revert StorageProofInvalid(\n                abi.encodePacked(storageKey),\n                abi.encodePacked(uint8(1)),\n                _proof.storageTrieWitness,\n                account.storageRoot\n            );\n        }\n        return true;\n    }\n\n    /**\n     * Sends a cross domain message.\n     * @param _messageQueue Address of the _messageQueue instance.\n     * @param _message Message to send.\n     * @param _gasLimit NVM gas limit for the message.\n     */\n    function _sendXDomainMessage(\n        address _messageQueue,\n        bytes memory _message,\n        uint256 _gasLimit\n    ) internal {\n        // slither-disable-next-line reentrancy-events\n        IMessageQueue(_messageQueue).enqueue(\n            Lib_PredeployAddresses.SL_CROSS_DOMAIN_MESSENGER,\n            _gasLimit,\n            _message\n        );\n    }\n}\n"
      },
      "contracts/standards/AddressAliasHelper.sol": {
        "content": "// SPDX-License-Identifier: Apache-2.0\n\n/*\n * Copyright 2019-2021, Offchain Labs, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *    http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npragma solidity ^0.8.7;\n\nlibrary AddressAliasHelper {\n    uint160 constant offset = uint160(0x1111000000000000000000000000000000001111);\n\n    /// @notice Utility function that converts the address in the BL that submitted a tx to\n    /// the inbox to the msg.sender viewed in the SL\n    /// @param blAddress the address in the BL that triggered the tx to SL\n    /// @return slAddress SL address as viewed in msg.sender\n    function applyBLToSLAlias(address blAddress) internal pure returns (address slAddress) {\n        unchecked {\n            slAddress = address(uint160(blAddress) + offset);\n        }\n    }\n\n    /// @notice Utility function that converts the msg.sender viewed in the SL to the\n    /// address in the BL that submitted a tx to the inbox\n    /// @param slAddress SL address as viewed in msg.sender\n    /// @return blAddress the address in the BL that triggered the tx to SL\n    function undoBLToSLAlias(address slAddress) internal pure returns (address blAddress) {\n        unchecked {\n            blAddress = address(uint160(slAddress) - offset);\n        }\n    }\n}\n"
      },
      "contracts/libraries/resolver/Lib_AddressManager.sol": {
        "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.9;\n\n/* External Imports */\nimport { Ownable } from \"@openzeppelin/contracts/access/Ownable.sol\";\n\n/**\n * @title Lib_AddressManager\n */\ncontract Lib_AddressManager is Ownable {\n    /**********\n     * Events *\n     **********/\n\n    event AddressSet(string indexed _name, address _newAddress, address _oldAddress);\n\n    /*************\n     * Variables *\n     *************/\n\n    mapping(bytes32 => address) private addresses;\n\n    /********************\n     * Public Functions *\n     ********************/\n\n    /**\n     * Changes the address associated with a particular name.\n     * @param _name String name to associate an address with.\n     * @param _address Address to associate with the name.\n     */\n    function setAddress(string memory _name, address _address) external onlyOwner {\n        bytes32 nameHash = _getNameHash(_name);\n        address oldAddress = addresses[nameHash];\n        addresses[nameHash] = _address;\n\n        emit AddressSet(_name, _address, oldAddress);\n    }\n\n    /**\n     * Retrieves the address associated with a given name.\n     * @param _name Name to retrieve an address for.\n     * @return Address associated with the given name.\n     */\n    function getAddress(string memory _name) external view returns (address) {\n        return addresses[_getNameHash(_name)];\n    }\n\n    /**********************\n     * Internal Functions *\n     **********************/\n\n    /**\n     * Computes the hash of a name.\n     * @param _name Name to compute a hash for.\n     * @return Hash of the given name.\n     */\n    function _getNameHash(string memory _name) internal pure returns (bytes32) {\n        return keccak256(abi.encodePacked(_name));\n    }\n}\n"
      },
      "contracts/libraries/codec/Lib_NVMCodec.sol": {
        "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.9;\n\n/* Library Imports */\nimport { Lib_RLPReader } from \"../rlp/Lib_RLPReader.sol\";\nimport { Lib_RLPWriter } from \"../rlp/Lib_RLPWriter.sol\";\nimport { Lib_BytesUtils } from \"../utils/Lib_BytesUtils.sol\";\nimport { Lib_Bytes32Utils } from \"../utils/Lib_Bytes32Utils.sol\";\n\n/**\n * @title Lib_NVMCodec\n */\nlibrary Lib_NVMCodec {\n    /*********\n     * Enums *\n     *********/\n\n    enum QueueOrigin {\n        SEQUENCER_QUEUE,\n        BLTOSL_QUEUE\n    }\n\n    /***********\n     * Structs *\n     ***********/\n\n    struct EVMAccount {\n        uint256 nonce;\n        uint256 balance;\n        bytes32 storageRoot;\n        bytes32 codeHash;\n    }\n\n    struct ChainBatchHeader {\n        uint256 batchIndex;\n        bytes32 batchRoot;\n        uint256 batchSize;\n        uint256 prevTotalElements;\n        bytes extraData;\n    }\n\n    struct ChainInclusionProof {\n        uint256 index;\n        bytes32[] siblings;\n    }\n\n    struct Transaction {\n        uint256 blTimestamp;\n        uint256 blockNumber;\n        uint256 slTimestamp;\n        QueueOrigin blQueueOrigin;\n        bytes data;\n    }\n\n    struct TransactionChainElement {\n        bool isSequenced;\n        uint256 queueIndex; // QUEUED TX ONLY\n        uint256 timestamp; // SEQUENCER TX ONLY\n        uint256 blockNumber; // SEQUENCER TX ONLY\n        bytes txData; // SEQUENCER TX ONLY\n    }\n\n    struct QueueElement {\n        bytes32 transactionHash;\n        uint40 timestamp;\n        uint40 blockNumber;\n    }\n\n    struct Receipt {\n        uint256 index;\n        bytes32 stateRoot;\n        bytes32 operatorHash;\n        bytes operatorSignature;\n    }\n\n    /**********************\n     * Internal Functions *\n     **********************/\n\n    /**\n     * Encodes a standard NVM transaction.\n     * @param _transaction NVM transaction to encode.\n     * @return Encoded transaction bytes.\n     */\n    function encodeTransaction(Transaction memory _transaction)\n        internal\n        pure\n        returns (bytes memory)\n    {\n        return\n            abi.encodePacked(\n                _transaction.blTimestamp,\n                _transaction.blockNumber,\n                _transaction.slTimestamp,\n                _transaction.blQueueOrigin,\n                _transaction.data\n            );\n    }\n\n    /**\n     * Hashes a standard NVM transaction.\n     * @param _transaction NVM transaction to encode.\n     * @return Hashed transaction\n     */\n    function hashTransaction(Transaction memory _transaction) internal pure returns (bytes32) {\n        return keccak256(encodeTransaction(_transaction));\n    }\n\n    /**\n     * @notice Decodes an RLP-encoded account state into a useful struct.\n     * @param _encoded RLP-encoded account state.\n     * @return Account state struct.\n     */\n    function decodeEVMAccount(bytes memory _encoded) internal pure returns (EVMAccount memory) {\n        Lib_RLPReader.RLPItem[] memory accountState = Lib_RLPReader.readList(_encoded);\n\n        return\n            EVMAccount({\n                nonce: Lib_RLPReader.readUint256(accountState[0]),\n                balance: Lib_RLPReader.readUint256(accountState[1]),\n                storageRoot: Lib_RLPReader.readBytes32(accountState[2]),\n                codeHash: Lib_RLPReader.readBytes32(accountState[3])\n            });\n    }\n\n    /**\n     * Calculates a hash for a given batch header.\n     * @param _batchHeader Header to hash.\n     * @return Hash of the header.\n     */\n    function hashBatchHeader(Lib_NVMCodec.ChainBatchHeader memory _batchHeader)\n        internal\n        pure\n        returns (bytes32)\n    {\n        return\n            keccak256(\n                abi.encode(\n                    _batchHeader.batchRoot,\n                    _batchHeader.batchSize,\n                    _batchHeader.prevTotalElements,\n                    _batchHeader.extraData\n                )\n            );\n    }\n}\n"
      },
      "contracts/libraries/constants/Lib_PredeployAddresses.sol": {
        "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.9;\n\n/**\n * @title Lib_PredeployAddresses\n */\nlibrary Lib_PredeployAddresses {\n    address internal constant SL_TO_BL_MESSAGE_PASSER = 0x4200000000000000000000000000000000000000;\n    address internal constant BL_MESSAGE_SENDER = 0x4200000000000000000000000000000000000001;\n    address internal constant DEPLOYER_WHITELIST = 0x4200000000000000000000000000000000000002;\n    address payable internal constant NVM_ETH = payable(0xDeadDeAddeAddEAddeadDEaDDEAdDeaDDeAD0000);\n    address internal constant SL_CROSS_DOMAIN_MESSENGER =\n        0x4200000000000000000000000000000000000007;\n    address internal constant LIB_ADDRESS_MANAGER = 0x4200000000000000000000000000000000000008;\n    address internal constant PROXY_EOA = 0x4200000000000000000000000000000000000009;\n    address internal constant SL_STANDARD_BRIDGE = 0x4200000000000000000000000000000000000010;\n    address internal constant SEQUENCER_FEE_VAULT = 0x4200000000000000000000000000000000000011;\n    address internal constant NAHMII_STANDARD_ERC20_FACTORY =\n        0x4200000000000000000000000000000000000012;\n    address internal constant BL_BLOCK_NUMBER = 0x4200000000000000000000000000000000000013;\n}\n"
      },
      "contracts/libraries/resolver/Lib_AddressResolver.sol": {
        "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.9;\n\n/* Library Imports */\nimport { Lib_AddressManager } from \"./Lib_AddressManager.sol\";\n\n/**\n * @title Lib_AddressResolver\n */\nabstract contract Lib_AddressResolver {\n    /*************\n     * Variables *\n     *************/\n\n    Lib_AddressManager public libAddressManager;\n\n    /***************\n     * Constructor *\n     ***************/\n\n    /**\n     * @param _libAddressManager Address of the Lib_AddressManager.\n     */\n    constructor(address _libAddressManager) {\n        libAddressManager = Lib_AddressManager(_libAddressManager);\n    }\n\n    /********************\n     * Public Functions *\n     ********************/\n\n    /**\n     * Resolves the address associated with a given name.\n     * @param _name Name to resolve an address for.\n     * @return Address associated with the given name.\n     */\n    function resolve(string memory _name) public view returns (address) {\n        return libAddressManager.getAddress(_name);\n    }\n}\n"
      },
      "contracts/libraries/trie/Lib_SecureMerkleTrie.sol": {
        "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.9;\n\n/* Library Imports */\nimport { Lib_MerkleTrie } from \"./Lib_MerkleTrie.sol\";\n\n/**\n * @title Lib_SecureMerkleTrie\n */\nlibrary Lib_SecureMerkleTrie {\n    /**********************\n     * Internal Functions *\n     **********************/\n\n    /**\n     * @notice Verifies a proof that a given key/value pair is present in the\n     * Merkle trie.\n     * @param _key Key of the node to search for, as a hex string.\n     * @param _value Value of the node to search for, as a hex string.\n     * @param _proof Merkle trie inclusion proof for the desired node. Unlike\n     * traditional Merkle trees, this proof is executed top-down and consists\n     * of a list of RLP-encoded nodes that make a path down to the target node.\n     * @param _root Known root of the Merkle trie. Used to verify that the\n     * included proof is correctly constructed.\n     * @return _verified `true` if the k/v pair exists in the trie, `false` otherwise.\n     */\n    function verifyInclusionProof(\n        bytes memory _key,\n        bytes memory _value,\n        bytes memory _proof,\n        bytes32 _root\n    ) internal pure returns (bool _verified) {\n        bytes memory key = _getSecureKey(_key);\n        return Lib_MerkleTrie.verifyInclusionProof(key, _value, _proof, _root);\n    }\n\n    /**\n     * @notice Retrieves the value associated with a given key.\n     * @param _key Key to search for, as hex bytes.\n     * @param _proof Merkle trie inclusion proof for the key.\n     * @param _root Known root of the Merkle trie.\n     * @return _exists Whether or not the key exists.\n     * @return _value Value of the key if it exists.\n     */\n    function get(\n        bytes memory _key,\n        bytes memory _proof,\n        bytes32 _root\n    ) internal pure returns (bool _exists, bytes memory _value) {\n        bytes memory key = _getSecureKey(_key);\n        return Lib_MerkleTrie.get(key, _proof, _root);\n    }\n\n    /*********************\n     * Private Functions *\n     *********************/\n\n    /**\n     * Computes the secure counterpart to a key.\n     * @param _key Key to get a secure key from.\n     * @return _secureKey Secure version of the key.\n     */\n    function _getSecureKey(bytes memory _key) private pure returns (bytes memory _secureKey) {\n        return abi.encodePacked(keccak256(_key));\n    }\n}\n"
      },
      "contracts/libraries/constants/Lib_DefaultValues.sol": {
        "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.9;\n\n/**\n * @title Lib_DefaultValues\n */\nlibrary Lib_DefaultValues {\n    // The default x-domain message sender being set to a non-zero value makes\n    // deployment a bit more expensive, but in exchange the refund on every call to\n    // `relayMessage` by the BL and SL messengers will be higher.\n    address internal constant DEFAULT_XDOMAIN_SENDER = 0x000000000000000000000000000000000000dEaD;\n}\n"
      },
      "contracts/libraries/codec/Lib_Receipt.sol": {
        "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.9;\n\n/* Library Imports */\nimport { Lib_NVMCodec } from \"./Lib_NVMCodec.sol\";\nimport \"@openzeppelin/contracts/utils/cryptography/ECDSA.sol\";\n\n/**\n * @title Lib_Receipt\n * @dev A library for dealing with the receipt verification\n */\nlibrary Lib_Receipt {\n    using ECDSA for bytes32;\n\n    /**\n     * Recovers the address of the operator from the receipt's operator signature.\n     * @param _receipt receipt to recover from.\n     * @return Address of the operator signer of the receipt.\n     */\n    function recoverOperatorAddress(Lib_NVMCodec.Receipt memory _receipt)\n        internal\n        pure\n        returns (address)\n    {\n        bytes memory encoded = abi.encodePacked(\n            _receipt.stateRoot,\n            _receipt.index,\n            _receipt.operatorHash\n        );\n\n        return keccak256(encoded).recover(_receipt.operatorSignature);\n    }\n\n    /**\n     * Verifies the operator signature.\n     * @param _receipt receipt to verify.\n     * @param _operatorAddress address of the operator signer.\n     * @return True if the operator signature is valid, else false.\n     */\n    function verifyOperatorSignature(Lib_NVMCodec.Receipt memory _receipt, address _operatorAddress)\n        internal\n        pure\n        returns (bool)\n    {\n        return recoverOperatorAddress(_receipt) == _operatorAddress;\n    }\n\n    /**\n     * Verifies whether a transaction is valid.\n     * @param _transaction Transaction to verify.\n     * @param _receipt Receipt to verify.\n     * @return True if the transaction exists in the CTC, else false.\n     */\n    function verifyTransaction(\n        Lib_NVMCodec.Transaction memory _transaction,\n        Lib_NVMCodec.Receipt memory _receipt\n    ) internal pure returns (bool) {\n        bytes32 operatorHash = Lib_NVMCodec.hashTransaction(_transaction);\n        return operatorHash == _receipt.operatorHash;\n    }\n}\n"
      },
      "contracts/BL/rollup/IFaultProofTimer.sol": {
        "content": "// SPDX-License-Identifier: MIT\npragma solidity >0.5.0 <0.9.0;\n\n/* Library Imports */\nimport { Lib_NVMCodec } from \"../../libraries/codec/Lib_NVMCodec.sol\";\n\n/**\n * @title IFaultProofTimer\n */\ninterface IFaultProofTimer {\n    /**\n     * Gets the defined fault proof window\n     * @return The fault proof window\n     */\n    function getFaultProofWindow() external view returns (uint256);\n\n    /**\n     * Sets the fault proof window with the provided value\n     * @param _faultProofWindow value to be set as the fault proof window\n     */\n    function setFaultProofWindow(uint256 _faultProofWindow) external;\n\n    /**\n     * Checks whether a given transaction is still inside the fault proof window.\n     * @param _nvmTransaction Transaction to check.\n     * @return _inside Whether or not the transaction is inside the fault proof window.\n     */\n    function insideFaultProofWindow(Lib_NVMCodec.Transaction memory _nvmTransaction)\n        external\n        view\n        returns (bool);\n}\n"
      },
      "contracts/libraries/bridge/Lib_CrossDomainUtils.sol": {
        "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.9;\n\n/**\n * @title Lib_CrossDomainUtils\n */\nlibrary Lib_CrossDomainUtils {\n    /**\n     * Generates the correct cross domain calldata for a message.\n     * @param _target Target contract address.\n     * @param _sender Message sender address.\n     * @param _message Message to send to the target.\n     * @param _messageNonce Nonce for the provided message.\n     * @return ABI encoded cross domain calldata.\n     */\n    function encodeXDomainCalldata(\n        address _target,\n        address _sender,\n        bytes memory _message,\n        uint256 _messageNonce\n    ) internal pure returns (bytes memory) {\n        return\n            abi.encodeWithSignature(\n                \"relayMessage(address,address,bytes,uint256)\",\n                _target,\n                _sender,\n                _message,\n                _messageNonce\n            );\n    }\n}\n"
      },
      "contracts/BL/messaging/IBLCrossDomainMessenger.sol": {
        "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.9;\n\n/* Library Imports */\nimport { Lib_NVMCodec } from \"../../libraries/codec/Lib_NVMCodec.sol\";\n\n/* Interface Imports */\nimport { ICrossDomainMessenger } from \"../../libraries/bridge/ICrossDomainMessenger.sol\";\n\n/**\n * @title IBLCrossDomainMessenger\n */\ninterface IBLCrossDomainMessenger is ICrossDomainMessenger {\n    /*******************\n     * Data Structures *\n     *******************/\n\n    struct SLMessageInclusionProof {\n        bytes32 stateRoot;\n        bytes stateTrieWitness;\n        bytes storageTrieWitness;\n    }\n\n    /********************\n     * Public Functions *\n     ********************/\n\n    /**\n     * Relays a cross domain message to a contract.\n     * @param _target Target contract address.\n     * @param _sender Message sender address.\n     * @param _message Message to send to the target.\n     * @param _messageNonce Nonce for the provided message.\n     * @param _transaction Message transaction.\n     * @param _receipt Message receipt.\n     * @param _proof Inclusion proof for the given message.\n     */\n    function relayMessage(\n        address _target,\n        address _sender,\n        bytes memory _message,\n        uint256 _messageNonce,\n        Lib_NVMCodec.Transaction memory _transaction,\n        Lib_NVMCodec.Receipt memory _receipt,\n        SLMessageInclusionProof memory _proof\n    ) external;\n\n    /**\n     * Replays a cross domain message to the target messenger.\n     * @param _target Target contract address.\n     * @param _sender Original sender address.\n     * @param _message Message to send to the target.\n     * @param _queueIndex CTC Queue index for the message to replay.\n     * @param _oldGasLimit Original gas limit used to send the message.\n     * @param _newGasLimit New gas limit to be used for this message.\n     */\n    function replayMessage(\n        address _target,\n        address _sender,\n        bytes memory _message,\n        uint256 _queueIndex,\n        uint32 _oldGasLimit,\n        uint32 _newGasLimit\n    ) external;\n}\n"
      },
      "contracts/BL/rollup/IMessageQueue.sol": {
        "content": "// SPDX-License-Identifier: MIT\npragma solidity >0.5.0 <0.9.0;\n\n/* Library Imports */\nimport { Lib_NVMCodec } from \"../../libraries/codec/Lib_NVMCodec.sol\";\n\n/**\n * @title IMessageQueue\n */\ninterface IMessageQueue {\n    /**********\n     * Events *\n     **********/\n\n    event TransactionEnqueued(\n        address indexed _blTxOrigin,\n        address indexed _target,\n        uint256 _gasLimit,\n        bytes _data,\n        uint256 indexed _queueIndex,\n        uint256 _timestamp\n    );\n\n    /********************\n     * Public Functions *\n     ********************/\n\n    /**\n     * Gets the queue element at a particular index.\n     * @param _index Index of the queue element to access.\n     * @return _element Queue element at the given index.\n     */\n    function getQueueElement(uint256 _index)\n        external\n        view\n        returns (Lib_NVMCodec.QueueElement memory _element);\n\n    /**\n     * Retrieves the length of the queue, including\n     * both pending and canonical transactions.\n     * @return Length of the queue.\n     */\n    function getQueueLength() external view returns (uint40);\n\n    /**\n     * Adds a transaction to the queue.\n     * @param _target Target contract to send the transaction to.\n     * @param _gasLimit Gas limit for the given transaction.\n     * @param _data Transaction data.\n     */\n    function enqueue(\n        address _target,\n        uint256 _gasLimit,\n        bytes memory _data\n    ) external;\n}\n"
      },
      "@openzeppelin/contracts-upgradeable/security/PausableUpgradeable.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (security/Pausable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../utils/ContextUpgradeable.sol\";\nimport \"../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Contract module which allows children to implement an emergency stop\n * mechanism that can be triggered by an authorized account.\n *\n * This module is used through inheritance. It will make available the\n * modifiers `whenNotPaused` and `whenPaused`, which can be applied to\n * the functions of your contract. Note that they will not be pausable by\n * simply including this module, only once the modifiers are put in place.\n */\nabstract contract PausableUpgradeable is Initializable, ContextUpgradeable {\n    /**\n     * @dev Emitted when the pause is triggered by `account`.\n     */\n    event Paused(address account);\n\n    /**\n     * @dev Emitted when the pause is lifted by `account`.\n     */\n    event Unpaused(address account);\n\n    bool private _paused;\n\n    /**\n     * @dev Initializes the contract in unpaused state.\n     */\n    function __Pausable_init() internal onlyInitializing {\n        __Pausable_init_unchained();\n    }\n\n    function __Pausable_init_unchained() internal onlyInitializing {\n        _paused = false;\n    }\n\n    /**\n     * @dev Modifier to make a function callable only when the contract is not paused.\n     *\n     * Requirements:\n     *\n     * - The contract must not be paused.\n     */\n    modifier whenNotPaused() {\n        _requireNotPaused();\n        _;\n    }\n\n    /**\n     * @dev Modifier to make a function callable only when the contract is paused.\n     *\n     * Requirements:\n     *\n     * - The contract must be paused.\n     */\n    modifier whenPaused() {\n        _requirePaused();\n        _;\n    }\n\n    /**\n     * @dev Returns true if the contract is paused, and false otherwise.\n     */\n    function paused() public view virtual returns (bool) {\n        return _paused;\n    }\n\n    /**\n     * @dev Throws if the contract is paused.\n     */\n    function _requireNotPaused() internal view virtual {\n        require(!paused(), \"Pausable: paused\");\n    }\n\n    /**\n     * @dev Throws if the contract is not paused.\n     */\n    function _requirePaused() internal view virtual {\n        require(paused(), \"Pausable: not paused\");\n    }\n\n    /**\n     * @dev Triggers stopped state.\n     *\n     * Requirements:\n     *\n     * - The contract must not be paused.\n     */\n    function _pause() internal virtual whenNotPaused {\n        _paused = true;\n        emit Paused(_msgSender());\n    }\n\n    /**\n     * @dev Returns to normal state.\n     *\n     * Requirements:\n     *\n     * - The contract must be paused.\n     */\n    function _unpause() internal virtual whenPaused {\n        _paused = false;\n        emit Unpaused(_msgSender());\n    }\n\n    /**\n     * @dev This empty reserved space is put in place to allow future versions to add new\n     * variables without shifting down storage in the inheritance chain.\n     * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n     */\n    uint256[49] private __gap;\n}\n"
      },
      "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (access/Ownable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../utils/ContextUpgradeable.sol\";\nimport \"../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Contract module which provides a basic access control mechanism, where\n * there is an account (an owner) that can be granted exclusive access to\n * specific functions.\n *\n * By default, the owner account will be the one that deploys the contract. This\n * can later be changed with {transferOwnership}.\n *\n * This module is used through inheritance. It will make available the modifier\n * `onlyOwner`, which can be applied to your functions to restrict their use to\n * the owner.\n */\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\n    address private _owner;\n\n    event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n    /**\n     * @dev Initializes the contract setting the deployer as the initial owner.\n     */\n    function __Ownable_init() internal onlyInitializing {\n        __Ownable_init_unchained();\n    }\n\n    function __Ownable_init_unchained() internal onlyInitializing {\n        _transferOwnership(_msgSender());\n    }\n\n    /**\n     * @dev Throws if called by any account other than the owner.\n     */\n    modifier onlyOwner() {\n        _checkOwner();\n        _;\n    }\n\n    /**\n     * @dev Returns the address of the current owner.\n     */\n    function owner() public view virtual returns (address) {\n        return _owner;\n    }\n\n    /**\n     * @dev Throws if the sender is not the owner.\n     */\n    function _checkOwner() internal view virtual {\n        require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n    }\n\n    /**\n     * @dev Leaves the contract without owner. It will not be possible to call\n     * `onlyOwner` functions anymore. Can only be called by the current owner.\n     *\n     * NOTE: Renouncing ownership will leave the contract without an owner,\n     * thereby removing any functionality that is only available to the owner.\n     */\n    function renounceOwnership() public virtual onlyOwner {\n        _transferOwnership(address(0));\n    }\n\n    /**\n     * @dev Transfers ownership of the contract to a new account (`newOwner`).\n     * Can only be called by the current owner.\n     */\n    function transferOwnership(address newOwner) public virtual onlyOwner {\n        require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n        _transferOwnership(newOwner);\n    }\n\n    /**\n     * @dev Transfers ownership of the contract to a new account (`newOwner`).\n     * Internal function without access restriction.\n     */\n    function _transferOwnership(address newOwner) internal virtual {\n        address oldOwner = _owner;\n        _owner = newOwner;\n        emit OwnershipTransferred(oldOwner, newOwner);\n    }\n\n    /**\n     * @dev This empty reserved space is put in place to allow future versions to add new\n     * variables without shifting down storage in the inheritance chain.\n     * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n     */\n    uint256[49] private __gap;\n}\n"
      },
      "@openzeppelin/contracts-upgradeable/security/ReentrancyGuardUpgradeable.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (security/ReentrancyGuard.sol)\n\npragma solidity ^0.8.0;\nimport \"../proxy/utils/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    uint256 private _status;\n\n    function __ReentrancyGuard_init() internal onlyInitializing {\n        __ReentrancyGuard_init_unchained();\n    }\n\n    function __ReentrancyGuard_init_unchained() internal onlyInitializing {\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        // On the first call to nonReentrant, _notEntered will be true\n        require(_status != _ENTERED, \"ReentrancyGuard: reentrant call\");\n\n        // Any calls to nonReentrant after this point will fail\n        _status = _ENTERED;\n\n        _;\n\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 This empty reserved space is put in place to allow future versions to add new\n     * variables without shifting down storage in the inheritance chain.\n     * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n     */\n    uint256[49] private __gap;\n}\n"
      },
      "@openzeppelin/contracts/access/Ownable.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (access/Ownable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../utils/Context.sol\";\n\n/**\n * @dev Contract module which provides a basic access control mechanism, where\n * there is an account (an owner) that can be granted exclusive access to\n * specific functions.\n *\n * By default, the owner account will be the one that deploys the contract. This\n * can later be changed with {transferOwnership}.\n *\n * This module is used through inheritance. It will make available the modifier\n * `onlyOwner`, which can be applied to your functions to restrict their use to\n * the owner.\n */\nabstract contract Ownable is Context {\n    address private _owner;\n\n    event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n    /**\n     * @dev Initializes the contract setting the deployer as the initial owner.\n     */\n    constructor() {\n        _transferOwnership(_msgSender());\n    }\n\n    /**\n     * @dev Throws if called by any account other than the owner.\n     */\n    modifier onlyOwner() {\n        _checkOwner();\n        _;\n    }\n\n    /**\n     * @dev Returns the address of the current owner.\n     */\n    function owner() public view virtual returns (address) {\n        return _owner;\n    }\n\n    /**\n     * @dev Throws if the sender is not the owner.\n     */\n    function _checkOwner() internal view virtual {\n        require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n    }\n\n    /**\n     * @dev Leaves the contract without owner. It will not be possible to call\n     * `onlyOwner` functions anymore. Can only be called by the current owner.\n     *\n     * NOTE: Renouncing ownership will leave the contract without an owner,\n     * thereby removing any functionality that is only available to the owner.\n     */\n    function renounceOwnership() public virtual onlyOwner {\n        _transferOwnership(address(0));\n    }\n\n    /**\n     * @dev Transfers ownership of the contract to a new account (`newOwner`).\n     * Can only be called by the current owner.\n     */\n    function transferOwnership(address newOwner) public virtual onlyOwner {\n        require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n        _transferOwnership(newOwner);\n    }\n\n    /**\n     * @dev Transfers ownership of the contract to a new account (`newOwner`).\n     * Internal function without access restriction.\n     */\n    function _transferOwnership(address newOwner) internal virtual {\n        address oldOwner = _owner;\n        _owner = newOwner;\n        emit OwnershipTransferred(oldOwner, newOwner);\n    }\n}\n"
      },
      "@openzeppelin/contracts/utils/Context.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract Context {\n    function _msgSender() internal view virtual returns (address) {\n        return msg.sender;\n    }\n\n    function _msgData() internal view virtual returns (bytes calldata) {\n        return msg.data;\n    }\n}\n"
      },
      "contracts/libraries/rlp/Lib_RLPWriter.sol": {
        "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.9;\n\n/**\n * @title Lib_RLPWriter\n * @author Bakaoh (with modifications)\n */\nlibrary Lib_RLPWriter {\n    /**********************\n     * Internal Functions *\n     **********************/\n\n    /**\n     * RLP encodes a byte string.\n     * @param _in The byte string to encode.\n     * @return The RLP encoded string in bytes.\n     */\n    function writeBytes(bytes memory _in) internal pure returns (bytes memory) {\n        bytes memory encoded;\n\n        if (_in.length == 1 && uint8(_in[0]) < 128) {\n            encoded = _in;\n        } else {\n            encoded = abi.encodePacked(_writeLength(_in.length, 128), _in);\n        }\n\n        return encoded;\n    }\n\n    /**\n     * RLP encodes a list of RLP encoded byte byte strings.\n     * @param _in The list of RLP encoded byte strings.\n     * @return The RLP encoded list of items in bytes.\n     */\n    function writeList(bytes[] memory _in) internal pure returns (bytes memory) {\n        bytes memory list = _flatten(_in);\n        return abi.encodePacked(_writeLength(list.length, 192), list);\n    }\n\n    /**\n     * RLP encodes a string.\n     * @param _in The string to encode.\n     * @return The RLP encoded string in bytes.\n     */\n    function writeString(string memory _in) internal pure returns (bytes memory) {\n        return writeBytes(bytes(_in));\n    }\n\n    /**\n     * RLP encodes an address.\n     * @param _in The address to encode.\n     * @return The RLP encoded address in bytes.\n     */\n    function writeAddress(address _in) internal pure returns (bytes memory) {\n        return writeBytes(abi.encodePacked(_in));\n    }\n\n    /**\n     * RLP encodes a uint.\n     * @param _in The uint256 to encode.\n     * @return The RLP encoded uint256 in bytes.\n     */\n    function writeUint(uint256 _in) internal pure returns (bytes memory) {\n        return writeBytes(_toBinary(_in));\n    }\n\n    /**\n     * RLP encodes a bool.\n     * @param _in The bool to encode.\n     * @return The RLP encoded bool in bytes.\n     */\n    function writeBool(bool _in) internal pure returns (bytes memory) {\n        bytes memory encoded = new bytes(1);\n        encoded[0] = (_in ? bytes1(0x01) : bytes1(0x80));\n        return encoded;\n    }\n\n    /*********************\n     * Private Functions *\n     *********************/\n\n    /**\n     * Encode the first byte, followed by the `len` in binary form if `length` is more than 55.\n     * @param _len The length of the string or the payload.\n     * @param _offset 128 if item is string, 192 if item is list.\n     * @return RLP encoded bytes.\n     */\n    function _writeLength(uint256 _len, uint256 _offset) private pure returns (bytes memory) {\n        bytes memory encoded;\n\n        if (_len < 56) {\n            encoded = new bytes(1);\n            encoded[0] = bytes1(uint8(_len) + uint8(_offset));\n        } else {\n            uint256 lenLen;\n            uint256 i = 1;\n            while (_len / i != 0) {\n                lenLen++;\n                i *= 256;\n            }\n\n            encoded = new bytes(lenLen + 1);\n            encoded[0] = bytes1(uint8(lenLen) + uint8(_offset) + 55);\n            for (i = 1; i <= lenLen; i++) {\n                encoded[i] = bytes1(uint8((_len / (256**(lenLen - i))) % 256));\n            }\n        }\n\n        return encoded;\n    }\n\n    /**\n     * Encode integer in big endian binary form with no leading zeroes.\n     * @notice TODO: This should be optimized with assembly to save gas costs.\n     * @param _x The integer to encode.\n     * @return RLP encoded bytes.\n     */\n    function _toBinary(uint256 _x) private pure returns (bytes memory) {\n        bytes memory b = abi.encodePacked(_x);\n\n        uint256 i = 0;\n        for (; i < 32; i++) {\n            if (b[i] != 0) {\n                break;\n            }\n        }\n\n        bytes memory res = new bytes(32 - i);\n        for (uint256 j = 0; j < res.length; j++) {\n            res[j] = b[i++];\n        }\n\n        return res;\n    }\n\n    /**\n     * Copies a piece of memory to another location.\n     * @notice From: https://github.com/Arachnid/solidity-stringutils/blob/master/src/strings.sol.\n     * @param _dest Destination location.\n     * @param _src Source location.\n     * @param _len Length of memory to copy.\n     */\n    function _memcpy(\n        uint256 _dest,\n        uint256 _src,\n        uint256 _len\n    ) private pure {\n        uint256 dest = _dest;\n        uint256 src = _src;\n        uint256 len = _len;\n\n        for (; len >= 32; len -= 32) {\n            assembly {\n                mstore(dest, mload(src))\n            }\n            dest += 32;\n            src += 32;\n        }\n\n        uint256 mask;\n        unchecked {\n            mask = 256**(32 - len) - 1;\n        }\n        assembly {\n            let srcpart := and(mload(src), not(mask))\n            let destpart := and(mload(dest), mask)\n            mstore(dest, or(destpart, srcpart))\n        }\n    }\n\n    /**\n     * Flattens a list of byte strings into one byte string.\n     * @notice From: https://github.com/sammayo/solidity-rlp-encoder/blob/master/RLPEncode.sol.\n     * @param _list List of byte strings to flatten.\n     * @return The flattened byte string.\n     */\n    function _flatten(bytes[] memory _list) private pure returns (bytes memory) {\n        if (_list.length == 0) {\n            return new bytes(0);\n        }\n\n        uint256 len;\n        uint256 i = 0;\n        for (; i < _list.length; i++) {\n            len += _list[i].length;\n        }\n\n        bytes memory flattened = new bytes(len);\n        uint256 flattenedPtr;\n        assembly {\n            flattenedPtr := add(flattened, 0x20)\n        }\n\n        for (i = 0; i < _list.length; i++) {\n            bytes memory item = _list[i];\n\n            uint256 listPtr;\n            assembly {\n                listPtr := add(item, 0x20)\n            }\n\n            _memcpy(flattenedPtr, listPtr, item.length);\n            flattenedPtr += _list[i].length;\n        }\n\n        return flattened;\n    }\n}\n"
      },
      "contracts/libraries/rlp/Lib_RLPReader.sol": {
        "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.9;\n\n/**\n * @title Lib_RLPReader\n * @dev Adapted from \"RLPReader\" by Hamdi Allam (hamdi.allam97@gmail.com).\n */\nlibrary Lib_RLPReader {\n    /*************\n     * Constants *\n     *************/\n\n    uint256 internal constant MAX_LIST_LENGTH = 32;\n\n    /*********\n     * Enums *\n     *********/\n\n    enum RLPItemType {\n        DATA_ITEM,\n        LIST_ITEM\n    }\n\n    /***********\n     * Structs *\n     ***********/\n\n    struct RLPItem {\n        uint256 length;\n        uint256 ptr;\n    }\n\n    /**********************\n     * Internal Functions *\n     **********************/\n\n    /**\n     * Converts bytes to a reference to memory position and length.\n     * @param _in Input bytes to convert.\n     * @return Output memory reference.\n     */\n    function toRLPItem(bytes memory _in) internal pure returns (RLPItem memory) {\n        uint256 ptr;\n        assembly {\n            ptr := add(_in, 32)\n        }\n\n        return RLPItem({ length: _in.length, ptr: ptr });\n    }\n\n    /**\n     * Reads an RLP list value into a list of RLP items.\n     * @param _in RLP list value.\n     * @return Decoded RLP list items.\n     */\n    function readList(RLPItem memory _in) internal pure returns (RLPItem[] memory) {\n        (uint256 listOffset, , RLPItemType itemType) = _decodeLength(_in);\n\n        require(itemType == RLPItemType.LIST_ITEM, \"Invalid RLP list value.\");\n\n        // Solidity in-memory arrays can't be increased in size, but *can* be decreased in size by\n        // writing to the length. Since we can't know the number of RLP items without looping over\n        // the entire input, we'd have to loop twice to accurately size this array. It's easier to\n        // simply set a reasonable maximum list length and decrease the size before we finish.\n        RLPItem[] memory out = new RLPItem[](MAX_LIST_LENGTH);\n\n        uint256 itemCount = 0;\n        uint256 offset = listOffset;\n        while (offset < _in.length) {\n            require(itemCount < MAX_LIST_LENGTH, \"Provided RLP list exceeds max list length.\");\n\n            (uint256 itemOffset, uint256 itemLength, ) = _decodeLength(\n                RLPItem({ length: _in.length - offset, ptr: _in.ptr + offset })\n            );\n\n            out[itemCount] = RLPItem({ length: itemLength + itemOffset, ptr: _in.ptr + offset });\n\n            itemCount += 1;\n            offset += itemOffset + itemLength;\n        }\n\n        // Decrease the array size to match the actual item count.\n        assembly {\n            mstore(out, itemCount)\n        }\n\n        return out;\n    }\n\n    /**\n     * Reads an RLP list value into a list of RLP items.\n     * @param _in RLP list value.\n     * @return Decoded RLP list items.\n     */\n    function readList(bytes memory _in) internal pure returns (RLPItem[] memory) {\n        return readList(toRLPItem(_in));\n    }\n\n    /**\n     * Reads an RLP bytes value into bytes.\n     * @param _in RLP bytes value.\n     * @return Decoded bytes.\n     */\n    function readBytes(RLPItem memory _in) internal pure returns (bytes memory) {\n        (uint256 itemOffset, uint256 itemLength, RLPItemType itemType) = _decodeLength(_in);\n\n        require(itemType == RLPItemType.DATA_ITEM, \"Invalid RLP bytes value.\");\n\n        return _copy(_in.ptr, itemOffset, itemLength);\n    }\n\n    /**\n     * Reads an RLP bytes value into bytes.\n     * @param _in RLP bytes value.\n     * @return Decoded bytes.\n     */\n    function readBytes(bytes memory _in) internal pure returns (bytes memory) {\n        return readBytes(toRLPItem(_in));\n    }\n\n    /**\n     * Reads an RLP string value into a string.\n     * @param _in RLP string value.\n     * @return Decoded string.\n     */\n    function readString(RLPItem memory _in) internal pure returns (string memory) {\n        return string(readBytes(_in));\n    }\n\n    /**\n     * Reads an RLP string value into a string.\n     * @param _in RLP string value.\n     * @return Decoded string.\n     */\n    function readString(bytes memory _in) internal pure returns (string memory) {\n        return readString(toRLPItem(_in));\n    }\n\n    /**\n     * Reads an RLP bytes32 value into a bytes32.\n     * @param _in RLP bytes32 value.\n     * @return Decoded bytes32.\n     */\n    function readBytes32(RLPItem memory _in) internal pure returns (bytes32) {\n        require(_in.length <= 33, \"Invalid RLP bytes32 value.\");\n\n        (uint256 itemOffset, uint256 itemLength, RLPItemType itemType) = _decodeLength(_in);\n\n        require(itemType == RLPItemType.DATA_ITEM, \"Invalid RLP bytes32 value.\");\n\n        uint256 ptr = _in.ptr + itemOffset;\n        bytes32 out;\n        assembly {\n            out := mload(ptr)\n\n            // Shift the bytes over to match the item size.\n            if lt(itemLength, 32) {\n                out := div(out, exp(256, sub(32, itemLength)))\n            }\n        }\n\n        return out;\n    }\n\n    /**\n     * Reads an RLP bytes32 value into a bytes32.\n     * @param _in RLP bytes32 value.\n     * @return Decoded bytes32.\n     */\n    function readBytes32(bytes memory _in) internal pure returns (bytes32) {\n        return readBytes32(toRLPItem(_in));\n    }\n\n    /**\n     * Reads an RLP uint256 value into a uint256.\n     * @param _in RLP uint256 value.\n     * @return Decoded uint256.\n     */\n    function readUint256(RLPItem memory _in) internal pure returns (uint256) {\n        return uint256(readBytes32(_in));\n    }\n\n    /**\n     * Reads an RLP uint256 value into a uint256.\n     * @param _in RLP uint256 value.\n     * @return Decoded uint256.\n     */\n    function readUint256(bytes memory _in) internal pure returns (uint256) {\n        return readUint256(toRLPItem(_in));\n    }\n\n    /**\n     * Reads an RLP bool value into a bool.\n     * @param _in RLP bool value.\n     * @return Decoded bool.\n     */\n    function readBool(RLPItem memory _in) internal pure returns (bool) {\n        require(_in.length == 1, \"Invalid RLP boolean value.\");\n\n        uint256 ptr = _in.ptr;\n        uint256 out;\n        assembly {\n            out := byte(0, mload(ptr))\n        }\n\n        require(out == 0 || out == 1, \"Lib_RLPReader: Invalid RLP boolean value, must be 0 or 1\");\n\n        return out != 0;\n    }\n\n    /**\n     * Reads an RLP bool value into a bool.\n     * @param _in RLP bool value.\n     * @return Decoded bool.\n     */\n    function readBool(bytes memory _in) internal pure returns (bool) {\n        return readBool(toRLPItem(_in));\n    }\n\n    /**\n     * Reads an RLP address value into a address.\n     * @param _in RLP address value.\n     * @return Decoded address.\n     */\n    function readAddress(RLPItem memory _in) internal pure returns (address) {\n        if (_in.length == 1) {\n            return address(0);\n        }\n\n        require(_in.length == 21, \"Invalid RLP address value.\");\n\n        return address(uint160(readUint256(_in)));\n    }\n\n    /**\n     * Reads an RLP address value into a address.\n     * @param _in RLP address value.\n     * @return Decoded address.\n     */\n    function readAddress(bytes memory _in) internal pure returns (address) {\n        return readAddress(toRLPItem(_in));\n    }\n\n    /**\n     * Reads the raw bytes of an RLP item.\n     * @param _in RLP item to read.\n     * @return Raw RLP bytes.\n     */\n    function readRawBytes(RLPItem memory _in) internal pure returns (bytes memory) {\n        return _copy(_in);\n    }\n\n    /*********************\n     * Private Functions *\n     *********************/\n\n    /**\n     * Decodes the length of an RLP item.\n     * @param _in RLP item to decode.\n     * @return Offset of the encoded data.\n     * @return Length of the encoded data.\n     * @return RLP item type (LIST_ITEM or DATA_ITEM).\n     */\n    function _decodeLength(RLPItem memory _in)\n        private\n        pure\n        returns (\n            uint256,\n            uint256,\n            RLPItemType\n        )\n    {\n        require(_in.length > 0, \"RLP item cannot be null.\");\n\n        uint256 ptr = _in.ptr;\n        uint256 prefix;\n        assembly {\n            prefix := byte(0, mload(ptr))\n        }\n\n        if (prefix <= 0x7f) {\n            // Single byte.\n\n            return (0, 1, RLPItemType.DATA_ITEM);\n        } else if (prefix <= 0xb7) {\n            // Short string.\n\n            // slither-disable-next-line variable-scope\n            uint256 strLen = prefix - 0x80;\n\n            require(_in.length > strLen, \"Invalid RLP short string.\");\n\n            return (1, strLen, RLPItemType.DATA_ITEM);\n        } else if (prefix <= 0xbf) {\n            // Long string.\n            uint256 lenOfStrLen = prefix - 0xb7;\n\n            require(_in.length > lenOfStrLen, \"Invalid RLP long string length.\");\n\n            uint256 strLen;\n            assembly {\n                // Pick out the string length.\n                strLen := div(mload(add(ptr, 1)), exp(256, sub(32, lenOfStrLen)))\n            }\n\n            require(_in.length > lenOfStrLen + strLen, \"Invalid RLP long string.\");\n\n            return (1 + lenOfStrLen, strLen, RLPItemType.DATA_ITEM);\n        } else if (prefix <= 0xf7) {\n            // Short list.\n            // slither-disable-next-line variable-scope\n            uint256 listLen = prefix - 0xc0;\n\n            require(_in.length > listLen, \"Invalid RLP short list.\");\n\n            return (1, listLen, RLPItemType.LIST_ITEM);\n        } else {\n            // Long list.\n            uint256 lenOfListLen = prefix - 0xf7;\n\n            require(_in.length > lenOfListLen, \"Invalid RLP long list length.\");\n\n            uint256 listLen;\n            assembly {\n                // Pick out the list length.\n                listLen := div(mload(add(ptr, 1)), exp(256, sub(32, lenOfListLen)))\n            }\n\n            require(_in.length > lenOfListLen + listLen, \"Invalid RLP long list.\");\n\n            return (1 + lenOfListLen, listLen, RLPItemType.LIST_ITEM);\n        }\n    }\n\n    /**\n     * Copies the bytes from a memory location.\n     * @param _src Pointer to the location to read from.\n     * @param _offset Offset to start reading from.\n     * @param _length Number of bytes to read.\n     * @return Copied bytes.\n     */\n    function _copy(\n        uint256 _src,\n        uint256 _offset,\n        uint256 _length\n    ) private pure returns (bytes memory) {\n        bytes memory out = new bytes(_length);\n        if (out.length == 0) {\n            return out;\n        }\n\n        uint256 src = _src + _offset;\n        uint256 dest;\n        assembly {\n            dest := add(out, 32)\n        }\n\n        // Copy over as many complete words as we can.\n        for (uint256 i = 0; i < _length / 32; i++) {\n            assembly {\n                mstore(dest, mload(src))\n            }\n\n            src += 32;\n            dest += 32;\n        }\n\n        // Pick out the remaining bytes.\n        uint256 mask;\n        unchecked {\n            mask = 256**(32 - (_length % 32)) - 1;\n        }\n\n        assembly {\n            mstore(dest, or(and(mload(src), not(mask)), and(mload(dest), mask)))\n        }\n        return out;\n    }\n\n    /**\n     * Copies an RLP item into bytes.\n     * @param _in RLP item to copy.\n     * @return Copied bytes.\n     */\n    function _copy(RLPItem memory _in) private pure returns (bytes memory) {\n        return _copy(_in.ptr, 0, _in.length);\n    }\n}\n"
      },
      "contracts/libraries/utils/Lib_BytesUtils.sol": {
        "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.9;\n\n/**\n * @title Lib_BytesUtils\n */\nlibrary Lib_BytesUtils {\n    /**********************\n     * Internal Functions *\n     **********************/\n\n    function slice(\n        bytes memory _bytes,\n        uint256 _start,\n        uint256 _length\n    ) internal pure returns (bytes memory) {\n        require(_length + 31 >= _length, \"slice_overflow\");\n        require(_start + _length >= _start, \"slice_overflow\");\n        require(_bytes.length >= _start + _length, \"slice_outOfBounds\");\n\n        bytes memory tempBytes;\n\n        assembly {\n            switch iszero(_length)\n            case 0 {\n                // Get a location of some free memory and store it in tempBytes as\n                // Solidity does for memory variables.\n                tempBytes := mload(0x40)\n\n                // The first word of the slice result is potentially a partial\n                // word read from the original array. To read it, we calculate\n                // the length of that partial word and start copying that many\n                // bytes into the array. The first word we copy will start with\n                // data we don't care about, but the last `lengthmod` bytes will\n                // land at the beginning of the contents of the new array. When\n                // we're done copying, we overwrite the full first word with\n                // the actual length of the slice.\n                let lengthmod := and(_length, 31)\n\n                // The multiplication in the next line is necessary\n                // because when slicing multiples of 32 bytes (lengthmod == 0)\n                // the following copy loop was copying the origin's length\n                // and then ending prematurely not copying everything it should.\n                let mc := add(add(tempBytes, lengthmod), mul(0x20, iszero(lengthmod)))\n                let end := add(mc, _length)\n\n                for {\n                    // The multiplication in the next line has the same exact purpose\n                    // as the one above.\n                    let cc := add(add(add(_bytes, lengthmod), mul(0x20, iszero(lengthmod))), _start)\n                } lt(mc, end) {\n                    mc := add(mc, 0x20)\n                    cc := add(cc, 0x20)\n                } {\n                    mstore(mc, mload(cc))\n                }\n\n                mstore(tempBytes, _length)\n\n                //update free-memory pointer\n                //allocating the array padded to 32 bytes like the compiler does now\n                mstore(0x40, and(add(mc, 31), not(31)))\n            }\n            //if we want a zero-length slice let's just return a zero-length array\n            default {\n                tempBytes := mload(0x40)\n\n                //zero out the 32 bytes slice we are about to return\n                //we need to do it because Solidity does not garbage collect\n                mstore(tempBytes, 0)\n\n                mstore(0x40, add(tempBytes, 0x20))\n            }\n        }\n\n        return tempBytes;\n    }\n\n    function slice(bytes memory _bytes, uint256 _start) internal pure returns (bytes memory) {\n        if (_start >= _bytes.length) {\n            return bytes(\"\");\n        }\n\n        return slice(_bytes, _start, _bytes.length - _start);\n    }\n\n    function toBytes32(bytes memory _bytes) internal pure returns (bytes32) {\n        if (_bytes.length < 32) {\n            bytes32 ret;\n            assembly {\n                ret := mload(add(_bytes, 32))\n            }\n            return ret;\n        }\n\n        return abi.decode(_bytes, (bytes32)); // will truncate if input length > 32 bytes\n    }\n\n    function toUint256(bytes memory _bytes) internal pure returns (uint256) {\n        return uint256(toBytes32(_bytes));\n    }\n\n    function toNibbles(bytes memory _bytes) internal pure returns (bytes memory) {\n        bytes memory nibbles = new bytes(_bytes.length * 2);\n\n        for (uint256 i = 0; i < _bytes.length; i++) {\n            nibbles[i * 2] = _bytes[i] >> 4;\n            nibbles[i * 2 + 1] = bytes1(uint8(_bytes[i]) % 16);\n        }\n\n        return nibbles;\n    }\n\n    function fromNibbles(bytes memory _bytes) internal pure returns (bytes memory) {\n        bytes memory ret = new bytes(_bytes.length / 2);\n\n        for (uint256 i = 0; i < ret.length; i++) {\n            ret[i] = (_bytes[i * 2] << 4) | (_bytes[i * 2 + 1]);\n        }\n\n        return ret;\n    }\n\n    function equal(bytes memory _bytes, bytes memory _other) internal pure returns (bool) {\n        return keccak256(_bytes) == keccak256(_other);\n    }\n}\n"
      },
      "contracts/libraries/utils/Lib_Bytes32Utils.sol": {
        "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.9;\n\n/**\n * @title Lib_Byte32Utils\n */\nlibrary Lib_Bytes32Utils {\n    /**********************\n     * Internal Functions *\n     **********************/\n\n    /**\n     * Converts a bytes32 value to a boolean. Anything non-zero will be converted to \"true.\"\n     * @param _in Input bytes32 value.\n     * @return Bytes32 as a boolean.\n     */\n    function toBool(bytes32 _in) internal pure returns (bool) {\n        return _in != 0;\n    }\n\n    /**\n     * Converts a boolean to a bytes32 value.\n     * @param _in Input boolean value.\n     * @return Boolean as a bytes32.\n     */\n    function fromBool(bool _in) internal pure returns (bytes32) {\n        return bytes32(uint256(_in ? 1 : 0));\n    }\n\n    /**\n     * Converts a bytes32 value to an address. Takes the *last* 20 bytes.\n     * @param _in Input bytes32 value.\n     * @return Bytes32 as an address.\n     */\n    function toAddress(bytes32 _in) internal pure returns (address) {\n        return address(uint160(uint256(_in)));\n    }\n\n    /**\n     * Converts an address to a bytes32.\n     * @param _in Input address value.\n     * @return Address as a bytes32.\n     */\n    function fromAddress(address _in) internal pure returns (bytes32) {\n        return bytes32(uint256(uint160(_in)));\n    }\n}\n"
      },
      "contracts/libraries/trie/Lib_MerkleTrie.sol": {
        "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.9;\n\n/* Library Imports */\nimport { Lib_BytesUtils } from \"../utils/Lib_BytesUtils.sol\";\nimport { Lib_RLPReader } from \"../rlp/Lib_RLPReader.sol\";\nimport { Lib_RLPWriter } from \"../rlp/Lib_RLPWriter.sol\";\n\n/**\n * @title Lib_MerkleTrie\n */\nlibrary Lib_MerkleTrie {\n    /*******************\n     * Data Structures *\n     *******************/\n\n    enum NodeType {\n        BranchNode,\n        ExtensionNode,\n        LeafNode\n    }\n\n    struct TrieNode {\n        bytes encoded;\n        Lib_RLPReader.RLPItem[] decoded;\n    }\n\n    /**********************\n     * Contract Constants *\n     **********************/\n\n    // TREE_RADIX determines the number of elements per branch node.\n    uint256 constant TREE_RADIX = 16;\n    // Branch nodes have TREE_RADIX elements plus an additional `value` slot.\n    uint256 constant BRANCH_NODE_LENGTH = TREE_RADIX + 1;\n    // Leaf nodes and extension nodes always have two elements, a `path` and a `value`.\n    uint256 constant LEAF_OR_EXTENSION_NODE_LENGTH = 2;\n\n    // Prefixes are prepended to the `path` within a leaf or extension node and\n    // allow us to differentiate between the two node types. `ODD` or `EVEN` is\n    // determined by the number of nibbles within the unprefixed `path`. If the\n    // number of nibbles if even, we need to insert an extra padding nibble so\n    // the resulting prefixed `path` has an even number of nibbles.\n    uint8 constant PREFIX_EXTENSION_EVEN = 0;\n    uint8 constant PREFIX_EXTENSION_ODD = 1;\n    uint8 constant PREFIX_LEAF_EVEN = 2;\n    uint8 constant PREFIX_LEAF_ODD = 3;\n\n    // Just a utility constant. RLP represents `NULL` as 0x80.\n    bytes1 constant RLP_NULL = bytes1(0x80);\n\n    /**********************\n     * Internal Functions *\n     **********************/\n\n    /**\n     * @notice Verifies a proof that a given key/value pair is present in the\n     * Merkle trie.\n     * @param _key Key of the node to search for, as a hex string.\n     * @param _value Value of the node to search for, as a hex string.\n     * @param _proof Merkle trie inclusion proof for the desired node. Unlike\n     * traditional Merkle trees, this proof is executed top-down and consists\n     * of a list of RLP-encoded nodes that make a path down to the target node.\n     * @param _root Known root of the Merkle trie. Used to verify that the\n     * included proof is correctly constructed.\n     * @return _verified `true` if the k/v pair exists in the trie, `false` otherwise.\n     */\n    function verifyInclusionProof(\n        bytes memory _key,\n        bytes memory _value,\n        bytes memory _proof,\n        bytes32 _root\n    ) internal pure returns (bool _verified) {\n        (bool exists, bytes memory value) = get(_key, _proof, _root);\n\n        return (exists && Lib_BytesUtils.equal(_value, value));\n    }\n\n    /**\n     * @notice Retrieves the value associated with a given key.\n     * @param _key Key to search for, as hex bytes.\n     * @param _proof Merkle trie inclusion proof for the key.\n     * @param _root Known root of the Merkle trie.\n     * @return _exists Whether or not the key exists.\n     * @return _value Value of the key if it exists.\n     */\n    function get(\n        bytes memory _key,\n        bytes memory _proof,\n        bytes32 _root\n    ) internal pure returns (bool _exists, bytes memory _value) {\n        TrieNode[] memory proof = _parseProof(_proof);\n        (uint256 pathLength, bytes memory keyRemainder, bool isFinalNode) = _walkNodePath(\n            proof,\n            _key,\n            _root\n        );\n\n        bool exists = keyRemainder.length == 0;\n\n        require(exists || isFinalNode, \"Provided proof is invalid.\");\n\n        bytes memory value = exists ? _getNodeValue(proof[pathLength - 1]) : bytes(\"\");\n\n        return (exists, value);\n    }\n\n    /*********************\n     * Private Functions *\n     *********************/\n\n    /**\n     * @notice Walks through a proof using a provided key.\n     * @param _proof Inclusion proof to walk through.\n     * @param _key Key to use for the walk.\n     * @param _root Known root of the trie.\n     * @return _pathLength Length of the final path\n     * @return _keyRemainder Portion of the key remaining after the walk.\n     * @return _isFinalNode Whether or not we've hit a dead end.\n     */\n    function _walkNodePath(\n        TrieNode[] memory _proof,\n        bytes memory _key,\n        bytes32 _root\n    )\n        private\n        pure\n        returns (\n            uint256 _pathLength,\n            bytes memory _keyRemainder,\n            bool _isFinalNode\n        )\n    {\n        uint256 pathLength = 0;\n        bytes memory key = Lib_BytesUtils.toNibbles(_key);\n\n        bytes32 currentNodeID = _root;\n        uint256 currentKeyIndex = 0;\n        uint256 currentKeyIncrement = 0;\n        TrieNode memory currentNode;\n\n        // Proof is top-down, so we start at the first element (root).\n        for (uint256 i = 0; i < _proof.length; i++) {\n            currentNode = _proof[i];\n            currentKeyIndex += currentKeyIncrement;\n\n            // Keep track of the proof elements we actually need.\n            // It's expensive to resize arrays, so this simply reduces gas costs.\n            pathLength += 1;\n\n            if (currentKeyIndex == 0) {\n                // First proof element is always the root node.\n                require(keccak256(currentNode.encoded) == currentNodeID, \"Invalid root hash\");\n            } else if (currentNode.encoded.length >= 32) {\n                // Nodes 32 bytes or larger are hashed inside branch nodes.\n                require(\n                    keccak256(currentNode.encoded) == currentNodeID,\n                    \"Invalid large internal hash\"\n                );\n            } else {\n                // Nodes smaller than 31 bytes aren't hashed.\n                require(\n                    Lib_BytesUtils.toBytes32(currentNode.encoded) == currentNodeID,\n                    \"Invalid internal node hash\"\n                );\n            }\n\n            if (currentNode.decoded.length == BRANCH_NODE_LENGTH) {\n                if (currentKeyIndex == key.length) {\n                    // We've hit the end of the key\n                    // meaning the value should be within this branch node.\n                    break;\n                } else {\n                    // We're not at the end of the key yet.\n                    // Figure out what the next node ID should be and continue.\n                    uint8 branchKey = uint8(key[currentKeyIndex]);\n                    Lib_RLPReader.RLPItem memory nextNode = currentNode.decoded[branchKey];\n                    currentNodeID = _getNodeID(nextNode);\n                    currentKeyIncrement = 1;\n                    continue;\n                }\n            } else if (currentNode.decoded.length == LEAF_OR_EXTENSION_NODE_LENGTH) {\n                bytes memory path = _getNodePath(currentNode);\n                uint8 prefix = uint8(path[0]);\n                uint8 offset = 2 - (prefix % 2);\n                bytes memory pathRemainder = Lib_BytesUtils.slice(path, offset);\n                bytes memory keyRemainder = Lib_BytesUtils.slice(key, currentKeyIndex);\n                uint256 sharedNibbleLength = _getSharedNibbleLength(pathRemainder, keyRemainder);\n\n                if (prefix == PREFIX_LEAF_EVEN || prefix == PREFIX_LEAF_ODD) {\n                    if (\n                        pathRemainder.length == sharedNibbleLength &&\n                        keyRemainder.length == sharedNibbleLength\n                    ) {\n                        // The key within this leaf matches our key exactly.\n                        // Increment the key index to reflect that we have no remainder.\n                        currentKeyIndex += sharedNibbleLength;\n                    }\n\n                    // We've hit a leaf node, so our next node should be NULL.\n                    currentNodeID = bytes32(RLP_NULL);\n                    break;\n                } else if (prefix == PREFIX_EXTENSION_EVEN || prefix == PREFIX_EXTENSION_ODD) {\n                    if (sharedNibbleLength != pathRemainder.length) {\n                        // Our extension node is not identical to the remainder.\n                        // We've hit the end of this path\n                        // updates will need to modify this extension.\n                        currentNodeID = bytes32(RLP_NULL);\n                        break;\n                    } else {\n                        // Our extension shares some nibbles.\n                        // Carry on to the next node.\n                        currentNodeID = _getNodeID(currentNode.decoded[1]);\n                        currentKeyIncrement = sharedNibbleLength;\n                        continue;\n                    }\n                } else {\n                    revert(\"Received a node with an unknown prefix\");\n                }\n            } else {\n                revert(\"Received an unparseable node.\");\n            }\n        }\n\n        // If our node ID is NULL, then we're at a dead end.\n        bool isFinalNode = currentNodeID == bytes32(RLP_NULL);\n        return (pathLength, Lib_BytesUtils.slice(key, currentKeyIndex), isFinalNode);\n    }\n\n    /**\n     * @notice Parses an RLP-encoded proof into something more useful.\n     * @param _proof RLP-encoded proof to parse.\n     * @return _parsed Proof parsed into easily accessible structs.\n     */\n    function _parseProof(bytes memory _proof) private pure returns (TrieNode[] memory _parsed) {\n        Lib_RLPReader.RLPItem[] memory nodes = Lib_RLPReader.readList(_proof);\n        TrieNode[] memory proof = new TrieNode[](nodes.length);\n\n        for (uint256 i = 0; i < nodes.length; i++) {\n            bytes memory encoded = Lib_RLPReader.readBytes(nodes[i]);\n            proof[i] = TrieNode({ encoded: encoded, decoded: Lib_RLPReader.readList(encoded) });\n        }\n\n        return proof;\n    }\n\n    /**\n     * @notice Picks out the ID for a node. Node ID is referred to as the\n     * \"hash\" within the specification, but nodes < 32 bytes are not actually\n     * hashed.\n     * @param _node Node to pull an ID for.\n     * @return _nodeID ID for the node, depending on the size of its contents.\n     */\n    function _getNodeID(Lib_RLPReader.RLPItem memory _node) private pure returns (bytes32 _nodeID) {\n        bytes memory nodeID;\n\n        if (_node.length < 32) {\n            // Nodes smaller than 32 bytes are RLP encoded.\n            nodeID = Lib_RLPReader.readRawBytes(_node);\n        } else {\n            // Nodes 32 bytes or larger are hashed.\n            nodeID = Lib_RLPReader.readBytes(_node);\n        }\n\n        return Lib_BytesUtils.toBytes32(nodeID);\n    }\n\n    /**\n     * @notice Gets the path for a leaf or extension node.\n     * @param _node Node to get a path for.\n     * @return _path Node path, converted to an array of nibbles.\n     */\n    function _getNodePath(TrieNode memory _node) private pure returns (bytes memory _path) {\n        return Lib_BytesUtils.toNibbles(Lib_RLPReader.readBytes(_node.decoded[0]));\n    }\n\n    /**\n     * @notice Gets the path for a node.\n     * @param _node Node to get a value for.\n     * @return _value Node value, as hex bytes.\n     */\n    function _getNodeValue(TrieNode memory _node) private pure returns (bytes memory _value) {\n        return Lib_RLPReader.readBytes(_node.decoded[_node.decoded.length - 1]);\n    }\n\n    /**\n     * @notice Utility; determines the number of nibbles shared between two\n     * nibble arrays.\n     * @param _a First nibble array.\n     * @param _b Second nibble array.\n     * @return _shared Number of shared nibbles.\n     */\n    function _getSharedNibbleLength(bytes memory _a, bytes memory _b)\n        private\n        pure\n        returns (uint256 _shared)\n    {\n        uint256 i = 0;\n        while (_a.length > i && _b.length > i && _a[i] == _b[i]) {\n            i++;\n        }\n        return i;\n    }\n}\n"
      },
      "@openzeppelin/contracts/utils/cryptography/ECDSA.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.8.0) (utils/cryptography/ECDSA.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../Strings.sol\";\n\n/**\n * @dev Elliptic Curve Digital Signature Algorithm (ECDSA) operations.\n *\n * These functions can be used to verify that a message was signed by the holder\n * of the private keys of a given address.\n */\nlibrary ECDSA {\n    enum RecoverError {\n        NoError,\n        InvalidSignature,\n        InvalidSignatureLength,\n        InvalidSignatureS,\n        InvalidSignatureV // Deprecated in v4.8\n    }\n\n    function _throwError(RecoverError error) private pure {\n        if (error == RecoverError.NoError) {\n            return; // no error: do nothing\n        } else if (error == RecoverError.InvalidSignature) {\n            revert(\"ECDSA: invalid signature\");\n        } else if (error == RecoverError.InvalidSignatureLength) {\n            revert(\"ECDSA: invalid signature length\");\n        } else if (error == RecoverError.InvalidSignatureS) {\n            revert(\"ECDSA: invalid signature 's' value\");\n        }\n    }\n\n    /**\n     * @dev Returns the address that signed a hashed message (`hash`) with\n     * `signature` or error string. This address can then be used for verification purposes.\n     *\n     * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n     * this function rejects them by requiring the `s` value to be in the lower\n     * half order, and the `v` value to be either 27 or 28.\n     *\n     * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n     * verification to be secure: it is possible to craft signatures that\n     * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n     * this is by receiving a hash of the original message (which may otherwise\n     * be too long), and then calling {toEthSignedMessageHash} on it.\n     *\n     * Documentation for signature generation:\n     * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n     * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n     *\n     * _Available since v4.3._\n     */\n    function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n        if (signature.length == 65) {\n            bytes32 r;\n            bytes32 s;\n            uint8 v;\n            // ecrecover takes the signature parameters, and the only way to get them\n            // currently is to use assembly.\n            /// @solidity memory-safe-assembly\n            assembly {\n                r := mload(add(signature, 0x20))\n                s := mload(add(signature, 0x40))\n                v := byte(0, mload(add(signature, 0x60)))\n            }\n            return tryRecover(hash, v, r, s);\n        } else {\n            return (address(0), RecoverError.InvalidSignatureLength);\n        }\n    }\n\n    /**\n     * @dev Returns the address that signed a hashed message (`hash`) with\n     * `signature`. This address can then be used for verification purposes.\n     *\n     * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n     * this function rejects them by requiring the `s` value to be in the lower\n     * half order, and the `v` value to be either 27 or 28.\n     *\n     * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n     * verification to be secure: it is possible to craft signatures that\n     * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n     * this is by receiving a hash of the original message (which may otherwise\n     * be too long), and then calling {toEthSignedMessageHash} on it.\n     */\n    function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n        (address recovered, RecoverError error) = tryRecover(hash, signature);\n        _throwError(error);\n        return recovered;\n    }\n\n    /**\n     * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n     *\n     * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n     *\n     * _Available since v4.3._\n     */\n    function tryRecover(\n        bytes32 hash,\n        bytes32 r,\n        bytes32 vs\n    ) internal pure returns (address, RecoverError) {\n        bytes32 s = vs & bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n        uint8 v = uint8((uint256(vs) >> 255) + 27);\n        return tryRecover(hash, v, r, s);\n    }\n\n    /**\n     * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n     *\n     * _Available since v4.2._\n     */\n    function recover(\n        bytes32 hash,\n        bytes32 r,\n        bytes32 vs\n    ) internal pure returns (address) {\n        (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n        _throwError(error);\n        return recovered;\n    }\n\n    /**\n     * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n     * `r` and `s` signature fields separately.\n     *\n     * _Available since v4.3._\n     */\n    function tryRecover(\n        bytes32 hash,\n        uint8 v,\n        bytes32 r,\n        bytes32 s\n    ) internal pure returns (address, RecoverError) {\n        // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n        // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n        // the valid range for s in (301): 0 < s < secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n        // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n        //\n        // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n        // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n        // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n        // these malleable signatures as well.\n        if (uint256(s) > 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n            return (address(0), RecoverError.InvalidSignatureS);\n        }\n\n        // If the signature is valid (and not malleable), return the signer address\n        address signer = ecrecover(hash, v, r, s);\n        if (signer == address(0)) {\n            return (address(0), RecoverError.InvalidSignature);\n        }\n\n        return (signer, RecoverError.NoError);\n    }\n\n    /**\n     * @dev Overload of {ECDSA-recover} that receives the `v`,\n     * `r` and `s` signature fields separately.\n     */\n    function recover(\n        bytes32 hash,\n        uint8 v,\n        bytes32 r,\n        bytes32 s\n    ) internal pure returns (address) {\n        (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n        _throwError(error);\n        return recovered;\n    }\n\n    /**\n     * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n     * produces hash corresponding to the one signed with the\n     * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n     * JSON-RPC method as part of EIP-191.\n     *\n     * See {recover}.\n     */\n    function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\n        // 32 is the length in bytes of hash,\n        // enforced by the type signature above\n        return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n32\", hash));\n    }\n\n    /**\n     * @dev Returns an Ethereum Signed Message, created from `s`. This\n     * produces hash corresponding to the one signed with the\n     * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n     * JSON-RPC method as part of EIP-191.\n     *\n     * See {recover}.\n     */\n    function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n        return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", Strings.toString(s.length), s));\n    }\n\n    /**\n     * @dev Returns an Ethereum Signed Typed Data, created from a\n     * `domainSeparator` and a `structHash`. This produces hash corresponding\n     * to the one signed with the\n     * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n     * JSON-RPC method as part of EIP-712.\n     *\n     * See {recover}.\n     */\n    function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\n        return keccak256(abi.encodePacked(\"\\x19\\x01\", domainSeparator, structHash));\n    }\n}\n"
      },
      "@openzeppelin/contracts/utils/Strings.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.8.0) (utils/Strings.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./math/Math.sol\";\n\n/**\n * @dev String operations.\n */\nlibrary Strings {\n    bytes16 private constant _SYMBOLS = \"0123456789abcdef\";\n    uint8 private constant _ADDRESS_LENGTH = 20;\n\n    /**\n     * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n     */\n    function toString(uint256 value) internal pure returns (string memory) {\n        unchecked {\n            uint256 length = Math.log10(value) + 1;\n            string memory buffer = new string(length);\n            uint256 ptr;\n            /// @solidity memory-safe-assembly\n            assembly {\n                ptr := add(buffer, add(32, length))\n            }\n            while (true) {\n                ptr--;\n                /// @solidity memory-safe-assembly\n                assembly {\n                    mstore8(ptr, byte(mod(value, 10), _SYMBOLS))\n                }\n                value /= 10;\n                if (value == 0) break;\n            }\n            return buffer;\n        }\n    }\n\n    /**\n     * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n     */\n    function toHexString(uint256 value) internal pure returns (string memory) {\n        unchecked {\n            return toHexString(value, Math.log256(value) + 1);\n        }\n    }\n\n    /**\n     * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n     */\n    function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n        bytes memory buffer = new bytes(2 * length + 2);\n        buffer[0] = \"0\";\n        buffer[1] = \"x\";\n        for (uint256 i = 2 * length + 1; i > 1; --i) {\n            buffer[i] = _SYMBOLS[value & 0xf];\n            value >>= 4;\n        }\n        require(value == 0, \"Strings: hex length insufficient\");\n        return string(buffer);\n    }\n\n    /**\n     * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation.\n     */\n    function toHexString(address addr) internal pure returns (string memory) {\n        return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);\n    }\n}\n"
      },
      "@openzeppelin/contracts/utils/math/Math.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.8.0) (utils/math/Math.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Standard math utilities missing in the Solidity language.\n */\nlibrary Math {\n    enum Rounding {\n        Down, // Toward negative infinity\n        Up, // Toward infinity\n        Zero // Toward zero\n    }\n\n    /**\n     * @dev Returns the largest of two numbers.\n     */\n    function max(uint256 a, uint256 b) internal pure returns (uint256) {\n        return a > b ? a : b;\n    }\n\n    /**\n     * @dev Returns the smallest of two numbers.\n     */\n    function min(uint256 a, uint256 b) internal pure returns (uint256) {\n        return a < b ? a : b;\n    }\n\n    /**\n     * @dev Returns the average of two numbers. The result is rounded towards\n     * zero.\n     */\n    function average(uint256 a, uint256 b) internal pure returns (uint256) {\n        // (a + b) / 2 can overflow.\n        return (a & b) + (a ^ b) / 2;\n    }\n\n    /**\n     * @dev Returns the ceiling of the division of two numbers.\n     *\n     * This differs from standard division with `/` in that it rounds up instead\n     * of rounding down.\n     */\n    function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) {\n        // (a + b - 1) / b can overflow on addition, so we distribute.\n        return a == 0 ? 0 : (a - 1) / b + 1;\n    }\n\n    /**\n     * @notice Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or denominator == 0\n     * @dev Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv)\n     * with further edits by Uniswap Labs also under MIT license.\n     */\n    function mulDiv(\n        uint256 x,\n        uint256 y,\n        uint256 denominator\n    ) internal pure returns (uint256 result) {\n        unchecked {\n            // 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use\n            // use the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256\n            // variables such that product = prod1 * 2^256 + prod0.\n            uint256 prod0; // Least significant 256 bits of the product\n            uint256 prod1; // Most significant 256 bits of the product\n            assembly {\n                let mm := mulmod(x, y, not(0))\n                prod0 := mul(x, y)\n                prod1 := sub(sub(mm, prod0), lt(mm, prod0))\n            }\n\n            // Handle non-overflow cases, 256 by 256 division.\n            if (prod1 == 0) {\n                return prod0 / denominator;\n            }\n\n            // Make sure the result is less than 2^256. Also prevents denominator == 0.\n            require(denominator > prod1);\n\n            ///////////////////////////////////////////////\n            // 512 by 256 division.\n            ///////////////////////////////////////////////\n\n            // Make division exact by subtracting the remainder from [prod1 prod0].\n            uint256 remainder;\n            assembly {\n                // Compute remainder using mulmod.\n                remainder := mulmod(x, y, denominator)\n\n                // Subtract 256 bit number from 512 bit number.\n                prod1 := sub(prod1, gt(remainder, prod0))\n                prod0 := sub(prod0, remainder)\n            }\n\n            // Factor powers of two out of denominator and compute largest power of two divisor of denominator. Always >= 1.\n            // See https://cs.stackexchange.com/q/138556/92363.\n\n            // Does not overflow because the denominator cannot be zero at this stage in the function.\n            uint256 twos = denominator & (~denominator + 1);\n            assembly {\n                // Divide denominator by twos.\n                denominator := div(denominator, twos)\n\n                // Divide [prod1 prod0] by twos.\n                prod0 := div(prod0, twos)\n\n                // Flip twos such that it is 2^256 / twos. If twos is zero, then it becomes one.\n                twos := add(div(sub(0, twos), twos), 1)\n            }\n\n            // Shift in bits from prod1 into prod0.\n            prod0 |= prod1 * twos;\n\n            // Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such\n            // that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for\n            // four bits. That is, denominator * inv = 1 mod 2^4.\n            uint256 inverse = (3 * denominator) ^ 2;\n\n            // Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also works\n            // in modular arithmetic, doubling the correct bits in each step.\n            inverse *= 2 - denominator * inverse; // inverse mod 2^8\n            inverse *= 2 - denominator * inverse; // inverse mod 2^16\n            inverse *= 2 - denominator * inverse; // inverse mod 2^32\n            inverse *= 2 - denominator * inverse; // inverse mod 2^64\n            inverse *= 2 - denominator * inverse; // inverse mod 2^128\n            inverse *= 2 - denominator * inverse; // inverse mod 2^256\n\n            // Because the division is now exact we can divide by multiplying with the modular inverse of denominator.\n            // This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is\n            // less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1\n            // is no longer required.\n            result = prod0 * inverse;\n            return result;\n        }\n    }\n\n    /**\n     * @notice Calculates x * y / denominator with full precision, following the selected rounding direction.\n     */\n    function mulDiv(\n        uint256 x,\n        uint256 y,\n        uint256 denominator,\n        Rounding rounding\n    ) internal pure returns (uint256) {\n        uint256 result = mulDiv(x, y, denominator);\n        if (rounding == Rounding.Up && mulmod(x, y, denominator) > 0) {\n            result += 1;\n        }\n        return result;\n    }\n\n    /**\n     * @dev Returns the square root of a number. If the number is not a perfect square, the value is rounded down.\n     *\n     * Inspired by Henry S. Warren, Jr.'s \"Hacker's Delight\" (Chapter 11).\n     */\n    function sqrt(uint256 a) internal pure returns (uint256) {\n        if (a == 0) {\n            return 0;\n        }\n\n        // For our first guess, we get the biggest power of 2 which is smaller than the square root of the target.\n        //\n        // We know that the \"msb\" (most significant bit) of our target number `a` is a power of 2 such that we have\n        // `msb(a) <= a < 2*msb(a)`. This value can be written `msb(a)=2**k` with `k=log2(a)`.\n        //\n        // This can be rewritten `2**log2(a) <= a < 2**(log2(a) + 1)`\n        // → `sqrt(2**k) <= sqrt(a) < sqrt(2**(k+1))`\n        // → `2**(k/2) <= sqrt(a) < 2**((k+1)/2) <= 2**(k/2 + 1)`\n        //\n        // Consequently, `2**(log2(a) / 2)` is a good first approximation of `sqrt(a)` with at least 1 correct bit.\n        uint256 result = 1 << (log2(a) >> 1);\n\n        // At this point `result` is an estimation with one bit of precision. We know the true value is a uint128,\n        // since it is the square root of a uint256. Newton's method converges quadratically (precision doubles at\n        // every iteration). We thus need at most 7 iteration to turn our partial result with one bit of precision\n        // into the expected uint128 result.\n        unchecked {\n            result = (result + a / result) >> 1;\n            result = (result + a / result) >> 1;\n            result = (result + a / result) >> 1;\n            result = (result + a / result) >> 1;\n            result = (result + a / result) >> 1;\n            result = (result + a / result) >> 1;\n            result = (result + a / result) >> 1;\n            return min(result, a / result);\n        }\n    }\n\n    /**\n     * @notice Calculates sqrt(a), following the selected rounding direction.\n     */\n    function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) {\n        unchecked {\n            uint256 result = sqrt(a);\n            return result + (rounding == Rounding.Up && result * result < a ? 1 : 0);\n        }\n    }\n\n    /**\n     * @dev Return the log in base 2, rounded down, of a positive value.\n     * Returns 0 if given 0.\n     */\n    function log2(uint256 value) internal pure returns (uint256) {\n        uint256 result = 0;\n        unchecked {\n            if (value >> 128 > 0) {\n                value >>= 128;\n                result += 128;\n            }\n            if (value >> 64 > 0) {\n                value >>= 64;\n                result += 64;\n            }\n            if (value >> 32 > 0) {\n                value >>= 32;\n                result += 32;\n            }\n            if (value >> 16 > 0) {\n                value >>= 16;\n                result += 16;\n            }\n            if (value >> 8 > 0) {\n                value >>= 8;\n                result += 8;\n            }\n            if (value >> 4 > 0) {\n                value >>= 4;\n                result += 4;\n            }\n            if (value >> 2 > 0) {\n                value >>= 2;\n                result += 2;\n            }\n            if (value >> 1 > 0) {\n                result += 1;\n            }\n        }\n        return result;\n    }\n\n    /**\n     * @dev Return the log in base 2, following the selected rounding direction, of a positive value.\n     * Returns 0 if given 0.\n     */\n    function log2(uint256 value, Rounding rounding) internal pure returns (uint256) {\n        unchecked {\n            uint256 result = log2(value);\n            return result + (rounding == Rounding.Up && 1 << result < value ? 1 : 0);\n        }\n    }\n\n    /**\n     * @dev Return the log in base 10, rounded down, of a positive value.\n     * Returns 0 if given 0.\n     */\n    function log10(uint256 value) internal pure returns (uint256) {\n        uint256 result = 0;\n        unchecked {\n            if (value >= 10**64) {\n                value /= 10**64;\n                result += 64;\n            }\n            if (value >= 10**32) {\n                value /= 10**32;\n                result += 32;\n            }\n            if (value >= 10**16) {\n                value /= 10**16;\n                result += 16;\n            }\n            if (value >= 10**8) {\n                value /= 10**8;\n                result += 8;\n            }\n            if (value >= 10**4) {\n                value /= 10**4;\n                result += 4;\n            }\n            if (value >= 10**2) {\n                value /= 10**2;\n                result += 2;\n            }\n            if (value >= 10**1) {\n                result += 1;\n            }\n        }\n        return result;\n    }\n\n    /**\n     * @dev Return the log in base 10, following the selected rounding direction, of a positive value.\n     * Returns 0 if given 0.\n     */\n    function log10(uint256 value, Rounding rounding) internal pure returns (uint256) {\n        unchecked {\n            uint256 result = log10(value);\n            return result + (rounding == Rounding.Up && 10**result < value ? 1 : 0);\n        }\n    }\n\n    /**\n     * @dev Return the log in base 256, rounded down, of a positive value.\n     * Returns 0 if given 0.\n     *\n     * Adding one to the result gives the number of pairs of hex symbols needed to represent `value` as a hex string.\n     */\n    function log256(uint256 value) internal pure returns (uint256) {\n        uint256 result = 0;\n        unchecked {\n            if (value >> 128 > 0) {\n                value >>= 128;\n                result += 16;\n            }\n            if (value >> 64 > 0) {\n                value >>= 64;\n                result += 8;\n            }\n            if (value >> 32 > 0) {\n                value >>= 32;\n                result += 4;\n            }\n            if (value >> 16 > 0) {\n                value >>= 16;\n                result += 2;\n            }\n            if (value >> 8 > 0) {\n                result += 1;\n            }\n        }\n        return result;\n    }\n\n    /**\n     * @dev Return the log in base 10, following the selected rounding direction, of a positive value.\n     * Returns 0 if given 0.\n     */\n    function log256(uint256 value, Rounding rounding) internal pure returns (uint256) {\n        unchecked {\n            uint256 result = log256(value);\n            return result + (rounding == Rounding.Up && 1 << (result * 8) < value ? 1 : 0);\n        }\n    }\n}\n"
      },
      "contracts/libraries/bridge/ICrossDomainMessenger.sol": {
        "content": "// SPDX-License-Identifier: MIT\npragma solidity >0.5.0 <0.9.0;\n\n/**\n * @title ICrossDomainMessenger\n */\ninterface ICrossDomainMessenger {\n    /**********\n     * Events *\n     **********/\n\n    event SentMessage(\n        address indexed target,\n        address sender,\n        bytes message,\n        uint256 messageNonce,\n        uint256 gasLimit\n    );\n    event RelayedMessage(bytes32 indexed msgHash);\n    event FailedRelayedMessage(bytes32 indexed msgHash);\n\n    /*************\n     * Variables *\n     *************/\n\n    function xDomainMessageSender() external view returns (address);\n\n    /********************\n     * Public Functions *\n     ********************/\n\n    /**\n     * Sends a cross domain message to the target messenger.\n     * @param _target Target contract address.\n     * @param _message Message to send to the target.\n     * @param _gasLimit Gas limit for the provided message.\n     */\n    function sendMessage(\n        address _target,\n        bytes calldata _message,\n        uint32 _gasLimit\n    ) external;\n}\n"
      },
      "@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n\npragma solidity ^0.8.0;\nimport \"../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n    function __Context_init() internal onlyInitializing {\n    }\n\n    function __Context_init_unchained() internal onlyInitializing {\n    }\n    function _msgSender() internal view virtual returns (address) {\n        return msg.sender;\n    }\n\n    function _msgData() internal view virtual returns (bytes calldata) {\n        return msg.data;\n    }\n\n    /**\n     * @dev This empty reserved space is put in place to allow future versions to add new\n     * variables without shifting down storage in the inheritance chain.\n     * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n     */\n    uint256[50] private __gap;\n}\n"
      },
      "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (proxy/utils/Initializable.sol)\n\npragma solidity ^0.8.2;\n\nimport \"../../utils/AddressUpgradeable.sol\";\n\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * contract MyToken is ERC20Upgradeable {\n *     function initialize() initializer public {\n *         __ERC20_init(\"MyToken\", \"MTK\");\n *     }\n * }\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n *     function initializeV2() reinitializer(2) public {\n *         __ERC20Permit_init(\"MyToken\");\n *     }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n *     _disableInitializers();\n * }\n * ```\n * ====\n */\nabstract contract Initializable {\n    /**\n     * @dev Indicates that the contract has been initialized.\n     * @custom:oz-retyped-from bool\n     */\n    uint8 private _initialized;\n\n    /**\n     * @dev Indicates that the contract is in the process of being initialized.\n     */\n    bool private _initializing;\n\n    /**\n     * @dev Triggered when the contract has been initialized or reinitialized.\n     */\n    event Initialized(uint8 version);\n\n    /**\n     * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n     * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\n     */\n    modifier initializer() {\n        bool isTopLevelCall = !_initializing;\n        require(\n            (isTopLevelCall && _initialized < 1) || (!AddressUpgradeable.isContract(address(this)) && _initialized == 1),\n            \"Initializable: contract is already initialized\"\n        );\n        _initialized = 1;\n        if (isTopLevelCall) {\n            _initializing = true;\n        }\n        _;\n        if (isTopLevelCall) {\n            _initializing = false;\n            emit Initialized(1);\n        }\n    }\n\n    /**\n     * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n     * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n     * used to initialize parent contracts.\n     *\n     * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\n     * initialization step. This is essential to configure modules that are added through upgrades and that require\n     * initialization.\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    modifier reinitializer(uint8 version) {\n        require(!_initializing && _initialized < version, \"Initializable: contract is already initialized\");\n        _initialized = version;\n        _initializing = true;\n        _;\n        _initializing = false;\n        emit Initialized(version);\n    }\n\n    /**\n     * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n     * {initializer} and {reinitializer} modifiers, directly or indirectly.\n     */\n    modifier onlyInitializing() {\n        require(_initializing, \"Initializable: contract is not initializing\");\n        _;\n    }\n\n    /**\n     * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n     * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n     * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n     * through proxies.\n     */\n    function _disableInitializers() internal virtual {\n        require(!_initializing, \"Initializable: contract is initializing\");\n        if (_initialized < type(uint8).max) {\n            _initialized = type(uint8).max;\n            emit Initialized(type(uint8).max);\n        }\n    }\n}\n"
      },
      "@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Address.sol)\n\npragma solidity ^0.8.1;\n\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\n    /**\n     * @dev Returns true if `account` is a contract.\n     *\n     * [IMPORTANT]\n     * ====\n     * It is unsafe to assume that an address for which this function returns\n     * false is an externally-owned account (EOA) and not a contract.\n     *\n     * Among others, `isContract` will return false for the following\n     * types of addresses:\n     *\n     *  - an externally-owned account\n     *  - a contract in construction\n     *  - an address where a contract will be created\n     *  - an address where a contract lived, but was destroyed\n     * ====\n     *\n     * [IMPORTANT]\n     * ====\n     * You shouldn't rely on `isContract` to protect against flash loan attacks!\n     *\n     * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n     * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n     * constructor.\n     * ====\n     */\n    function isContract(address account) internal view returns (bool) {\n        // This method relies on extcodesize/address.code.length, which returns 0\n        // for contracts in construction, since the code is only stored at the end\n        // of the constructor execution.\n\n        return account.code.length > 0;\n    }\n\n    /**\n     * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n     * `recipient`, forwarding all available gas and reverting on errors.\n     *\n     * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n     * of certain opcodes, possibly making contracts go over the 2300 gas limit\n     * imposed by `transfer`, making them unable to receive funds via\n     * `transfer`. {sendValue} removes this limitation.\n     *\n     * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n     *\n     * IMPORTANT: because control is transferred to `recipient`, care must be\n     * taken to not create reentrancy vulnerabilities. Consider using\n     * {ReentrancyGuard} or the\n     * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n     */\n    function sendValue(address payable recipient, uint256 amount) internal {\n        require(address(this).balance >= amount, \"Address: insufficient balance\");\n\n        (bool success, ) = recipient.call{value: amount}(\"\");\n        require(success, \"Address: unable to send value, recipient may have reverted\");\n    }\n\n    /**\n     * @dev Performs a Solidity function call using a low level `call`. A\n     * plain `call` is an unsafe replacement for a function call: use this\n     * function instead.\n     *\n     * If `target` reverts with a revert reason, it is bubbled up by this\n     * function (like regular Solidity function calls).\n     *\n     * Returns the raw returned data. To convert to the expected return value,\n     * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n     *\n     * Requirements:\n     *\n     * - `target` must be a contract.\n     * - calling `target` with `data` must not revert.\n     *\n     * _Available since v3.1._\n     */\n    function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n        return functionCall(target, data, \"Address: low-level call failed\");\n    }\n\n    /**\n     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n     * `errorMessage` as a fallback revert reason when `target` reverts.\n     *\n     * _Available since v3.1._\n     */\n    function functionCall(\n        address target,\n        bytes memory data,\n        string memory errorMessage\n    ) internal returns (bytes memory) {\n        return functionCallWithValue(target, data, 0, errorMessage);\n    }\n\n    /**\n     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n     * but also transferring `value` wei to `target`.\n     *\n     * Requirements:\n     *\n     * - the calling contract must have an ETH balance of at least `value`.\n     * - the called Solidity function must be `payable`.\n     *\n     * _Available since v3.1._\n     */\n    function functionCallWithValue(\n        address target,\n        bytes memory data,\n        uint256 value\n    ) internal returns (bytes memory) {\n        return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n    }\n\n    /**\n     * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n     * with `errorMessage` as a fallback revert reason when `target` reverts.\n     *\n     * _Available since v3.1._\n     */\n    function functionCallWithValue(\n        address target,\n        bytes memory data,\n        uint256 value,\n        string memory errorMessage\n    ) internal returns (bytes memory) {\n        require(address(this).balance >= value, \"Address: insufficient balance for call\");\n        require(isContract(target), \"Address: call to non-contract\");\n\n        (bool success, bytes memory returndata) = target.call{value: value}(data);\n        return verifyCallResult(success, returndata, errorMessage);\n    }\n\n    /**\n     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n     * but performing a static call.\n     *\n     * _Available since v3.3._\n     */\n    function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n        return functionStaticCall(target, data, \"Address: low-level static call failed\");\n    }\n\n    /**\n     * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n     * but performing a static call.\n     *\n     * _Available since v3.3._\n     */\n    function functionStaticCall(\n        address target,\n        bytes memory data,\n        string memory errorMessage\n    ) internal view returns (bytes memory) {\n        require(isContract(target), \"Address: static call to non-contract\");\n\n        (bool success, bytes memory returndata) = target.staticcall(data);\n        return verifyCallResult(success, returndata, errorMessage);\n    }\n\n    /**\n     * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n     * revert reason using the provided one.\n     *\n     * _Available since v4.3._\n     */\n    function verifyCallResult(\n        bool success,\n        bytes memory returndata,\n        string memory errorMessage\n    ) internal pure returns (bytes memory) {\n        if (success) {\n            return returndata;\n        } else {\n            // Look for revert reason and bubble it up if present\n            if (returndata.length > 0) {\n                // The easiest way to bubble the revert reason is using memory via assembly\n                /// @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}\n"
      }
    },
    "settings": {
      "optimizer": {
        "enabled": true,
        "runs": 10000
      },
      "outputSelection": {
        "*": {
          "*": [
            "evm.bytecode",
            "evm.deployedBytecode",
            "devdoc",
            "userdoc",
            "metadata",
            "abi"
          ]
        }
      },
      "metadata": {
        "useLiteralContent": true
      },
      "libraries": {}
    }
  }}