{
  "address": "0xA1C7B28B4743248584725fEf31516fD4Ea72aEA8",
  "abi": [
    {
      "inputs": [],
      "stateMutability": "nonpayable",
      "type": "constructor"
    },
    {
      "anonymous": false,
      "inputs": [
        {
          "indexed": false,
          "internalType": "uint8",
          "name": "version",
          "type": "uint8"
        }
      ],
      "name": "Initialized",
      "type": "event"
    },
    {
      "anonymous": false,
      "inputs": [
        {
          "indexed": true,
          "internalType": "address",
          "name": "previousOwner",
          "type": "address"
        },
        {
          "indexed": true,
          "internalType": "address",
          "name": "newOwner",
          "type": "address"
        }
      ],
      "name": "OwnershipTransferred",
      "type": "event"
    },
    {
      "inputs": [],
      "name": "blockFinalizationVerifier",
      "outputs": [
        {
          "internalType": "contract IVerifier",
          "name": "",
          "type": "address"
        }
      ],
      "stateMutability": "view",
      "type": "function"
    },
    {
      "inputs": [],
      "name": "blockInitiationVerifier",
      "outputs": [
        {
          "internalType": "contract IVerifier",
          "name": "",
          "type": "address"
        }
      ],
      "stateMutability": "view",
      "type": "function"
    },
    {
      "inputs": [],
      "name": "callOpVerifier",
      "outputs": [
        {
          "internalType": "contract IVerifier",
          "name": "",
          "type": "address"
        }
      ],
      "stateMutability": "view",
      "type": "function"
    },
    {
      "inputs": [],
      "name": "environmentalOpVerifier",
      "outputs": [
        {
          "internalType": "contract IVerifier",
          "name": "",
          "type": "address"
        }
      ],
      "stateMutability": "view",
      "type": "function"
    },
    {
      "inputs": [],
      "name": "initialize",
      "outputs": [],
      "stateMutability": "nonpayable",
      "type": "function"
    },
    {
      "inputs": [],
      "name": "interTxVerifier",
      "outputs": [
        {
          "internalType": "contract IVerifier",
          "name": "",
          "type": "address"
        }
      ],
      "stateMutability": "view",
      "type": "function"
    },
    {
      "inputs": [],
      "name": "invalidOpVerifier",
      "outputs": [
        {
          "internalType": "contract IVerifier",
          "name": "",
          "type": "address"
        }
      ],
      "stateMutability": "view",
      "type": "function"
    },
    {
      "inputs": [],
      "name": "memoryOpVerifier",
      "outputs": [
        {
          "internalType": "contract IVerifier",
          "name": "",
          "type": "address"
        }
      ],
      "stateMutability": "view",
      "type": "function"
    },
    {
      "inputs": [],
      "name": "owner",
      "outputs": [
        {
          "internalType": "address",
          "name": "",
          "type": "address"
        }
      ],
      "stateMutability": "view",
      "type": "function"
    },
    {
      "inputs": [],
      "name": "renounceOwnership",
      "outputs": [],
      "stateMutability": "nonpayable",
      "type": "function"
    },
    {
      "inputs": [
        {
          "internalType": "uint8",
          "name": "verifier",
          "type": "uint8"
        },
        {
          "internalType": "contract IVerifier",
          "name": "impl",
          "type": "address"
        }
      ],
      "name": "setVerifier",
      "outputs": [],
      "stateMutability": "nonpayable",
      "type": "function"
    },
    {
      "inputs": [],
      "name": "stackOpVerifier",
      "outputs": [
        {
          "internalType": "contract IVerifier",
          "name": "",
          "type": "address"
        }
      ],
      "stateMutability": "view",
      "type": "function"
    },
    {
      "inputs": [],
      "name": "storageOpVerifier",
      "outputs": [
        {
          "internalType": "contract IVerifier",
          "name": "",
          "type": "address"
        }
      ],
      "stateMutability": "view",
      "type": "function"
    },
    {
      "inputs": [
        {
          "internalType": "address",
          "name": "newOwner",
          "type": "address"
        }
      ],
      "name": "transferOwnership",
      "outputs": [],
      "stateMutability": "nonpayable",
      "type": "function"
    },
    {
      "inputs": [
        {
          "components": [
            {
              "internalType": "address",
              "name": "coinbase",
              "type": "address"
            },
            {
              "internalType": "uint256",
              "name": "timestamp",
              "type": "uint256"
            },
            {
              "internalType": "uint256",
              "name": "number",
              "type": "uint256"
            },
            {
              "internalType": "address",
              "name": "origin",
              "type": "address"
            },
            {
              "components": [
                {
                  "internalType": "uint64",
                  "name": "nonce",
                  "type": "uint64"
                },
                {
                  "internalType": "uint256",
                  "name": "gasPrice",
                  "type": "uint256"
                },
                {
                  "internalType": "uint64",
                  "name": "gas",
                  "type": "uint64"
                },
                {
                  "internalType": "address",
                  "name": "to",
                  "type": "address"
                },
                {
                  "internalType": "uint256",
                  "name": "value",
                  "type": "uint256"
                },
                {
                  "internalType": "bytes",
                  "name": "data",
                  "type": "bytes"
                },
                {
                  "internalType": "uint256",
                  "name": "v",
                  "type": "uint256"
                },
                {
                  "internalType": "uint256",
                  "name": "r",
                  "type": "uint256"
                },
                {
                  "internalType": "uint256",
                  "name": "s",
                  "type": "uint256"
                }
              ],
              "internalType": "struct EVMTypesLib.Transaction",
              "name": "transaction",
              "type": "tuple"
            },
            {
              "internalType": "bytes32",
              "name": "inputRoot",
              "type": "bytes32"
            },
            {
              "internalType": "bytes32",
              "name": "txHash",
              "type": "bytes32"
            }
          ],
          "internalType": "struct VerificationContext.Context",
          "name": "ctx",
          "type": "tuple"
        },
        {
          "internalType": "uint8",
          "name": "verifier",
          "type": "uint8"
        },
        {
          "internalType": "bytes32",
          "name": "currStateHash",
          "type": "bytes32"
        },
        {
          "internalType": "bytes",
          "name": "encoded",
          "type": "bytes"
        }
      ],
      "name": "verifyOneStepProof",
      "outputs": [
        {
          "internalType": "bytes32",
          "name": "",
          "type": "bytes32"
        }
      ],
      "stateMutability": "view",
      "type": "function"
    }
  ],
  "transactionHash": "0x48ee788f7895eefc50d0aab47c09acecf5f8fb7495c0a2f6d963c60f9c457dfe",
  "receipt": {
    "to": null,
    "from": "0x2A2954F3989a83Cc43DD58B0f038D5F276f21333",
    "contractAddress": "0xA1C7B28B4743248584725fEf31516fD4Ea72aEA8",
    "transactionIndex": 10,
    "gasUsed": "846143",
    "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080000000000000000000000000001000000000000000000400000000000000000000000000000000000000000000000000000000000000040000000000000200000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
    "blockHash": "0x956fd2e5b06dfbca8445be19a3d42cd4608f7429904eea9b9a73820804f2139a",
    "transactionHash": "0x48ee788f7895eefc50d0aab47c09acecf5f8fb7495c0a2f6d963c60f9c457dfe",
    "logs": [
      {
        "transactionIndex": 10,
        "blockNumber": 17578215,
        "transactionHash": "0x48ee788f7895eefc50d0aab47c09acecf5f8fb7495c0a2f6d963c60f9c457dfe",
        "address": "0xA1C7B28B4743248584725fEf31516fD4Ea72aEA8",
        "topics": [
          "0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498"
        ],
        "data": "0x00000000000000000000000000000000000000000000000000000000000000ff",
        "logIndex": 36,
        "blockHash": "0x956fd2e5b06dfbca8445be19a3d42cd4608f7429904eea9b9a73820804f2139a"
      }
    ],
    "blockNumber": 17578215,
    "cumulativeGasUsed": "2268543",
    "status": 1,
    "byzantium": true
  },
  "args": [],
  "numDeployments": 1,
  "solcInputHash": "b4b807d8f93d16c4b74f280046862b6f",
  "metadata": "{\"compiler\":{\"version\":\"0.8.9+commit.e5eed63a\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"version\",\"type\":\"uint8\"}],\"name\":\"Initialized\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"blockFinalizationVerifier\",\"outputs\":[{\"internalType\":\"contract IVerifier\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"blockInitiationVerifier\",\"outputs\":[{\"internalType\":\"contract IVerifier\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"callOpVerifier\",\"outputs\":[{\"internalType\":\"contract IVerifier\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"environmentalOpVerifier\",\"outputs\":[{\"internalType\":\"contract IVerifier\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"initialize\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"interTxVerifier\",\"outputs\":[{\"internalType\":\"contract IVerifier\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"invalidOpVerifier\",\"outputs\":[{\"internalType\":\"contract IVerifier\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"memoryOpVerifier\",\"outputs\":[{\"internalType\":\"contract IVerifier\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"renounceOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint8\",\"name\":\"verifier\",\"type\":\"uint8\"},{\"internalType\":\"contract IVerifier\",\"name\":\"impl\",\"type\":\"address\"}],\"name\":\"setVerifier\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"stackOpVerifier\",\"outputs\":[{\"internalType\":\"contract IVerifier\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"storageOpVerifier\",\"outputs\":[{\"internalType\":\"contract IVerifier\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"coinbase\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"timestamp\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"number\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"origin\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"nonce\",\"type\":\"uint64\"},{\"internalType\":\"uint256\",\"name\":\"gasPrice\",\"type\":\"uint256\"},{\"internalType\":\"uint64\",\"name\":\"gas\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"v\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"r\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"s\",\"type\":\"uint256\"}],\"internalType\":\"struct EVMTypesLib.Transaction\",\"name\":\"transaction\",\"type\":\"tuple\"},{\"internalType\":\"bytes32\",\"name\":\"inputRoot\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"txHash\",\"type\":\"bytes32\"}],\"internalType\":\"struct VerificationContext.Context\",\"name\":\"ctx\",\"type\":\"tuple\"},{\"internalType\":\"uint8\",\"name\":\"verifier\",\"type\":\"uint8\"},{\"internalType\":\"bytes32\",\"name\":\"currStateHash\",\"type\":\"bytes32\"},{\"internalType\":\"bytes\",\"name\":\"encoded\",\"type\":\"bytes\"}],\"name\":\"verifyOneStepProof\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"constructor\":{\"custom:oz-upgrades-unsafe-allow\":\"constructor\"},\"owner()\":{\"details\":\"Returns the address of the current owner.\"},\"renounceOwnership()\":{\"details\":\"Leaves the contract without owner. It will not be possible to call `onlyOwner` functions anymore. Can only be called by the current owner. NOTE: Renouncing ownership will leave the contract without an owner, thereby removing any functionality that is only available to the owner.\"},\"transferOwnership(address)\":{\"details\":\"Transfers ownership of the contract to a new account (`newOwner`). Can only be called by the current owner.\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/L1/fraud-proof/verifier/VerifierEntry.sol\":\"VerifierEntry\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"@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\",\"keccak256\":\"0x247c62047745915c0af6b955470a72d1696ebad4352d7d3011aef1a2463cd888\",\"license\":\"MIT\"},\"@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\",\"keccak256\":\"0x0203dcadc5737d9ef2c211d6fa15d18ebc3b30dfa51903b64870b01a062b0b4e\",\"license\":\"MIT\"},\"@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\",\"keccak256\":\"0x611aa3f23e59cfdd1863c536776407b3e33d695152a266fa7cfb34440a29a8a3\",\"license\":\"MIT\"},\"@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\",\"keccak256\":\"0x963ea7f0b48b032eef72fe3a7582edf78408d6f834115b9feadd673a4d5bd149\",\"license\":\"MIT\"},\"contracts/L1/fraud-proof/libraries/BytesLib.sol\":{\"content\":\"// SPDX-License-Identifier: Unlicense\\n\\n/*\\n * @title Solidity Bytes Arrays Utils\\n * @author Gon\\u00e7alo S\\u00e1 <goncalo.sa@consensys.net>\\n * @custom:attribution https://github.com/GNSPS/solidity-bytes-utils\\n *\\n * @dev Bytes tightly packed arrays utility library for ethereum contracts written in Solidity.\\n *      The library lets you concatenate, slice and type cast bytes arrays both in memory and storage.\\n */\\n\\npragma solidity >=0.8.0 <0.9.0;\\n\\nlibrary BytesLib {\\n    function concat(bytes memory _preBytes, bytes memory _postBytes) internal pure returns (bytes memory) {\\n        bytes memory tempBytes;\\n\\n        assembly {\\n            // Get a location of some free memory and store it in tempBytes as\\n            // Solidity does for memory variables.\\n            tempBytes := mload(0x40)\\n\\n            // Store the length of the first bytes array at the beginning of\\n            // the memory for tempBytes.\\n            let length := mload(_preBytes)\\n            mstore(tempBytes, length)\\n\\n            // Maintain a memory counter for the current write location in the\\n            // temp bytes array by adding the 32 bytes for the array length to\\n            // the starting location.\\n            let mc := add(tempBytes, 0x20)\\n            // Stop copying when the memory counter reaches the length of the\\n            // first bytes array.\\n            let end := add(mc, length)\\n\\n            for {\\n                // Initialize a copy counter to the start of the _preBytes data,\\n                // 32 bytes into its memory.\\n                let cc := add(_preBytes, 0x20)\\n            } lt(mc, end) {\\n                // Increase both counters by 32 bytes each iteration.\\n                mc := add(mc, 0x20)\\n                cc := add(cc, 0x20)\\n            } {\\n                // Write the _preBytes data into the tempBytes memory 32 bytes\\n                // at a time.\\n                mstore(mc, mload(cc))\\n            }\\n\\n            // Add the length of _postBytes to the current length of tempBytes\\n            // and store it as the new length in the first 32 bytes of the\\n            // tempBytes memory.\\n            length := mload(_postBytes)\\n            mstore(tempBytes, add(length, mload(tempBytes)))\\n\\n            // Move the memory counter back from a multiple of 0x20 to the\\n            // actual end of the _preBytes data.\\n            mc := end\\n            // Stop copying when the memory counter reaches the new combined\\n            // length of the arrays.\\n            end := add(mc, length)\\n\\n            for { let cc := add(_postBytes, 0x20) } lt(mc, end) {\\n                mc := add(mc, 0x20)\\n                cc := add(cc, 0x20)\\n            } { mstore(mc, mload(cc)) }\\n\\n            // Update the free-memory pointer by padding our last write location\\n            // to 32 bytes: add 31 bytes to the end of tempBytes to move to the\\n            // next 32 byte block, then round down to the nearest multiple of\\n            // 32. If the sum of the length of the two arrays is zero then add\\n            // one before rounding down to leave a blank 32 bytes (the length block with 0).\\n            mstore(\\n                0x40,\\n                and(\\n                    add(add(end, iszero(add(length, mload(_preBytes)))), 31),\\n                    not(31) // Round down to the nearest 32 bytes.\\n                )\\n            )\\n        }\\n\\n        return tempBytes;\\n    }\\n\\n    function concatStorage(bytes storage _preBytes, bytes memory _postBytes) internal {\\n        assembly {\\n            // Read the first 32 bytes of _preBytes storage, which is the length\\n            // of the array. (We don't need to use the offset into the slot\\n            // because arrays use the entire slot.)\\n            let fslot := sload(_preBytes.slot)\\n            // Arrays of 31 bytes or less have an even value in their slot,\\n            // while longer arrays have an odd value. The actual length is\\n            // the slot divided by two for odd values, and the lowest order\\n            // byte divided by two for even values.\\n            // If the slot is even, bitwise and the slot with 255 and divide by\\n            // two to get the length. If the slot is odd, bitwise and the slot\\n            // with -1 and divide by two.\\n            let slength := div(and(fslot, sub(mul(0x100, iszero(and(fslot, 1))), 1)), 2)\\n            let mlength := mload(_postBytes)\\n            let newlength := add(slength, mlength)\\n            // slength can contain both the length and contents of the array\\n            // if length < 32 bytes so let's prepare for that\\n            // v. http://solidity.readthedocs.io/en/latest/miscellaneous.html#layout-of-state-variables-in-storage\\n            switch add(lt(slength, 32), lt(newlength, 32))\\n            case 2 {\\n                // Since the new array still fits in the slot, we just need to\\n                // update the contents of the slot.\\n                // uint256(bytes_storage) = uint256(bytes_storage) + uint256(bytes_memory) + new_length\\n                sstore(\\n                    _preBytes.slot,\\n                    // all the modifications to the slot are inside this\\n                    // next block\\n                    add(\\n                        // we can just add to the slot contents because the\\n                        // bytes we want to change are the LSBs\\n                        fslot,\\n                        add(\\n                            mul(\\n                                div(\\n                                    // load the bytes from memory\\n                                    mload(add(_postBytes, 0x20)),\\n                                    // zero all bytes to the right\\n                                    exp(0x100, sub(32, mlength))\\n                                ),\\n                                // and now shift left the number of bytes to\\n                                // leave space for the length in the slot\\n                                exp(0x100, sub(32, newlength))\\n                            ),\\n                            // increase length by the double of the memory\\n                            // bytes length\\n                            mul(mlength, 2)\\n                        )\\n                    )\\n                )\\n            }\\n            case 1 {\\n                // The stored value fits in the slot, but the combined value\\n                // will exceed it.\\n                // get the keccak hash to get the contents of the array\\n                mstore(0x0, _preBytes.slot)\\n                let sc := add(keccak256(0x0, 0x20), div(slength, 32))\\n\\n                // save new length\\n                sstore(_preBytes.slot, add(mul(newlength, 2), 1))\\n\\n                // The contents of the _postBytes array start 32 bytes into\\n                // the structure. Our first read should obtain the `submod`\\n                // bytes that can fit into the unused space in the last word\\n                // of the stored array. To get this, we read 32 bytes starting\\n                // from `submod`, so the data we read overlaps with the array\\n                // contents by `submod` bytes. Masking the lowest-order\\n                // `submod` bytes allows us to add that value directly to the\\n                // stored value.\\n\\n                let submod := sub(32, slength)\\n                let mc := add(_postBytes, submod)\\n                let end := add(_postBytes, mlength)\\n                let mask := sub(exp(0x100, submod), 1)\\n\\n                sstore(\\n                    sc,\\n                    add(\\n                        and(fslot, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00),\\n                        and(mload(mc), mask)\\n                    )\\n                )\\n\\n                for {\\n                    mc := add(mc, 0x20)\\n                    sc := add(sc, 1)\\n                } lt(mc, end) {\\n                    sc := add(sc, 1)\\n                    mc := add(mc, 0x20)\\n                } { sstore(sc, mload(mc)) }\\n\\n                mask := exp(0x100, sub(mc, end))\\n\\n                sstore(sc, mul(div(mload(mc), mask), mask))\\n            }\\n            default {\\n                // get the keccak hash to get the contents of the array\\n                mstore(0x0, _preBytes.slot)\\n                // Start copying to the last used word of the stored array.\\n                let sc := add(keccak256(0x0, 0x20), div(slength, 32))\\n\\n                // save new length\\n                sstore(_preBytes.slot, add(mul(newlength, 2), 1))\\n\\n                // Copy over the first `submod` bytes of the new data as in\\n                // case 1 above.\\n                let slengthmod := mod(slength, 32)\\n                let mlengthmod := mod(mlength, 32)\\n                let submod := sub(32, slengthmod)\\n                let mc := add(_postBytes, submod)\\n                let end := add(_postBytes, mlength)\\n                let mask := sub(exp(0x100, submod), 1)\\n\\n                sstore(sc, add(sload(sc), and(mload(mc), mask)))\\n\\n                for {\\n                    sc := add(sc, 1)\\n                    mc := add(mc, 0x20)\\n                } lt(mc, end) {\\n                    sc := add(sc, 1)\\n                    mc := add(mc, 0x20)\\n                } { sstore(sc, mload(mc)) }\\n\\n                mask := exp(0x100, sub(mc, end))\\n\\n                sstore(sc, mul(div(mload(mc), mask), mask))\\n            }\\n        }\\n    }\\n\\n    function slice(bytes memory _bytes, uint256 _start, uint256 _length) internal pure returns (bytes memory) {\\n        require(_length + 31 >= _length, \\\"slice_overflow\\\");\\n        require(_bytes.length >= _start + _length, \\\"slice_outOfBounds\\\");\\n\\n        bytes memory tempBytes;\\n\\n        assembly {\\n            switch iszero(_length)\\n            case 0 {\\n                // Get a location of some free memory and store it in tempBytes as\\n                // Solidity does for memory variables.\\n                tempBytes := mload(0x40)\\n\\n                // The first word of the slice result is potentially a partial\\n                // word read from the original array. To read it, we calculate\\n                // the length of that partial word and start copying that many\\n                // bytes into the array. The first word we copy will start with\\n                // data we don't care about, but the last `lengthmod` bytes will\\n                // land at the beginning of the contents of the new array. When\\n                // we're done copying, we overwrite the full first word with\\n                // the actual length of the slice.\\n                let lengthmod := and(_length, 31)\\n\\n                // The multiplication in the next line is necessary\\n                // because when slicing multiples of 32 bytes (lengthmod == 0)\\n                // the following copy loop was copying the origin's length\\n                // and then ending prematurely not copying everything it should.\\n                let mc := add(add(tempBytes, lengthmod), mul(0x20, iszero(lengthmod)))\\n                let end := add(mc, _length)\\n\\n                for {\\n                    // The multiplication in the next line has the same exact purpose\\n                    // as the one above.\\n                    let cc := add(add(add(_bytes, lengthmod), mul(0x20, iszero(lengthmod))), _start)\\n                } lt(mc, end) {\\n                    mc := add(mc, 0x20)\\n                    cc := add(cc, 0x20)\\n                } { mstore(mc, mload(cc)) }\\n\\n                mstore(tempBytes, _length)\\n\\n                //update free-memory pointer\\n                //allocating the array padded to 32 bytes like the compiler does now\\n                mstore(0x40, and(add(mc, 31), not(31)))\\n            }\\n            //if we want a zero-length slice let's just return a zero-length array\\n            default {\\n                tempBytes := mload(0x40)\\n                //zero out the 32 bytes slice we are about to return\\n                //we need to do it because Solidity does not garbage collect\\n                mstore(tempBytes, 0)\\n\\n                mstore(0x40, add(tempBytes, 0x20))\\n            }\\n        }\\n\\n        return tempBytes;\\n    }\\n\\n    function toBytes32Pad(bytes memory _bytes, uint256 _start) internal pure returns (bytes32) {\\n        bytes32 result;\\n\\n        assembly {\\n            result := mload(add(add(_bytes, 0x20), _start))\\n        }\\n\\n        if (_bytes.length < _start + 32) {\\n            uint256 pad = 32 + _start - _bytes.length;\\n            result = result >> pad << pad;\\n        }\\n\\n        return result;\\n    }\\n\\n    function toAddress(bytes memory _bytes, uint256 _start) internal pure returns (address) {\\n        require(_bytes.length >= _start + 20, \\\"toAddress_outOfBounds\\\");\\n        address tempAddress;\\n\\n        assembly {\\n            tempAddress := div(mload(add(add(_bytes, 0x20), _start)), 0x1000000000000000000000000)\\n        }\\n\\n        return tempAddress;\\n    }\\n\\n    function toUint8(bytes memory _bytes, uint256 _start) internal pure returns (uint8) {\\n        require(_bytes.length >= _start + 1, \\\"toUint8_outOfBounds\\\");\\n        uint8 tempUint;\\n\\n        assembly {\\n            tempUint := mload(add(add(_bytes, 0x1), _start))\\n        }\\n\\n        return tempUint;\\n    }\\n\\n    function toUint16(bytes memory _bytes, uint256 _start) internal pure returns (uint16) {\\n        require(_bytes.length >= _start + 2, \\\"toUint16_outOfBounds\\\");\\n        uint16 tempUint;\\n\\n        assembly {\\n            tempUint := mload(add(add(_bytes, 0x2), _start))\\n        }\\n\\n        return tempUint;\\n    }\\n\\n    function toUint32(bytes memory _bytes, uint256 _start) internal pure returns (uint32) {\\n        require(_bytes.length >= _start + 4, \\\"toUint32_outOfBounds\\\");\\n        uint32 tempUint;\\n\\n        assembly {\\n            tempUint := mload(add(add(_bytes, 0x4), _start))\\n        }\\n\\n        return tempUint;\\n    }\\n\\n    function toUint64(bytes memory _bytes, uint256 _start) internal pure returns (uint64) {\\n        require(_bytes.length >= _start + 8, \\\"toUint64_outOfBounds\\\");\\n        uint64 tempUint;\\n\\n        assembly {\\n            tempUint := mload(add(add(_bytes, 0x8), _start))\\n        }\\n\\n        return tempUint;\\n    }\\n\\n    function toUint96(bytes memory _bytes, uint256 _start) internal pure returns (uint96) {\\n        require(_bytes.length >= _start + 12, \\\"toUint96_outOfBounds\\\");\\n        uint96 tempUint;\\n\\n        assembly {\\n            tempUint := mload(add(add(_bytes, 0xc), _start))\\n        }\\n\\n        return tempUint;\\n    }\\n\\n    function toUint128(bytes memory _bytes, uint256 _start) internal pure returns (uint128) {\\n        require(_bytes.length >= _start + 16, \\\"toUint128_outOfBounds\\\");\\n        uint128 tempUint;\\n\\n        assembly {\\n            tempUint := mload(add(add(_bytes, 0x10), _start))\\n        }\\n\\n        return tempUint;\\n    }\\n\\n    function toUint256(bytes memory _bytes, uint256 _start) internal pure returns (uint256) {\\n        require(_bytes.length >= _start + 32, \\\"toUint256_outOfBounds\\\");\\n        uint256 tempUint;\\n\\n        assembly {\\n            tempUint := mload(add(add(_bytes, 0x20), _start))\\n        }\\n\\n        return tempUint;\\n    }\\n\\n    function toBytes32(bytes memory _bytes, uint256 _start) internal pure returns (bytes32) {\\n        require(_bytes.length >= _start + 32, \\\"toBytes32_outOfBounds\\\");\\n        bytes32 tempBytes32;\\n\\n        assembly {\\n            tempBytes32 := mload(add(add(_bytes, 0x20), _start))\\n        }\\n\\n        return tempBytes32;\\n    }\\n\\n    function equal(bytes memory _preBytes, bytes memory _postBytes) internal pure returns (bool) {\\n        bool success = true;\\n\\n        assembly {\\n            let length := mload(_preBytes)\\n\\n            // if lengths don't match the arrays are not equal\\n            switch eq(length, mload(_postBytes))\\n            case 1 {\\n                // cb is a circuit breaker in the for loop since there's\\n                //  no said feature for inline assembly loops\\n                // cb = 1 - don't breaker\\n                // cb = 0 - break\\n                let cb := 1\\n\\n                let mc := add(_preBytes, 0x20)\\n                let end := add(mc, length)\\n\\n                for { let cc := add(_postBytes, 0x20) }\\n                // the next line is the loop condition:\\n                // while(uint256(mc < end) + cb == 2)\\n                eq(add(lt(mc, end), cb), 2) {\\n                    mc := add(mc, 0x20)\\n                    cc := add(cc, 0x20)\\n                } {\\n                    // if any of these checks fails then arrays are not equal\\n                    if iszero(eq(mload(mc), mload(cc))) {\\n                        // unsuccess:\\n                        success := 0\\n                        cb := 0\\n                    }\\n                }\\n            }\\n            default {\\n                // unsuccess:\\n                success := 0\\n            }\\n        }\\n\\n        return success;\\n    }\\n\\n    function equalStorage(bytes storage _preBytes, bytes memory _postBytes) internal view returns (bool) {\\n        bool success = true;\\n\\n        assembly {\\n            // we know _preBytes_offset is 0\\n            let fslot := sload(_preBytes.slot)\\n            // Decode the length of the stored array like in concatStorage().\\n            let slength := div(and(fslot, sub(mul(0x100, iszero(and(fslot, 1))), 1)), 2)\\n            let mlength := mload(_postBytes)\\n\\n            // if lengths don't match the arrays are not equal\\n            switch eq(slength, mlength)\\n            case 1 {\\n                // slength can contain both the length and contents of the array\\n                // if length < 32 bytes so let's prepare for that\\n                // v. http://solidity.readthedocs.io/en/latest/miscellaneous.html#layout-of-state-variables-in-storage\\n                if iszero(iszero(slength)) {\\n                    switch lt(slength, 32)\\n                    case 1 {\\n                        // blank the last byte which is the length\\n                        fslot := mul(div(fslot, 0x100), 0x100)\\n\\n                        if iszero(eq(fslot, mload(add(_postBytes, 0x20)))) {\\n                            // unsuccess:\\n                            success := 0\\n                        }\\n                    }\\n                    default {\\n                        // cb is a circuit breaker in the for loop since there's\\n                        //  no said feature for inline assembly loops\\n                        // cb = 1 - don't breaker\\n                        // cb = 0 - break\\n                        let cb := 1\\n\\n                        // get the keccak hash to get the contents of the array\\n                        mstore(0x0, _preBytes.slot)\\n                        let sc := keccak256(0x0, 0x20)\\n\\n                        let mc := add(_postBytes, 0x20)\\n                        let end := add(mc, mlength)\\n\\n                        // the next line is the loop condition:\\n                        // while(uint256(mc < end) + cb == 2)\\n                        for {} eq(add(lt(mc, end), cb), 2) {\\n                            sc := add(sc, 1)\\n                            mc := add(mc, 0x20)\\n                        } {\\n                            if iszero(eq(sload(sc), mload(mc))) {\\n                                // unsuccess:\\n                                success := 0\\n                                cb := 0\\n                            }\\n                        }\\n                    }\\n                }\\n            }\\n            default {\\n                // unsuccess:\\n                success := 0\\n            }\\n        }\\n\\n        return success;\\n    }\\n}\\n\",\"keccak256\":\"0x35162cc8fa7ac784dd613242330c03110274f10e03f2e87f3fe4e48067954813\",\"license\":\"Unlicense\"},\"contracts/L1/fraud-proof/libraries/DeserializationLib.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\n\\n/*\\n * Copyright 2022, Specular contributors\\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.0;\\n\\nimport \\\"./BytesLib.sol\\\";\\n\\nlibrary DeserializationLib {\\n    function deserializeAddress(bytes memory data, uint256 startOffset) internal pure returns (uint256, address) {\\n        return (startOffset + 20, BytesLib.toAddress(data, startOffset));\\n    }\\n\\n    function deserializeUint256(bytes memory data, uint256 startOffset) internal pure returns (uint256, uint256) {\\n        require(data.length >= startOffset && data.length - startOffset >= 32, \\\"too short\\\");\\n        return (startOffset + 32, BytesLib.toUint256(data, startOffset));\\n    }\\n\\n    function deserializeBytes32(bytes memory data, uint256 startOffset) internal pure returns (uint256, bytes32) {\\n        require(data.length >= startOffset && data.length - startOffset >= 32, \\\"too short\\\");\\n        return (startOffset + 32, BytesLib.toBytes32(data, startOffset));\\n    }\\n}\\n\",\"keccak256\":\"0x2f3dd8e98a3d8c86d628d345254ee19111d0c4c61ecc4843e78cb1f57be66791\",\"license\":\"Apache-2.0\"},\"contracts/L1/fraud-proof/libraries/MerkleLib.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\nlibrary MerkleLib {\\n    // Hashes a and b in the order they are passed\\n    function hash_node(bytes32 a, bytes32 b) internal pure returns (bytes32 hash) {\\n        assembly {\\n            mstore(0x00, a)\\n            mstore(0x20, b)\\n            hash := keccak256(0x00, 0x40)\\n        }\\n    }\\n\\n    // Hashes a and b in order define by boolean\\n    function hash_pair(bytes32 a, bytes32 b, bool order) internal pure returns (bytes32 hash) {\\n        hash = order ? hash_node(a, b) : hash_node(b, a);\\n    }\\n\\n    // Counts number of set bits (1's) in 32-bit unsigned integer\\n    function bit_count_32(uint32 n) internal pure returns (uint32) {\\n        n = n - ((n >> 1) & 0x55555555);\\n        n = (n & 0x33333333) + ((n >> 2) & 0x33333333);\\n\\n        return (((n + (n >> 4)) & 0xF0F0F0F) * 0x1010101) >> 24;\\n    }\\n\\n    // Round 32-bit unsigned integer up to the nearest power of 2\\n    function round_up_to_power_of_2(uint32 n) internal pure returns (uint32) {\\n        if (bit_count_32(n) == 1) return n;\\n\\n        n |= n >> 1;\\n        n |= n >> 2;\\n        n |= n >> 4;\\n        n |= n >> 8;\\n        n |= n >> 16;\\n\\n        return n + 1;\\n    }\\n\\n    // Get the Element Merkle Root for a tree with just a single bytes32 element in memory\\n    function get_root_from_one(bytes32 element) internal pure returns (bytes32) {\\n        return keccak256(abi.encodePacked(bytes1(0), element));\\n    }\\n\\n    // Get nodes (parent of leafs) from bytes32 elements in memory\\n    function get_nodes_from_elements(bytes32[] memory elements) internal pure returns (bytes32[] memory nodes) {\\n        uint256 element_count = elements.length;\\n        uint256 node_count = (element_count >> 1) + (element_count & 1);\\n        nodes = new bytes32[](node_count);\\n        uint256 write_index;\\n        uint256 left_index;\\n\\n        while (write_index < node_count) {\\n            left_index = write_index << 1;\\n\\n            if (left_index == element_count - 1) {\\n                nodes[write_index] = keccak256(abi.encodePacked(bytes1(0), elements[left_index]));\\n                break;\\n            }\\n\\n            nodes[write_index++] = hash_node(\\n                keccak256(abi.encodePacked(bytes1(0), elements[left_index])),\\n                keccak256(abi.encodePacked(bytes1(0), elements[left_index + 1]))\\n            );\\n        }\\n    }\\n\\n    // Get the Element Merkle Root given nodes (parent of leafs)\\n    function get_root_from_nodes(bytes32[] memory nodes) internal pure returns (bytes32) {\\n        uint256 node_count = nodes.length;\\n        uint256 write_index;\\n        uint256 left_index;\\n\\n        while (node_count > 1) {\\n            left_index = write_index << 1;\\n\\n            if (left_index == node_count - 1) {\\n                nodes[write_index] = nodes[left_index];\\n                write_index = 0;\\n                node_count = (node_count >> 1) + (node_count & 1);\\n                continue;\\n            }\\n\\n            if (left_index >= node_count) {\\n                write_index = 0;\\n                node_count = (node_count >> 1) + (node_count & 1);\\n                continue;\\n            }\\n\\n            nodes[write_index++] = hash_node(nodes[left_index], nodes[left_index + 1]);\\n        }\\n\\n        return nodes[0];\\n    }\\n\\n    // Get the Element Merkle Root for a tree with several bytes32 elements in memory\\n    function get_root_from_many(bytes32[] memory elements) internal pure returns (bytes32) {\\n        return get_root_from_nodes(get_nodes_from_elements(elements));\\n    }\\n\\n    // Get the original Element Merkle Root, given a Size Proof\\n    function get_root_from_size_proof(uint256 element_count, bytes32[] memory proof)\\n        internal\\n        pure\\n        returns (bytes32 hash)\\n    {\\n        uint256 proof_index = bit_count_32(uint32(element_count)) - 1;\\n        hash = proof[proof_index];\\n\\n        while (proof_index > 0) {\\n            hash = hash_node(proof[--proof_index], hash);\\n        }\\n    }\\n\\n    // Get the original Element Merkle Root, given an index, a leaf, and a Single Proof\\n    function get_root_from_leaf_and_single_proof(uint256 index, bytes32 leaf, bytes32[] memory proof)\\n        internal\\n        pure\\n        returns (bytes32)\\n    {\\n        uint256 proof_index = proof.length - 1;\\n        uint256 upper_bound = uint256(proof[0]) - 1;\\n\\n        while (proof_index > 0) {\\n            if (index != upper_bound || (index & 1 == 1)) {\\n                leaf = (index & 1 == 1) ? hash_node(proof[proof_index], leaf) : hash_node(leaf, proof[proof_index]);\\n                proof_index -= 1;\\n            }\\n\\n            index >>= 1;\\n            upper_bound >>= 1;\\n        }\\n\\n        return leaf;\\n    }\\n\\n    // Get the original Element Merkle Root, given an index, a bytes32 element, and a Single Proof\\n    function get_root_from_single_proof(uint256 index, bytes32 element, bytes32[] memory proof)\\n        internal\\n        pure\\n        returns (bytes32 hash)\\n    {\\n        hash = keccak256(abi.encodePacked(bytes1(0), element));\\n        hash = get_root_from_leaf_and_single_proof(index, hash, proof);\\n    }\\n\\n    // Get the original and updated Element Merkle Root, given an index, a leaf, an update leaf, and a Single Proof\\n    function get_roots_from_leaf_and_single_proof_update(\\n        uint256 index,\\n        bytes32 leaf,\\n        bytes32 update_leaf,\\n        bytes32[] memory proof\\n    ) internal pure returns (bytes32 scratch, bytes32) {\\n        uint256 proof_index = proof.length - 1;\\n        uint256 upper_bound = uint256(proof[0]) - 1;\\n\\n        while (proof_index > 0) {\\n            if ((index != upper_bound) || (index & 1 == 1)) {\\n                scratch = proof[proof_index];\\n                proof_index -= 1;\\n                leaf = (index & 1 == 1) ? hash_node(scratch, leaf) : hash_node(leaf, scratch);\\n                update_leaf = (index & 1 == 1) ? hash_node(scratch, update_leaf) : hash_node(update_leaf, scratch);\\n            }\\n\\n            index >>= 1;\\n            upper_bound >>= 1;\\n        }\\n\\n        return (leaf, update_leaf);\\n    }\\n\\n    // Get the original and updated Element Merkle Root, given an index, a bytes32 element, a bytes32 update element, and a Single Proof\\n    function get_roots_from_single_proof_update(\\n        uint256 index,\\n        bytes32 element,\\n        bytes32 update_element,\\n        bytes32[] memory proof\\n    ) internal pure returns (bytes32 hash, bytes32 update_hash) {\\n        hash = keccak256(abi.encodePacked(bytes1(0), element));\\n        update_hash = keccak256(abi.encodePacked(bytes1(0), update_element));\\n        return get_roots_from_leaf_and_single_proof_update(index, hash, update_hash, proof);\\n    }\\n\\n    // Get the indices of the elements being proven, given an Existence Multi Proof\\n    function get_indices_from_multi_proof(uint256 element_count, bytes32 flags, bytes32 skips, bytes32 orders)\\n        internal\\n        pure\\n        returns (uint256[] memory indices)\\n    {\\n        indices = new uint256[](element_count);\\n        uint256[] memory bits_pushed = new uint256[](element_count);\\n        bool[] memory grouped_with_next = new bool[](element_count);\\n        element_count -= 1;\\n        uint256 index = element_count;\\n        bytes32 bit_check = 0x0000000000000000000000000000000000000000000000000000000000000001;\\n        bytes32 flag;\\n        bytes32 skip;\\n        bytes32 order;\\n        uint256 bits_to_push;\\n\\n        while (true) {\\n            flag = flags & bit_check;\\n            skip = skips & bit_check;\\n            order = orders & bit_check;\\n            bits_to_push = 1 << bits_pushed[index];\\n\\n            if (skip == bit_check) {\\n                if (flag == bit_check) return indices;\\n\\n                while (true) {\\n                    bits_pushed[index]++;\\n\\n                    if (index == 0) {\\n                        index = element_count;\\n                        break;\\n                    }\\n\\n                    if (!grouped_with_next[index--]) break;\\n                }\\n\\n                bit_check <<= 1;\\n                continue;\\n            }\\n\\n            if (flag == bit_check) {\\n                while (true) {\\n                    if (order == bit_check) {\\n                        indices[index] |= bits_to_push;\\n                    }\\n\\n                    bits_pushed[index]++;\\n\\n                    if (index == 0) {\\n                        index = element_count;\\n                        break;\\n                    }\\n\\n                    if (!grouped_with_next[index]) {\\n                        grouped_with_next[index--] = true;\\n                        break;\\n                    }\\n\\n                    grouped_with_next[index--] = true;\\n                }\\n            }\\n\\n            while (true) {\\n                if (order != bit_check) {\\n                    indices[index] |= bits_to_push;\\n                }\\n\\n                bits_pushed[index]++;\\n\\n                if (index == 0) {\\n                    index = element_count;\\n                    break;\\n                }\\n\\n                if (!grouped_with_next[index--]) break;\\n            }\\n\\n            bit_check <<= 1;\\n        }\\n    }\\n\\n    // Get leafs from bytes32 elements in memory, in reverse order\\n    function get_reversed_leafs_from_elements(bytes32[] memory elements)\\n        internal\\n        pure\\n        returns (bytes32[] memory leafs)\\n    {\\n        uint256 element_count = elements.length;\\n        leafs = new bytes32[](element_count);\\n        // uint256 read_index = element_count - 1;\\n        // uint256 write_index;\\n\\n        for (uint64 i = 0; i < element_count; i++) {\\n            leafs[i] = keccak256(abi.encodePacked(bytes1(0), elements[element_count - 1 - i]));\\n        }\\n\\n        // while (write_index < element_count) {\\n        //     leafs[write_index] = keccak256(abi.encodePacked(bytes1(0), elements[read_index]));\\n        //     write_index += 1;\\n        //     read_index -= 1;\\n        // }\\n    }\\n\\n    // Get the original Element Merkle Root, given leafs and an Existence Multi Proof\\n    function get_root_from_leafs_and_multi_proof(bytes32[] memory leafs, bytes32[] memory proof)\\n        internal\\n        pure\\n        returns (bytes32 right)\\n    {\\n        uint256 leaf_count = leafs.length;\\n        uint256 read_index;\\n        uint256 write_index;\\n        uint256 proof_index = 4;\\n        bytes32 bit_check = 0x0000000000000000000000000000000000000000000000000000000000000001;\\n        bytes32 flags = proof[1];\\n        bytes32 skips = proof[2];\\n        bytes32 orders = proof[3];\\n\\n        while (true) {\\n            if (skips & bit_check == bit_check) {\\n                if (flags & bit_check == bit_check) return leafs[(write_index == 0 ? leaf_count : write_index) - 1];\\n\\n                leafs[write_index] = leafs[read_index];\\n\\n                read_index = (read_index + 1) % leaf_count;\\n                write_index = (write_index + 1) % leaf_count;\\n                bit_check <<= 1;\\n                continue;\\n            }\\n\\n            right = (flags & bit_check == bit_check) ? leafs[read_index++] : proof[proof_index++];\\n\\n            read_index %= leaf_count;\\n\\n            leafs[write_index] = hash_pair(leafs[read_index], right, orders & bit_check == bit_check);\\n\\n            read_index = (read_index + 1) % leaf_count;\\n            write_index = (write_index + 1) % leaf_count;\\n            bit_check <<= 1;\\n        }\\n    }\\n\\n    // Get the original Element Merkle Root, given bytes32 memory in memory and an Existence Multi Proof\\n    function get_root_from_multi_proof(bytes32[] memory elements, bytes32[] memory proof)\\n        internal\\n        pure\\n        returns (bytes32)\\n    {\\n        return get_root_from_leafs_and_multi_proof(get_reversed_leafs_from_elements(elements), proof);\\n    }\\n\\n    // Get current and update leafs from current bytes32 elements in memory and update bytes32 elements in memory, in reverse order\\n    function get_reversed_leafs_from_current_and_update_elements(\\n        bytes32[] memory elements,\\n        bytes32[] memory update_elements\\n    ) internal pure returns (bytes32[] memory leafs, bytes32[] memory update_leafs) {\\n        uint256 element_count = elements.length;\\n        require(update_elements.length == element_count, \\\"LENGTH_MISMATCH\\\");\\n\\n        leafs = new bytes32[](element_count);\\n        update_leafs = new bytes32[](element_count);\\n        // uint256 read_index = element_count - 1;\\n        // uint256 write_index;\\n\\n        // while (write_index < element_count) {\\n        //     leafs[write_index] = keccak256(abi.encodePacked(bytes1(0), elements[read_index]));\\n        //     update_leafs[write_index] = keccak256(abi.encodePacked(bytes1(0), update_elements[read_index]));\\n        //     write_index += 1;\\n        //     read_index -= 1;\\n        // }\\n\\n        for (uint64 i = 0; i < element_count; i++) {\\n            leafs[i] = keccak256(abi.encodePacked(bytes1(0), elements[element_count - 1 - i]));\\n            update_leafs[i] = keccak256(abi.encodePacked(bytes1(0), update_elements[element_count - 1 - i]));\\n        }\\n    }\\n\\n    // Get the original and updated Element Merkle Root, given leafs, update leafs, and an Existence Multi Proof\\n    function get_roots_from_leafs_and_multi_proof_update(\\n        bytes32[] memory leafs,\\n        bytes32[] memory update_leafs,\\n        bytes32[] memory proof\\n    ) internal pure returns (bytes32 flags, bytes32 skips) {\\n        uint256 leaf_count = update_leafs.length;\\n        uint256 read_index;\\n        uint256 write_index;\\n        uint256 proof_index = 4;\\n        bytes32 bit_check = 0x0000000000000000000000000000000000000000000000000000000000000001;\\n        flags = proof[1];\\n        skips = proof[2];\\n        bytes32 orders = proof[3];\\n        bytes32 scratch;\\n        uint256 scratch_2;\\n\\n        while (true) {\\n            if (skips & bit_check == bit_check) {\\n                if (flags & bit_check == bit_check) {\\n                    read_index = (write_index == 0 ? leaf_count : write_index) - 1;\\n\\n                    return (leafs[read_index], update_leafs[read_index]);\\n                }\\n\\n                leafs[write_index] = leafs[read_index];\\n                update_leafs[write_index] = update_leafs[read_index];\\n\\n                read_index = (read_index + 1) % leaf_count;\\n                write_index = (write_index + 1) % leaf_count;\\n                bit_check <<= 1;\\n                continue;\\n            }\\n\\n            if (flags & bit_check == bit_check) {\\n                scratch_2 = (read_index + 1) % leaf_count;\\n\\n                leafs[write_index] = hash_pair(leafs[scratch_2], leafs[read_index], orders & bit_check == bit_check);\\n                update_leafs[write_index] =\\n                    hash_pair(update_leafs[scratch_2], update_leafs[read_index], orders & bit_check == bit_check);\\n\\n                read_index += 2;\\n            } else {\\n                scratch = proof[proof_index++];\\n\\n                leafs[write_index] = hash_pair(leafs[read_index], scratch, orders & bit_check == bit_check);\\n                update_leafs[write_index] =\\n                    hash_pair(update_leafs[read_index], scratch, orders & bit_check == bit_check);\\n\\n                read_index += 1;\\n            }\\n\\n            read_index %= leaf_count;\\n            write_index = (write_index + 1) % leaf_count;\\n            bit_check <<= 1;\\n        }\\n    }\\n\\n    // Get the original and updated Element Merkle Root,\\n    // given bytes32 elements in memory, bytes32 update elements in memory, and an Existence Multi Proof\\n    function get_roots_from_multi_proof_update(\\n        bytes32[] memory elements,\\n        bytes32[] memory update_elements,\\n        bytes32[] memory proof\\n    ) internal pure returns (bytes32, bytes32) {\\n        (bytes32[] memory leafs, bytes32[] memory update_leafs) =\\n            get_reversed_leafs_from_current_and_update_elements(elements, update_elements);\\n        return get_roots_from_leafs_and_multi_proof_update(leafs, update_leafs, proof);\\n    }\\n\\n    // Get the original Element Merkle Root, given an Append Proof\\n    function get_root_from_append_proof(bytes32[] memory proof) internal pure returns (bytes32 hash) {\\n        uint256 proof_index = bit_count_32(uint32(uint256(proof[0])));\\n        hash = proof[proof_index];\\n\\n        while (proof_index > 1) {\\n            proof_index -= 1;\\n            hash = hash_node(proof[proof_index], hash);\\n        }\\n    }\\n\\n    // Get the original and updated Element Merkle Root, given append leaf and an Append Proof\\n    function get_roots_from_leaf_and_append_proof_single_append(bytes32 append_leaf, bytes32[] memory proof)\\n        internal\\n        pure\\n        returns (bytes32 hash, bytes32 scratch)\\n    {\\n        uint256 proof_index = bit_count_32(uint32(uint256(proof[0])));\\n        hash = proof[proof_index];\\n        append_leaf = hash_node(hash, append_leaf);\\n\\n        while (proof_index > 1) {\\n            proof_index -= 1;\\n            scratch = proof[proof_index];\\n            append_leaf = hash_node(scratch, append_leaf);\\n            hash = hash_node(scratch, hash);\\n        }\\n\\n        return (hash, append_leaf);\\n    }\\n\\n    // Get the original and updated Element Merkle Root, given a bytes32 append element in memory and an Append Proof\\n    function get_roots_from_append_proof_single_append(bytes32 append_element, bytes32[] memory proof)\\n        internal\\n        pure\\n        returns (bytes32 append_leaf, bytes32)\\n    {\\n        append_leaf = keccak256(abi.encodePacked(bytes1(0), append_element));\\n        return get_roots_from_leaf_and_append_proof_single_append(append_leaf, proof);\\n    }\\n\\n    // Get leafs from bytes32 elements in memory\\n    function get_leafs_from_elements(bytes32[] memory elements) internal pure returns (bytes32[] memory leafs) {\\n        uint256 element_count = elements.length;\\n        leafs = new bytes32[](element_count);\\n\\n        while (element_count > 0) {\\n            element_count -= 1;\\n            leafs[element_count] = keccak256(abi.encodePacked(bytes1(0), elements[element_count]));\\n        }\\n    }\\n\\n    // Get the original and updated Element Merkle Root, given append leafs and an Append Proof\\n    function get_roots_from_leafs_and_append_proof_multi_append(bytes32[] memory append_leafs, bytes32[] memory proof)\\n        internal\\n        pure\\n        returns (bytes32 hash, bytes32)\\n    {\\n        uint256 leaf_count = append_leafs.length;\\n        uint256 write_index;\\n        uint256 read_index;\\n        uint256 offset = uint256(proof[0]);\\n        uint256 index = offset;\\n\\n        // reuse leaf_count variable as upper_bound, since leaf_count no longer needed\\n        leaf_count += offset;\\n        leaf_count -= 1;\\n        uint256 proof_index = bit_count_32(uint32(offset));\\n        hash = proof[proof_index];\\n\\n        while (leaf_count > 0) {\\n            if ((write_index == 0) && (index & 1 == 1)) {\\n                append_leafs[0] = hash_node(proof[proof_index], append_leafs[read_index]);\\n                proof_index -= 1;\\n                read_index += 1;\\n\\n                if (proof_index > 0) {\\n                    hash = hash_node(proof[proof_index], hash);\\n                }\\n\\n                write_index = 1;\\n                index += 1;\\n            } else if (index < leaf_count) {\\n                append_leafs[write_index++] = hash_node(append_leafs[read_index++], append_leafs[read_index]);\\n                read_index += 1;\\n                index += 2;\\n            }\\n\\n            if (index >= leaf_count) {\\n                if (index == leaf_count) {\\n                    append_leafs[write_index] = append_leafs[read_index];\\n                }\\n\\n                read_index = 0;\\n                write_index = 0;\\n                leaf_count >>= 1;\\n                offset >>= 1;\\n                index = offset;\\n            }\\n        }\\n\\n        return (hash, append_leafs[0]);\\n    }\\n\\n    // Get the original and updated Element Merkle Root, given bytes32 append elements in memory and an Append Proof\\n    function get_roots_from_append_proof_multi_append(bytes32[] memory append_elements, bytes32[] memory proof)\\n        internal\\n        pure\\n        returns (bytes32, bytes32)\\n    {\\n        return get_roots_from_leafs_and_append_proof_multi_append(get_leafs_from_elements(append_elements), proof);\\n    }\\n\\n    // Get the updated Element Merkle Root, given an append leaf and an Append Proof\\n    function get_new_root_from_leafs_and_append_proof_single_append(bytes32 append_leaf, bytes32[] memory proof)\\n        internal\\n        pure\\n        returns (bytes32 append_hash)\\n    {\\n        uint256 proof_index = bit_count_32(uint32(uint256(proof[0])));\\n        append_hash = hash_node(proof[proof_index], append_leaf);\\n\\n        while (proof_index > 1) {\\n            proof_index -= 1;\\n            append_hash = hash_node(proof[proof_index], append_hash);\\n        }\\n    }\\n\\n    // Get the updated Element Merkle Root, given a bytes32 append elements in memory and an Append Proof\\n    function get_new_root_from_append_proof_single_append(bytes32 append_element, bytes32[] memory proof)\\n        internal\\n        pure\\n        returns (bytes32 append_leaf)\\n    {\\n        append_leaf = keccak256(abi.encodePacked(bytes1(0), append_element));\\n        return get_new_root_from_leafs_and_append_proof_single_append(append_leaf, proof);\\n    }\\n\\n    // Get the updated Element Merkle Root, given append leafs and an Append Proof\\n    function get_new_root_from_leafs_and_append_proof_multi_append(\\n        bytes32[] memory append_leafs,\\n        bytes32[] memory proof\\n    ) internal pure returns (bytes32) {\\n        uint256 leaf_count = append_leafs.length;\\n        uint256 write_index;\\n        uint256 read_index;\\n        uint256 offset = uint256(proof[0]);\\n        uint256 index = offset;\\n\\n        // reuse leaf_count variable as upper_bound, since leaf_count no longer needed\\n        leaf_count += offset;\\n        leaf_count -= 1;\\n        uint256 proof_index = proof.length - 1;\\n\\n        while (leaf_count > 0) {\\n            if ((write_index == 0) && (index & 1 == 1)) {\\n                append_leafs[0] = hash_node(proof[proof_index], append_leafs[read_index]);\\n\\n                read_index += 1;\\n                proof_index -= 1;\\n                write_index = 1;\\n                index += 1;\\n            } else if (index < leaf_count) {\\n                append_leafs[write_index++] = hash_node(append_leafs[read_index++], append_leafs[read_index++]);\\n\\n                index += 2;\\n            }\\n\\n            if (index >= leaf_count) {\\n                if (index == leaf_count) {\\n                    append_leafs[write_index] = append_leafs[read_index];\\n                }\\n\\n                read_index = 0;\\n                write_index = 0;\\n                leaf_count >>= 1;\\n                offset >>= 1;\\n                index = offset;\\n            }\\n        }\\n\\n        return append_leafs[0];\\n    }\\n\\n    // Get the updated Element Merkle Root, given bytes32 append elements in memory and an Append Proof\\n    function get_new_root_from_append_proof_multi_append(bytes32[] memory append_elements, bytes32[] memory proof)\\n        internal\\n        pure\\n        returns (bytes32)\\n    {\\n        return get_new_root_from_leafs_and_append_proof_multi_append(get_leafs_from_elements(append_elements), proof);\\n    }\\n\\n    // Get the original Element Merkle Root and derive Append Proof, given an index, an append leaf, and a Single Proof\\n    function get_append_proof_from_leaf_and_single_proof(uint256 index, bytes32 leaf, bytes32[] memory proof)\\n        internal\\n        pure\\n        returns (bytes32 append_hash, bytes32[] memory append_proof)\\n    {\\n        uint256 proof_index = proof.length - 1;\\n        uint256 append_node_index = uint256(proof[0]);\\n        uint256 upper_bound = append_node_index - 1;\\n        uint256 append_proof_index = bit_count_32(uint32(append_node_index)) + 1;\\n        append_proof = new bytes32[](append_proof_index);\\n        append_proof[0] = bytes32(append_node_index);\\n        bytes32 scratch;\\n\\n        while (proof_index > 0) {\\n            if (index != upper_bound || (index & 1 == 1)) {\\n                scratch = proof[proof_index];\\n\\n                leaf = (index & 1 == 1) ? hash_node(scratch, leaf) : hash_node(leaf, scratch);\\n\\n                if (append_node_index & 1 == 1) {\\n                    append_proof_index -= 1;\\n                    append_proof[append_proof_index] = scratch;\\n                    append_hash = hash_node(scratch, append_hash);\\n                }\\n\\n                proof_index -= 1;\\n            } else if (append_node_index & 1 == 1) {\\n                append_proof_index -= 1;\\n                append_proof[append_proof_index] = leaf;\\n                append_hash = leaf;\\n            }\\n\\n            index >>= 1;\\n            upper_bound >>= 1;\\n            append_node_index >>= 1;\\n        }\\n\\n        require(append_proof_index == 2 || append_hash == leaf, \\\"INVALID_PROOF\\\");\\n\\n        if (append_proof_index == 2) {\\n            append_proof[1] = leaf;\\n        }\\n    }\\n\\n    // Get the original Element Merkle Root and derive Append Proof, given an index, a bytes32 element, and a Single Proof\\n    function get_append_proof_from_single_proof(uint256 index, bytes32 element, bytes32[] memory proof)\\n        internal\\n        pure\\n        returns (bytes32 leaf, bytes32[] memory)\\n    {\\n        leaf = keccak256(abi.encodePacked(bytes1(0), element));\\n        return get_append_proof_from_leaf_and_single_proof(index, leaf, proof);\\n    }\\n\\n    // Get the original Element Merkle Root and derive Append Proof, given an index, a leaf, an update leaf, and a Single Proof\\n    function get_append_proof_from_leaf_and_single_proof_update(\\n        uint256 index,\\n        bytes32 leaf,\\n        bytes32 update_leaf,\\n        bytes32[] memory proof\\n    ) internal pure returns (bytes32 append_hash, bytes32[] memory append_proof) {\\n        uint256 proof_index = proof.length - 1;\\n        uint256 append_node_index = uint256(proof[0]);\\n        uint256 upper_bound = append_node_index - 1;\\n        uint256 append_proof_index = bit_count_32(uint32(append_node_index)) + 1;\\n        append_proof = new bytes32[](append_proof_index);\\n        append_proof[0] = bytes32(append_node_index);\\n        bytes32 scratch;\\n\\n        while (proof_index > 0) {\\n            if (index != upper_bound || (index & 1 == 1)) {\\n                scratch = proof[proof_index];\\n\\n                leaf = (index & 1 == 1) ? hash_node(scratch, leaf) : hash_node(leaf, scratch);\\n\\n                update_leaf = (index & 1 == 1) ? hash_node(scratch, update_leaf) : hash_node(update_leaf, scratch);\\n\\n                if (append_node_index & 1 == 1) {\\n                    append_proof_index -= 1;\\n                    append_proof[append_proof_index] = scratch;\\n                    append_hash = hash_node(scratch, append_hash);\\n                }\\n\\n                proof_index -= 1;\\n            } else if (append_node_index & 1 == 1) {\\n                append_proof_index -= 1;\\n                append_proof[append_proof_index] = update_leaf;\\n                append_hash = leaf;\\n            }\\n\\n            index >>= 1;\\n            upper_bound >>= 1;\\n            append_node_index >>= 1;\\n        }\\n\\n        require(append_proof_index == 2 || append_hash == leaf, \\\"INVALID_PROOF\\\");\\n\\n        if (append_proof_index == 2) {\\n            append_proof[1] = update_leaf;\\n        }\\n    }\\n\\n    // Get the original Element Merkle Root and derive Append Proof,\\n    // given an index, a bytes32 element, a bytes32 update element, and a Single Proof\\n    function get_append_proof_from_single_proof_update(\\n        uint256 index,\\n        bytes32 element,\\n        bytes32 update_element,\\n        bytes32[] memory proof\\n    ) internal pure returns (bytes32 leaf, bytes32[] memory) {\\n        leaf = keccak256(abi.encodePacked(bytes1(0), element));\\n        bytes32 update_leaf = keccak256(abi.encodePacked(bytes1(0), update_element));\\n        return get_append_proof_from_leaf_and_single_proof_update(index, leaf, update_leaf, proof);\\n    }\\n\\n    // Hashes leaf at read index and next index (circular) to write index\\n    function hash_within_leafs(\\n        bytes32[] memory leafs,\\n        uint256 write_index,\\n        uint256 read_index,\\n        uint256 leaf_count,\\n        bool order\\n    ) internal pure {\\n        leafs[write_index] = order\\n            ? hash_node(leafs[(read_index + 1) % leaf_count], leafs[read_index])\\n            : hash_node(leafs[read_index], leafs[(read_index + 1) % leaf_count]);\\n    }\\n\\n    // Hashes value with leaf at read index to write index\\n    function hash_with_leafs(bytes32[] memory leafs, bytes32 value, uint256 write_index, uint256 read_index, bool order)\\n        internal\\n        pure\\n    {\\n        leafs[write_index] = order ? hash_node(leafs[read_index], value) : hash_node(value, leafs[read_index]);\\n    }\\n\\n    // Get the original Element Merkle Root and derive Append Proof, given leafs and an Existence Multi Proof\\n    function get_append_proof_from_leafs_and_multi_proof(bytes32[] memory leafs, bytes32[] memory proof)\\n        internal\\n        pure\\n        returns (bytes32 append_hash, bytes32[] memory append_proof)\\n    {\\n        uint256 leaf_count = leafs.length;\\n        uint256 read_index;\\n        uint256 write_index;\\n        uint256 proof_index = 4;\\n        uint256 append_node_index = uint256(proof[0]);\\n        uint256 append_proof_index = uint256(bit_count_32(uint32(append_node_index))) + 1;\\n        append_proof = new bytes32[](append_proof_index);\\n        append_proof[0] = bytes32(append_node_index);\\n        bytes32 bit_check = 0x0000000000000000000000000000000000000000000000000000000000000001;\\n        bytes32 skips = proof[2];\\n        uint256 read_index_of_append_node;\\n        bool scratch;\\n\\n        while (true) {\\n            if (skips & bit_check == bit_check) {\\n                if (proof[1] & bit_check == bit_check) {\\n                    read_index = (write_index == 0 ? leaf_count : write_index) - 1;\\n\\n                    // reuse bit_check as scratch variable\\n                    bit_check = leafs[read_index];\\n\\n                    require(append_proof_index == 2 || append_hash == bit_check, \\\"INVALID_PROOF\\\");\\n\\n                    if (append_proof_index == 2) {\\n                        append_proof[1] = bit_check;\\n                    }\\n\\n                    return (append_hash, append_proof);\\n                }\\n\\n                if (append_node_index & 1 == 1) {\\n                    append_proof_index -= 1;\\n                    append_hash = leafs[read_index]; // TODO scratch this leafs[read_index] above\\n                    append_proof[append_proof_index] = leafs[read_index];\\n                }\\n\\n                read_index_of_append_node = write_index;\\n                append_node_index >>= 1;\\n\\n                leafs[write_index] = leafs[read_index];\\n\\n                read_index = (read_index + 1) % leaf_count;\\n                write_index = (write_index + 1) % leaf_count;\\n                bit_check <<= 1;\\n                continue;\\n            }\\n\\n            scratch = proof[1] & bit_check == bit_check;\\n\\n            if (read_index_of_append_node == read_index) {\\n                if (append_node_index & 1 == 1) {\\n                    append_proof_index -= 1;\\n\\n                    if (scratch) {\\n                        // reuse read_index_of_append_node as temporary scratch variable\\n                        read_index_of_append_node = (read_index + 1) % leaf_count;\\n\\n                        append_hash = hash_node(leafs[read_index_of_append_node], append_hash);\\n                        append_proof[append_proof_index] = leafs[read_index_of_append_node];\\n                    } else {\\n                        append_hash = hash_node(proof[proof_index], append_hash);\\n                        append_proof[append_proof_index] = proof[proof_index];\\n                    }\\n                }\\n\\n                read_index_of_append_node = write_index;\\n                append_node_index >>= 1;\\n            }\\n\\n            if (scratch) {\\n                scratch = proof[3] & bit_check == bit_check;\\n                hash_within_leafs(leafs, write_index, read_index, leaf_count, scratch);\\n                read_index += 2;\\n            } else {\\n                scratch = proof[3] & bit_check == bit_check;\\n                hash_with_leafs(leafs, proof[proof_index], write_index, read_index, scratch);\\n                proof_index += 1;\\n                read_index += 1;\\n            }\\n\\n            read_index %= leaf_count;\\n            write_index = (write_index + 1) % leaf_count;\\n            bit_check <<= 1;\\n        }\\n    }\\n\\n    // Get the original Element Merkle Root and derive Append Proof, given bytes32 elements in memory and an Existence Multi Proof\\n    function get_append_proof_from_multi_proof(bytes32[] memory elements, bytes32[] memory proof)\\n        internal\\n        pure\\n        returns (bytes32, bytes32[] memory)\\n    {\\n        return get_append_proof_from_leafs_and_multi_proof(get_reversed_leafs_from_elements(elements), proof);\\n    }\\n\\n    // Get combined current and update leafs from current bytes32 elements in memory and update bytes32 elements in memory, in reverse order\\n    function get_reversed_combined_leafs_from_current_and_update_elements(\\n        bytes32[] memory elements,\\n        bytes32[] memory update_elements\\n    ) internal pure returns (bytes32[] memory combined_leafs) {\\n        uint256 element_count = elements.length;\\n        require(update_elements.length == element_count, \\\"LENGTH_MISMATCH\\\");\\n\\n        combined_leafs = new bytes32[](element_count << 1);\\n        // uint256 read_index = element_count - 1;\\n        // uint256 write_index;\\n\\n        // while (write_index < element_count) {\\n        //     combined_leafs[write_index] = keccak256(abi.encodePacked(bytes1(0), elements[read_index]));\\n        //     combined_leafs[element_count + write_index] =\\n        //         keccak256(abi.encodePacked(bytes1(0), update_elements[read_index]));\\n        //     write_index += 1;\\n        //     read_index -= 1;\\n        // }\\n\\n        for (uint64 i = 0; i < element_count; i++) {\\n            combined_leafs[i] = keccak256(abi.encodePacked(bytes1(0), elements[element_count - 1 - i]));\\n            combined_leafs[element_count + i] =\\n                keccak256(abi.encodePacked(bytes1(0), update_elements[element_count - 1 - i]));\\n        }\\n    }\\n\\n    // Copy leaf and update leaf at read indices and to write indices\\n    function copy_within_combined_leafs(\\n        bytes32[] memory combined_leafs,\\n        uint256 write_index,\\n        uint256 read_index,\\n        uint256 leaf_count\\n    ) internal pure {\\n        combined_leafs[write_index] = combined_leafs[read_index];\\n        combined_leafs[leaf_count + write_index] = combined_leafs[leaf_count + read_index];\\n    }\\n\\n    // Hashes leaf and update leaf at read indices and next indices (circular) to write indices\\n    function hash_within_combined_leafs(\\n        bytes32[] memory combined_leafs,\\n        uint256 write_index,\\n        uint256 read_index,\\n        uint256 leaf_count,\\n        bool order\\n    ) internal pure {\\n        uint256 scratch = (read_index + 1) % leaf_count;\\n\\n        combined_leafs[write_index] = order\\n            ? hash_node(combined_leafs[scratch], combined_leafs[read_index])\\n            : hash_node(combined_leafs[read_index], combined_leafs[scratch]);\\n\\n        combined_leafs[leaf_count + write_index] = order\\n            ? hash_node(combined_leafs[leaf_count + scratch], combined_leafs[leaf_count + read_index])\\n            : hash_node(combined_leafs[leaf_count + read_index], combined_leafs[leaf_count + scratch]);\\n    }\\n\\n    // Hashes value with leaf and update leaf at read indices to write indices\\n    function hash_with_combined_leafs(\\n        bytes32[] memory combined_leafs,\\n        bytes32 value,\\n        uint256 write_index,\\n        uint256 read_index,\\n        uint256 leaf_count,\\n        bool order\\n    ) internal pure {\\n        combined_leafs[write_index] =\\n            order ? hash_node(combined_leafs[read_index], value) : hash_node(value, combined_leafs[read_index]);\\n\\n        combined_leafs[leaf_count + write_index] = order\\n            ? hash_node(combined_leafs[leaf_count + read_index], value)\\n            : hash_node(value, combined_leafs[leaf_count + read_index]);\\n    }\\n\\n    // Get the original Element Merkle Root and derive Append Proof, given combined leafs and update leafs and an Existence Multi Proof\\n    function get_append_proof_from_leafs_and_multi_proof_update(bytes32[] memory combined_leafs, bytes32[] memory proof)\\n        internal\\n        pure\\n        returns (bytes32 append_hash, bytes32[] memory append_proof)\\n    {\\n        uint256 leaf_count = combined_leafs.length >> 1;\\n        uint256 read_index;\\n        uint256 write_index;\\n        uint256 read_index_of_append_node;\\n        uint256 proof_index = 4;\\n        uint256 append_node_index = uint256(proof[0]);\\n        uint256 append_proof_index = bit_count_32(uint32(append_node_index)) + 1;\\n        append_proof = new bytes32[](append_proof_index);\\n        append_proof[0] = bytes32(append_node_index);\\n        bytes32 bit_check = 0x0000000000000000000000000000000000000000000000000000000000000001;\\n        bool scratch;\\n\\n        while (true) {\\n            if (proof[2] & bit_check == bit_check) {\\n                if (proof[1] & bit_check == bit_check) {\\n                    read_index = (write_index == 0 ? leaf_count : write_index) - 1;\\n\\n                    // reuse bit_check as scratch variable\\n                    bit_check = combined_leafs[read_index];\\n\\n                    require(append_proof_index == 2 || append_hash == bit_check, \\\"INVALID_PROOF\\\");\\n\\n                    if (append_proof_index == 2) {\\n                        append_proof[1] = combined_leafs[leaf_count + read_index];\\n                    }\\n\\n                    return (bit_check, append_proof);\\n                }\\n\\n                if (append_node_index & 1 == 1) {\\n                    append_proof_index -= 1;\\n                    append_hash = combined_leafs[read_index];\\n                    append_proof[append_proof_index] = combined_leafs[leaf_count + read_index];\\n                }\\n\\n                read_index_of_append_node = write_index;\\n                append_node_index >>= 1;\\n\\n                copy_within_combined_leafs(combined_leafs, write_index, read_index, leaf_count);\\n\\n                read_index = (read_index + 1) % leaf_count;\\n                write_index = (write_index + 1) % leaf_count;\\n                bit_check <<= 1;\\n                continue;\\n            }\\n\\n            scratch = proof[1] & bit_check == bit_check;\\n\\n            if (read_index_of_append_node == read_index) {\\n                if (append_node_index & 1 == 1) {\\n                    append_proof_index -= 1;\\n\\n                    if (scratch) {\\n                        // use read_index_of_append_node as temporary scratch\\n                        read_index_of_append_node = (read_index + 1) % leaf_count;\\n\\n                        append_hash = hash_node(combined_leafs[read_index_of_append_node], append_hash);\\n                        append_proof[append_proof_index] = combined_leafs[leaf_count + read_index_of_append_node];\\n                    } else {\\n                        append_hash = hash_node(proof[proof_index], append_hash);\\n                        append_proof[append_proof_index] = proof[proof_index];\\n                    }\\n                }\\n\\n                read_index_of_append_node = write_index;\\n                append_node_index >>= 1;\\n            }\\n\\n            if (scratch) {\\n                scratch = proof[3] & bit_check == bit_check;\\n\\n                hash_within_combined_leafs(combined_leafs, write_index, read_index, leaf_count, scratch);\\n\\n                read_index += 2;\\n            } else {\\n                scratch = proof[3] & bit_check == bit_check;\\n\\n                hash_with_combined_leafs(\\n                    combined_leafs, proof[proof_index], write_index, read_index, leaf_count, scratch\\n                );\\n\\n                proof_index += 1;\\n                read_index += 1;\\n            }\\n\\n            read_index %= leaf_count;\\n            write_index = (write_index + 1) % leaf_count;\\n            bit_check <<= 1;\\n        }\\n    }\\n\\n    // Get the original Element Merkle Root and derive Append Proof,\\n    // given bytes32 elements in memory, bytes32 update elements in memory, and an Existence Multi Proof\\n    function get_append_proof_from_multi_proof_update(\\n        bytes32[] memory elements,\\n        bytes32[] memory update_elements,\\n        bytes32[] memory proof\\n    ) internal pure returns (bytes32, bytes32[] memory) {\\n        return get_append_proof_from_leafs_and_multi_proof_update(\\n            get_reversed_combined_leafs_from_current_and_update_elements(elements, update_elements), proof\\n        );\\n    }\\n\\n    // INTERFACE: Check if bytes32 element exists at index, given a root and a Single Proof\\n    function element_exists(bytes32 root, uint256 index, bytes32 element, bytes32[] memory proof)\\n        internal\\n        pure\\n        returns (bool)\\n    {\\n        return hash_node(proof[0], get_root_from_single_proof(index, element, proof)) == root;\\n    }\\n\\n    // INTERFACE: Check if bytes32 elements in memory exist, given a root and a Single Proof\\n    function elements_exist(bytes32 root, bytes32[] memory elements, bytes32[] memory proof)\\n        internal\\n        pure\\n        returns (bool)\\n    {\\n        return hash_node(proof[0], get_root_from_multi_proof(elements, proof)) == root;\\n    }\\n\\n    // INTERFACE: Get the indices of the bytes32 elements in memory, given an Existence Multi Proof\\n    function get_indices(bytes32[] memory elements, bytes32[] memory proof) internal pure returns (uint256[] memory) {\\n        return get_indices_from_multi_proof(elements.length, proof[1], proof[2], proof[3]);\\n    }\\n\\n    // INTERFACE: Check tree size, given a Size Proof\\n    function verify_size_with_proof(bytes32 root, uint256 size, bytes32[] memory proof) internal pure returns (bool) {\\n        if (root == bytes32(0) && size == 0) return true;\\n\\n        return hash_node(bytes32(size), get_root_from_size_proof(size, proof)) == root;\\n    }\\n\\n    // INTERFACE: Check tree size, given a the Element Merkle Root\\n    function verify_size(bytes32 root, uint256 size, bytes32 element_root) internal pure returns (bool) {\\n        if (root == bytes32(0) && size == 0) return true;\\n\\n        return hash_node(bytes32(size), element_root) == root;\\n    }\\n\\n    // INTERFACE: Try to update a bytes32 element, given a root, and index, an bytes32 element, and a Single Proof\\n    function try_update_one(\\n        bytes32 root,\\n        uint256 index,\\n        bytes32 element,\\n        bytes32 update_element,\\n        bytes32[] memory proof\\n    ) internal pure returns (bytes32 new_element_root) {\\n        bytes32 total_element_count = proof[0];\\n\\n        require(root != bytes32(0) || total_element_count == bytes32(0), \\\"EMPTY_TREE\\\");\\n\\n        bytes32 old_element_root;\\n        (old_element_root, new_element_root) = get_roots_from_single_proof_update(index, element, update_element, proof);\\n\\n        require(hash_node(total_element_count, old_element_root) == root, \\\"INVALID_PROOF\\\");\\n\\n        return hash_node(total_element_count, new_element_root);\\n    }\\n\\n    // INTERFACE: Try to update bytes32 elements in memory, given a root, bytes32 elements in memory, and an Existence Multi Proof\\n    function try_update_many(\\n        bytes32 root,\\n        bytes32[] memory elements,\\n        bytes32[] memory update_elements,\\n        bytes32[] memory proof\\n    ) internal pure returns (bytes32 new_element_root) {\\n        bytes32 total_element_count = proof[0];\\n\\n        require(root != bytes32(0) || total_element_count == bytes32(0), \\\"EMPTY_TREE\\\");\\n\\n        bytes32 old_element_root;\\n        (old_element_root, new_element_root) = get_roots_from_multi_proof_update(elements, update_elements, proof);\\n\\n        require(hash_node(total_element_count, old_element_root) == root, \\\"INVALID_PROOF\\\");\\n\\n        return hash_node(total_element_count, new_element_root);\\n    }\\n\\n    // INTERFACE: Try to append a bytes32 element, given a root and an Append Proof\\n    function try_append_one(bytes32 root, bytes32 append_element, bytes32[] memory proof)\\n        internal\\n        pure\\n        returns (bytes32 new_element_root)\\n    {\\n        bytes32 total_element_count = proof[0];\\n\\n        require((root == bytes32(0)) == (total_element_count == bytes32(0)), \\\"INVALID_TREE\\\");\\n\\n        if (root == bytes32(0)) return hash_node(bytes32(uint256(1)), get_root_from_one(append_element));\\n\\n        bytes32 old_element_root;\\n        (old_element_root, new_element_root) = get_roots_from_append_proof_single_append(append_element, proof);\\n\\n        require(hash_node(total_element_count, old_element_root) == root, \\\"INVALID_PROOF\\\");\\n\\n        return hash_node(bytes32(uint256(total_element_count) + 1), new_element_root);\\n    }\\n\\n    // INTERFACE: Try to append bytes32 elements in memory, given a root and an Append Proof\\n    function try_append_many(bytes32 root, bytes32[] memory append_elements, bytes32[] memory proof)\\n        internal\\n        pure\\n        returns (bytes32 new_element_root)\\n    {\\n        bytes32 total_element_count = proof[0];\\n\\n        require((root == bytes32(0)) == (total_element_count == bytes32(0)), \\\"INVALID_TREE\\\");\\n\\n        if (root == bytes32(0)) {\\n            return hash_node(bytes32(append_elements.length), get_root_from_many(append_elements));\\n        }\\n\\n        bytes32 old_element_root;\\n        (old_element_root, new_element_root) = get_roots_from_append_proof_multi_append(append_elements, proof);\\n\\n        require(hash_node(total_element_count, old_element_root) == root, \\\"INVALID_PROOF\\\");\\n\\n        return hash_node(bytes32(uint256(total_element_count) + append_elements.length), new_element_root);\\n    }\\n\\n    // INTERFACE: Try to append a bytes32 element, given a root, an index, a bytes32 element, and a Single Proof\\n    function try_append_one_using_one(\\n        bytes32 root,\\n        uint256 index,\\n        bytes32 element,\\n        bytes32 append_element,\\n        bytes32[] memory proof\\n    ) internal pure returns (bytes32 element_root) {\\n        bytes32 total_element_count = proof[0];\\n\\n        require(root != bytes32(0) || total_element_count == bytes32(0), \\\"EMPTY_TREE\\\");\\n\\n        bytes32[] memory append_proof;\\n        (element_root, append_proof) = get_append_proof_from_single_proof(index, element, proof);\\n\\n        require(hash_node(total_element_count, element_root) == root, \\\"INVALID_PROOF\\\");\\n\\n        element_root = get_new_root_from_append_proof_single_append(append_element, append_proof);\\n\\n        return hash_node(bytes32(uint256(total_element_count) + 1), element_root);\\n    }\\n\\n    // INTERFACE: Try to append bytes32 elements in memory, given a root, an index, a bytes32 element, and a Single Proof\\n    function try_append_many_using_one(\\n        bytes32 root,\\n        uint256 index,\\n        bytes32 element,\\n        bytes32[] memory append_elements,\\n        bytes32[] memory proof\\n    ) internal pure returns (bytes32 element_root) {\\n        bytes32 total_element_count = proof[0];\\n\\n        require(root != bytes32(0) || total_element_count == bytes32(0), \\\"EMPTY_TREE\\\");\\n\\n        bytes32[] memory append_proof;\\n        (element_root, append_proof) = get_append_proof_from_single_proof(index, element, proof);\\n\\n        require(hash_node(total_element_count, element_root) == root, \\\"INVALID_PROOF\\\");\\n\\n        element_root = get_new_root_from_append_proof_multi_append(append_elements, append_proof);\\n\\n        return hash_node(bytes32(uint256(total_element_count) + append_elements.length), element_root);\\n    }\\n\\n    // INTERFACE: Try to append a bytes32 element, given a root, bytes32 elements in memory, and an Existence Multi Proof\\n    function try_append_one_using_many(\\n        bytes32 root,\\n        bytes32[] memory elements,\\n        bytes32 append_element,\\n        bytes32[] memory proof\\n    ) internal pure returns (bytes32 element_root) {\\n        bytes32 total_element_count = proof[0];\\n\\n        require(root != bytes32(0) || total_element_count == bytes32(0), \\\"EMPTY_TREE\\\");\\n\\n        bytes32[] memory append_proof;\\n        (element_root, append_proof) = get_append_proof_from_multi_proof(elements, proof);\\n\\n        require(hash_node(total_element_count, element_root) == root, \\\"INVALID_PROOF\\\");\\n\\n        element_root = get_new_root_from_append_proof_single_append(append_element, append_proof);\\n\\n        return hash_node(bytes32(uint256(total_element_count) + 1), element_root);\\n    }\\n\\n    // INTERFACE: Try to append bytes32 elements in memory, given a root, bytes32 elements in memory, and an Existence Multi Proof\\n    function try_append_many_using_many(\\n        bytes32 root,\\n        bytes32[] memory elements,\\n        bytes32[] memory append_elements,\\n        bytes32[] memory proof\\n    ) internal pure returns (bytes32 element_root) {\\n        bytes32 total_element_count = proof[0];\\n\\n        require(root != bytes32(0) || total_element_count == bytes32(0), \\\"EMPTY_TREE\\\");\\n\\n        bytes32[] memory append_proof;\\n        (element_root, append_proof) = get_append_proof_from_multi_proof(elements, proof);\\n\\n        require(hash_node(total_element_count, element_root) == root, \\\"INVALID_PROOF\\\");\\n\\n        element_root = get_new_root_from_append_proof_multi_append(append_elements, append_proof);\\n\\n        return hash_node(bytes32(uint256(total_element_count) + append_elements.length), element_root);\\n    }\\n\\n    // INTERFACE: Try to update a bytes32 element and append a bytes32 element,\\n    // given a root, an index, a bytes32 element, and a Single Proof\\n    function try_update_one_and_append_one(\\n        bytes32 root,\\n        uint256 index,\\n        bytes32 element,\\n        bytes32 update_element,\\n        bytes32 append_element,\\n        bytes32[] memory proof\\n    ) internal pure returns (bytes32 element_root) {\\n        bytes32 total_element_count = proof[0];\\n\\n        require(root != bytes32(0) || total_element_count == bytes32(0), \\\"EMPTY_TREE\\\");\\n\\n        bytes32[] memory append_proof;\\n        (element_root, append_proof) = get_append_proof_from_single_proof_update(index, element, update_element, proof);\\n\\n        require(hash_node(total_element_count, element_root) == root, \\\"INVALID_PROOF\\\");\\n\\n        element_root = get_new_root_from_append_proof_single_append(append_element, append_proof);\\n\\n        return hash_node(bytes32(uint256(total_element_count) + 1), element_root);\\n    }\\n\\n    // INTERFACE: Try to update a bytes32 element and append bytes32 elements in memory,\\n    // given a root, an index, a bytes32 element, and a Single Proof\\n    function try_update_one_and_append_many(\\n        bytes32 root,\\n        uint256 index,\\n        bytes32 element,\\n        bytes32 update_element,\\n        bytes32[] memory append_elements,\\n        bytes32[] memory proof\\n    ) internal pure returns (bytes32 element_root) {\\n        bytes32 total_element_count = proof[0];\\n\\n        require(root != bytes32(0) || total_element_count == bytes32(0), \\\"EMPTY_TREE\\\");\\n\\n        bytes32[] memory append_proof;\\n        (element_root, append_proof) = get_append_proof_from_single_proof_update(index, element, update_element, proof);\\n\\n        require(hash_node(total_element_count, element_root) == root, \\\"INVALID_PROOF\\\");\\n\\n        element_root = get_new_root_from_append_proof_multi_append(append_elements, append_proof);\\n\\n        return hash_node(bytes32(uint256(total_element_count) + append_elements.length), element_root);\\n    }\\n\\n    // INTERFACE: Try to update bytes32 elements in memory and append a bytes32 element,\\n    // given a root, bytes32 elements in memory, and a Single Proof\\n    function try_update_many_and_append_one(\\n        bytes32 root,\\n        bytes32[] memory elements,\\n        bytes32[] memory update_elements,\\n        bytes32 append_element,\\n        bytes32[] memory proof\\n    ) internal pure returns (bytes32 element_root) {\\n        bytes32 total_element_count = proof[0];\\n\\n        require(root != bytes32(0) || total_element_count == bytes32(0), \\\"EMPTY_TREE\\\");\\n\\n        bytes32[] memory append_proof;\\n        (element_root, append_proof) = get_append_proof_from_multi_proof_update(elements, update_elements, proof);\\n\\n        require(hash_node(total_element_count, element_root) == root, \\\"INVALID_PROOF\\\");\\n\\n        element_root = get_new_root_from_append_proof_single_append(append_element, append_proof);\\n\\n        return hash_node(bytes32(uint256(total_element_count) + 1), element_root);\\n    }\\n\\n    // INTERFACE: Try to update bytes32 elements in memory and append bytes32 elements in memory,\\n    // given a root, bytes32 elements in memory, and an Existence Multi Proof\\n    function try_update_many_and_append_many(\\n        bytes32 root,\\n        bytes32[] memory elements,\\n        bytes32[] memory update_elements,\\n        bytes32[] memory append_elements,\\n        bytes32[] memory proof\\n    ) internal pure returns (bytes32 element_root) {\\n        bytes32 total_element_count = proof[0];\\n\\n        require(root != bytes32(0) || total_element_count == bytes32(0), \\\"EMPTY_TREE\\\");\\n\\n        bytes32[] memory append_proof;\\n        (element_root, append_proof) = get_append_proof_from_multi_proof_update(elements, update_elements, proof);\\n\\n        require(hash_node(total_element_count, element_root) == root, \\\"INVALID_PROOF\\\");\\n\\n        element_root = get_new_root_from_append_proof_multi_append(append_elements, append_proof);\\n\\n        return hash_node(bytes32(uint256(total_element_count) + append_elements.length), element_root);\\n    }\\n\\n    // INTERFACE: Create a tree and return the root, given a bytes32 element\\n    function create_from_one(bytes32 element) internal pure returns (bytes32 new_element_root) {\\n        return hash_node(bytes32(uint256(1)), get_root_from_one(element));\\n    }\\n\\n    // INTERFACE: Create a tree and return the root, given bytes32 elements in memory\\n    function create_from_many(bytes32[] memory elements) internal pure returns (bytes32 new_element_root) {\\n        return hash_node(bytes32(elements.length), get_root_from_many(elements));\\n    }\\n}\\n\",\"keccak256\":\"0x287df71c610876eb503766565c160917df28cb0ae9780c10753dbb2bd2058409\",\"license\":\"MIT\"},\"contracts/L1/fraud-proof/libraries/RLPReader.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\n\\n/*\\n * @author Hamdi Allam hamdi.allam97@gmail.com\\n * Please reach out with any questions or concerns\\n */\\n\\npragma solidity ^0.8.0;\\n\\nlibrary RLPReader {\\n    uint8 constant STRING_SHORT_START = 0x80;\\n    uint8 constant STRING_LONG_START = 0xb8;\\n    uint8 constant LIST_SHORT_START = 0xc0;\\n    uint8 constant LIST_LONG_START = 0xf8;\\n    uint8 constant WORD_SIZE = 32;\\n\\n    struct RLPItem {\\n        uint256 len;\\n        uint256 memPtr;\\n    }\\n\\n    struct Iterator {\\n        RLPItem item; // Item that's being iterated over.\\n        uint256 nextPtr; // Position of the next item in the list.\\n    }\\n\\n    /*\\n    * @dev Returns the next element in the iteration. Reverts if it has not next element.\\n    * @param self The iterator.\\n    * @return The next element in the iteration.\\n    */\\n    function next(Iterator memory self) internal pure returns (RLPItem memory) {\\n        require(hasNext(self));\\n\\n        uint256 ptr = self.nextPtr;\\n        uint256 itemLength = _itemLength(ptr);\\n        self.nextPtr = ptr + itemLength;\\n\\n        return RLPItem(itemLength, ptr);\\n    }\\n\\n    /*\\n    * @dev Returns true if the iteration has more elements.\\n    * @param self The iterator.\\n    * @return true if the iteration has more elements.\\n    */\\n    function hasNext(Iterator memory self) internal pure returns (bool) {\\n        RLPItem memory item = self.item;\\n        return self.nextPtr < item.memPtr + item.len;\\n    }\\n\\n    /*\\n    * @param item RLP encoded bytes\\n    */\\n    function toRlpItem(bytes memory item) internal pure returns (RLPItem memory) {\\n        uint256 memPtr;\\n        assembly {\\n            memPtr := add(item, 0x20)\\n        }\\n\\n        return RLPItem(item.length, memPtr);\\n    }\\n\\n    /*\\n    * @dev Create an iterator. Reverts if item is not a list.\\n    * @param self The RLP item.\\n    * @return An 'Iterator' over the item.\\n    */\\n    function iterator(RLPItem memory self) internal pure returns (Iterator memory) {\\n        require(isList(self));\\n\\n        uint256 ptr = self.memPtr + _payloadOffset(self.memPtr);\\n        return Iterator(self, ptr);\\n    }\\n\\n    /*\\n    * @param the RLP item.\\n    */\\n    function rlpLen(RLPItem memory item) internal pure returns (uint256) {\\n        return item.len;\\n    }\\n\\n    /*\\n     * @param the RLP item.\\n     * @return (memPtr, len) pair: location of the item's payload in memory.\\n     */\\n    function payloadLocation(RLPItem memory item) internal pure returns (uint256, uint256) {\\n        uint256 offset = _payloadOffset(item.memPtr);\\n        uint256 memPtr = item.memPtr + offset;\\n        uint256 len = item.len - offset; // data length\\n        return (memPtr, len);\\n    }\\n\\n    /*\\n     * @param the RLP item.\\n     * @return RLPItem of (memPtr, len) pair: location of the item's payload in memory.\\n     */\\n    function payloadToRlpItem(RLPItem memory item) internal pure returns (RLPItem memory) {\\n        uint256 offset = _payloadOffset(item.memPtr);\\n        uint256 memPtr = item.memPtr + offset;\\n        uint256 len = item.len - offset; // data length\\n        return RLPItem(memPtr, len);\\n    }\\n\\n    /*\\n    * @param the RLP item.\\n    */\\n    function payloadLen(RLPItem memory item) internal pure returns (uint256) {\\n        (, uint256 len) = payloadLocation(item);\\n        return len;\\n    }\\n\\n    /*\\n    * @param the RLP item containing the encoded list.\\n    */\\n    function toList(RLPItem memory item) internal pure returns (RLPItem[] memory) {\\n        require(isList(item));\\n\\n        uint256 items = numItems(item);\\n        RLPItem[] memory result = new RLPItem[](items);\\n\\n        uint256 memPtr = item.memPtr + _payloadOffset(item.memPtr);\\n        uint256 dataLen;\\n        for (uint256 i = 0; i < items; i++) {\\n            dataLen = _itemLength(memPtr);\\n            result[i] = RLPItem(dataLen, memPtr);\\n            memPtr = memPtr + dataLen;\\n        }\\n\\n        return result;\\n    }\\n\\n    // @return indicator whether encoded payload is a list. negate this function call for isData.\\n    function isList(RLPItem memory item) internal pure returns (bool) {\\n        if (item.len == 0) return false;\\n\\n        uint8 byte0;\\n        uint256 memPtr = item.memPtr;\\n        assembly {\\n            byte0 := byte(0, mload(memPtr))\\n        }\\n\\n        if (byte0 < LIST_SHORT_START) {\\n            return false;\\n        }\\n        return true;\\n    }\\n\\n    /*\\n     * @dev A cheaper version of keccak256(toRlpBytes(item)) that avoids copying memory.\\n     * @return keccak256 hash of RLP encoded bytes.\\n     */\\n    function rlpBytesKeccak256(RLPItem memory item) internal pure returns (bytes32) {\\n        uint256 ptr = item.memPtr;\\n        uint256 len = item.len;\\n        bytes32 result;\\n        assembly {\\n            result := keccak256(ptr, len)\\n        }\\n        return result;\\n    }\\n\\n    /*\\n     * @dev A cheaper version of keccak256(toBytes(item)) that avoids copying memory.\\n     * @return keccak256 hash of the item payload.\\n     */\\n    function payloadKeccak256(RLPItem memory item) internal pure returns (bytes32) {\\n        (uint256 memPtr, uint256 len) = payloadLocation(item);\\n        bytes32 result;\\n        assembly {\\n            result := keccak256(memPtr, len)\\n        }\\n        return result;\\n    }\\n\\n    /**\\n     * RLPItem conversions into data types *\\n     */\\n\\n    // @returns raw rlp encoding in bytes\\n    function toRlpBytes(RLPItem memory item) internal pure returns (bytes memory) {\\n        bytes memory result = new bytes(item.len);\\n        if (result.length == 0) return result;\\n\\n        uint256 ptr;\\n        assembly {\\n            ptr := add(0x20, result)\\n        }\\n\\n        copy(item.memPtr, ptr, item.len);\\n        return result;\\n    }\\n\\n    // any non-zero byte except \\\"0x80\\\" is considered true\\n    function toBoolean(RLPItem memory item) internal pure returns (bool) {\\n        require(item.len == 1);\\n        uint256 result;\\n        uint256 memPtr = item.memPtr;\\n        assembly {\\n            result := byte(0, mload(memPtr))\\n        }\\n\\n        // SEE Github Issue #5.\\n        // Summary: Most commonly used RLP libraries (i.e Geth) will encode\\n        // \\\"0\\\" as \\\"0x80\\\" instead of as \\\"0\\\". We handle this edge case explicitly\\n        // here.\\n        if (result == 0 || result == STRING_SHORT_START) {\\n            return false;\\n        } else {\\n            return true;\\n        }\\n    }\\n\\n    function toAddress(RLPItem memory item) internal pure returns (address) {\\n        // 1 byte for the length prefix\\n        require(item.len == 21);\\n\\n        return address(uint160(toUint(item)));\\n    }\\n\\n    function toUint(RLPItem memory item) internal pure returns (uint256) {\\n        require(item.len > 0 && item.len <= 33);\\n\\n        (uint256 memPtr, uint256 len) = payloadLocation(item);\\n\\n        uint256 result;\\n        assembly {\\n            result := mload(memPtr)\\n\\n            // shfit to the correct location if neccesary\\n            if lt(len, 32) { result := div(result, exp(256, sub(32, len))) }\\n        }\\n\\n        return result;\\n    }\\n\\n    // enforces 32 byte length\\n    function toUintStrict(RLPItem memory item) internal pure returns (uint256) {\\n        // one byte prefix\\n        require(item.len == 33);\\n\\n        uint256 result;\\n        uint256 memPtr = item.memPtr + 1;\\n        assembly {\\n            result := mload(memPtr)\\n        }\\n\\n        return result;\\n    }\\n\\n    function toBytes(RLPItem memory item) internal pure returns (bytes memory) {\\n        require(item.len > 0);\\n\\n        (uint256 memPtr, uint256 len) = payloadLocation(item);\\n        bytes memory result = new bytes(len);\\n\\n        uint256 destPtr;\\n        assembly {\\n            destPtr := add(0x20, result)\\n        }\\n\\n        copy(memPtr, destPtr, len);\\n        return result;\\n    }\\n\\n    /*\\n    * Private Helpers\\n    */\\n\\n    // @return number of payload items inside an encoded list.\\n    function numItems(RLPItem memory item) private pure returns (uint256) {\\n        if (item.len == 0) return 0;\\n\\n        uint256 count = 0;\\n        uint256 currPtr = item.memPtr + _payloadOffset(item.memPtr);\\n        uint256 endPtr = item.memPtr + item.len;\\n        while (currPtr < endPtr) {\\n            currPtr = currPtr + _itemLength(currPtr); // skip over an item\\n            count++;\\n        }\\n\\n        return count;\\n    }\\n\\n    // @return entire rlp item byte length\\n    function _itemLength(uint256 memPtr) private pure returns (uint256) {\\n        uint256 itemLen;\\n        uint256 byte0;\\n        assembly {\\n            byte0 := byte(0, mload(memPtr))\\n        }\\n\\n        if (byte0 < STRING_SHORT_START) {\\n            itemLen = 1;\\n        } else if (byte0 < STRING_LONG_START) {\\n            itemLen = byte0 - STRING_SHORT_START + 1;\\n        } else if (byte0 < LIST_SHORT_START) {\\n            assembly {\\n                let byteLen := sub(byte0, 0xb7) // # of bytes the actual length is\\n                memPtr := add(memPtr, 1) // skip over the first byte\\n\\n                /* 32 byte word size */\\n                let dataLen := div(mload(memPtr), exp(256, sub(32, byteLen))) // right shifting to get the len\\n                itemLen := add(dataLen, add(byteLen, 1))\\n            }\\n        } else if (byte0 < LIST_LONG_START) {\\n            itemLen = byte0 - LIST_SHORT_START + 1;\\n        } else {\\n            assembly {\\n                let byteLen := sub(byte0, 0xf7)\\n                memPtr := add(memPtr, 1)\\n\\n                let dataLen := div(mload(memPtr), exp(256, sub(32, byteLen))) // right shifting to the correct length\\n                itemLen := add(dataLen, add(byteLen, 1))\\n            }\\n        }\\n\\n        return itemLen;\\n    }\\n\\n    // @return number of bytes until the data\\n    function _payloadOffset(uint256 memPtr) private pure returns (uint256) {\\n        uint256 byte0;\\n        assembly {\\n            byte0 := byte(0, mload(memPtr))\\n        }\\n\\n        if (byte0 < STRING_SHORT_START) {\\n            return 0;\\n        } else if (byte0 < STRING_LONG_START || (byte0 >= LIST_SHORT_START && byte0 < LIST_LONG_START)) {\\n            return 1;\\n        } else if (\\n            byte0 < LIST_SHORT_START // being explicit\\n        ) {\\n            return byte0 - (STRING_LONG_START - 1) + 1;\\n        } else {\\n            return byte0 - (LIST_LONG_START - 1) + 1;\\n        }\\n    }\\n\\n    /*\\n    * @param src Pointer to source\\n    * @param dest Pointer to destination\\n    * @param len Amount of memory to copy from the source\\n    */\\n    function copy(uint256 src, uint256 dest, uint256 len) private pure {\\n        if (len == 0) return;\\n\\n        // copy as many word sizes as possible\\n        for (; len >= WORD_SIZE; len -= WORD_SIZE) {\\n            assembly {\\n                mstore(dest, mload(src))\\n            }\\n\\n            src += WORD_SIZE;\\n            dest += WORD_SIZE;\\n        }\\n\\n        if (len > 0) {\\n            // left over bytes. Mask is used to remove unwanted bytes from the word\\n            uint256 mask = 256 ** (WORD_SIZE - len) - 1;\\n            assembly {\\n                let srcpart := and(mload(src), not(mask)) // zero out src\\n                let destpart := and(mload(dest), mask) // retrieve the bytes\\n                mstore(dest, or(destpart, srcpart))\\n            }\\n        }\\n    }\\n}\\n\",\"keccak256\":\"0x8bf8579e473cf267b43ce28dfa9b66b6cb9480cb293e0f995e7b6074f66b9c39\",\"license\":\"Apache-2.0\"},\"contracts/L1/fraud-proof/libraries/RLPWriter.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\n/**\\n * @custom:attribution https://github.com/bakaoh/solidity-rlp-encode\\n * @title RLPWriter\\n * @author RLPWriter is a library for encoding Solidity types to RLP bytes. Adapted from Bakaoh's\\n *         RLPEncode library (https://github.com/bakaoh/solidity-rlp-encode) with minor\\n *         modifications to improve legibility.\\n */\\nlibrary RLPWriter {\\n    /**\\n     * @notice RLP encodes a byte string.\\n     *\\n     * @param _in The byte string to encode.\\n     *\\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     * @notice RLP encodes a list of RLP encoded byte byte strings.\\n     *\\n     * @param _in The list of RLP encoded byte strings.\\n     *\\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     * @notice RLP encodes a string.\\n     *\\n     * @param _in The string to encode.\\n     *\\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     * @notice RLP encodes an address.\\n     *\\n     * @param _in The address to encode.\\n     *\\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     * @notice RLP encodes a uint.\\n     *\\n     * @param _in The uint256 to encode.\\n     *\\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     * @notice RLP encodes a bool.\\n     *\\n     * @param _in The bool to encode.\\n     *\\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     * @notice Encode the first byte and then the `len` in binary form if `length` is more than 55.\\n     *\\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     *\\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     * @notice Encode integer in big endian binary form with no leading zeroes.\\n     *\\n     * @param _x The integer to encode.\\n     *\\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     * @custom:attribution https://github.com/Arachnid/solidity-stringutils\\n     * @notice Copies a piece of memory to another location.\\n     *\\n     * @param _dest Destination location.\\n     * @param _src  Source location.\\n     * @param _len  Length of memory to copy.\\n     */\\n    function _memcpy(uint256 _dest, uint256 _src, uint256 _len) 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     * @custom:attribution https://github.com/sammayo/solidity-rlp-encoder\\n     * @notice Flattens a list of byte strings into one byte string.\\n     *\\n     * @param _list List of byte strings to flatten.\\n     *\\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\",\"keccak256\":\"0xe5a21bf190b08cd999280f22383da1703688309b47ba4c60a36fb40c628e3e78\",\"license\":\"MIT\"},\"contracts/L1/fraud-proof/verifier/IVerifier.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\n\\n/*\\n * Copyright 2022, Specular contributors\\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.0;\\n\\nimport \\\"./libraries/VerificationContext.sol\\\";\\n\\ninterface IVerifier {\\n    function verifyOneStepProof(VerificationContext.Context memory ctx, bytes32 currStateHash, bytes calldata encoded)\\n        external\\n        pure\\n        returns (bytes32);\\n}\\n\",\"keccak256\":\"0x1ae9ce9afd67261074a4242b9fb804d90f78f11eb667ed7bb0b97a51aee7b43b\",\"license\":\"Apache-2.0\"},\"contracts/L1/fraud-proof/verifier/IVerifierEntry.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\n\\n/*\\n * Copyright 2022, Specular contributors\\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.0;\\n\\nimport \\\"./libraries/VerificationContext.sol\\\";\\n\\ninterface IVerifierEntry {\\n    function verifyOneStepProof(\\n        VerificationContext.Context memory ctx,\\n        uint8 verifier,\\n        bytes32 currStateHash,\\n        bytes calldata encoded\\n    ) external view returns (bytes32);\\n}\\n\",\"keccak256\":\"0xd50cc2ff3f6f64c1a92543eaddafc253c706d53ee40c0bd88141d53c555fe6c0\",\"license\":\"Apache-2.0\"},\"contracts/L1/fraud-proof/verifier/VerifierEntry.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\n\\n/*\\n * Copyright 2022, Specular contributors\\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.0;\\n\\nimport \\\"@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol\\\";\\nimport \\\"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\\\";\\n\\nimport \\\"./libraries/VerificationContext.sol\\\";\\nimport \\\"./libraries/Params.sol\\\";\\nimport \\\"./IVerifier.sol\\\";\\nimport \\\"./IVerifierEntry.sol\\\";\\n\\ncontract VerifierEntry is IVerifierEntry, Initializable, OwnableUpgradeable {\\n    IVerifier public  blockInitiationVerifier;\\n    IVerifier public blockFinalizationVerifier;\\n    IVerifier public interTxVerifier;\\n    IVerifier public stackOpVerifier;\\n    IVerifier public environmentalOpVerifier;\\n    IVerifier public memoryOpVerifier;\\n    IVerifier public storageOpVerifier;\\n    IVerifier public callOpVerifier;\\n    IVerifier public invalidOpVerifier;\\n\\n    /// @custom:oz-upgrades-unsafe-allow constructor\\n    constructor() {\\n        _disableInitializers();\\n    }\\n\\n    function initialize() public initializer {\\n        __Ownable_init();\\n    }\\n\\n    function setVerifier(uint8 verifier, IVerifier impl)\\n        external\\n        onlyOwner\\n    {\\n        if (verifier == Params.V_BLOCK_INIT) {\\n            blockInitiationVerifier = impl;\\n        } else if (verifier == Params.V_BLOCK_FINAL) {\\n            blockFinalizationVerifier = impl;\\n        } else if (verifier == Params.V_INTER_TX) {\\n            interTxVerifier = impl;\\n        } else if (verifier == Params.V_STACK_OP) {\\n            stackOpVerifier = impl;\\n        } else if (verifier == Params.V_ENVIRONMENTAL_OP) {\\n            environmentalOpVerifier = impl;\\n        } else if (verifier == Params.V_MEMORY_OP) {\\n            memoryOpVerifier = impl;\\n        } else if (verifier == Params.V_STORAGE_OP) {\\n            storageOpVerifier = impl;\\n        } else if (verifier == Params.V_CALL_OP) {\\n            callOpVerifier = impl;\\n        } else if (verifier == Params.V_INVALID_OP) {\\n            invalidOpVerifier = impl;\\n        } else {\\n            revert(\\\"unreachable\\\");\\n        }\\n    }\\n\\n    function verifyOneStepProof(\\n        VerificationContext.Context memory ctx,\\n        uint8 verifier,\\n        bytes32 currStateHash,\\n        bytes calldata encoded\\n    ) external view override returns (bytes32) {\\n        IVerifier impl;\\n        if (verifier == Params.V_BLOCK_INIT) {\\n            impl = blockInitiationVerifier;\\n        } else if (verifier == Params.V_BLOCK_FINAL) {\\n            impl = blockFinalizationVerifier;\\n        } else if (verifier == Params.V_INTER_TX) {\\n            impl = interTxVerifier;\\n        } else if (verifier == Params.V_STACK_OP) {\\n            impl = stackOpVerifier;\\n        } else if (verifier == Params.V_ENVIRONMENTAL_OP) {\\n            impl = environmentalOpVerifier;\\n        } else if (verifier == Params.V_MEMORY_OP) {\\n            impl = memoryOpVerifier;\\n        } else if (verifier == Params.V_STORAGE_OP) {\\n            impl = storageOpVerifier;\\n        } else if (verifier == Params.V_CALL_OP) {\\n            impl = callOpVerifier;\\n        } else if (verifier == Params.V_INVALID_OP) {\\n            impl = invalidOpVerifier;\\n        } else {\\n            revert(\\\"unreachable\\\");\\n        }\\n        return impl.verifyOneStepProof(ctx, currStateHash, encoded);\\n    }\\n}\\n\",\"keccak256\":\"0xfca30be9fda3ca6b1cf97322deda55858ef409f1f725d7ff7d63cec27506d9bb\",\"license\":\"Apache-2.0\"},\"contracts/L1/fraud-proof/verifier/libraries/BloomLib.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\n\\n/*\\n * Copyright 2022, Specular contributors\\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.0;\\n\\nimport \\\"../../libraries/BytesLib.sol\\\";\\n\\nlibrary BloomLib {\\n    using BytesLib for bytes;\\n\\n    struct Bloom {\\n        bytes32[8] data;\\n    }\\n\\n    function emptyBloom() internal pure returns (Bloom memory b) {\\n        return b;\\n    }\\n\\n    function decodeBloom(bytes calldata encoded, uint64 offset) internal pure returns (Bloom memory) {\\n        Bloom memory bloom;\\n        for (uint256 i = 0; i < 8; i++) {\\n            bloom.data[i] = encoded.toBytes32(offset);\\n            offset += 32;\\n        }\\n        return bloom;\\n    }\\n\\n    function addHash(Bloom memory bloom, bytes32 h) internal pure {\\n        uint16 i1 = 255 - (uint16(uint256(h) >> 240) & 0x7ff) >> 3;\\n        uint8 v1 = uint8(1 << (uint8(h[1]) & 0x7));\\n        bloom.data[i1 >> 5] = bytes32(uint256(bloom.data[i1 >> 5]) | (uint256(v1) << 8 * (31 - (i1 & 0x1f))));\\n        uint16 i2 = 255 - (uint16(uint256(h) >> 224) & 0x7ff) >> 3;\\n        uint8 v2 = uint8(1 << (uint8(h[3]) & 0x7));\\n        bloom.data[i2 >> 5] = bytes32(uint256(bloom.data[i2 >> 5]) | (uint256(v2) << 8 * (31 - (i2 & 0x1f))));\\n        uint16 i3 = 255 - (uint16(uint256(h) >> 208) & 0x7ff) >> 3;\\n        uint8 v3 = uint8(1 << (uint8(h[5]) & 0x7));\\n        bloom.data[i3 >> 5] = bytes32(uint256(bloom.data[i3 >> 5]) | (uint256(v3) << 8 * (31 - (i3 & 0x1f))));\\n    }\\n\\n    function add(Bloom memory bloom, bytes memory data) internal pure {\\n        bytes32 h;\\n        assembly {\\n            h := keccak256(add(data, 0x20), mload(data))\\n        }\\n        addHash(bloom, h);\\n    }\\n\\n    function add(Bloom memory bloom, address data) internal pure {\\n        bytes32 h = keccak256(abi.encodePacked(data));\\n        addHash(bloom, h);\\n    }\\n\\n    function add(Bloom memory bloom, bytes32 data) internal pure {\\n        bytes32 h = keccak256(abi.encodePacked(data));\\n        addHash(bloom, h);\\n    }\\n}\\n\",\"keccak256\":\"0x2077a2c7d984643614fd1d639e0d9e217d4e62645849b92ec70cd56cb9845105\",\"license\":\"Apache-2.0\"},\"contracts/L1/fraud-proof/verifier/libraries/EVMTypesLib.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\n\\n/*\\n * Copyright 2022, Specular contributors\\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.0;\\n\\nimport \\\"../../libraries/BytesLib.sol\\\";\\nimport \\\"../../libraries/RLPReader.sol\\\";\\nimport \\\"../../libraries/RLPWriter.sol\\\";\\nimport \\\"./BloomLib.sol\\\";\\n\\nlibrary EVMTypesLib {\\n    using BytesLib for bytes;\\n    using RLPReader for bytes;\\n    using RLPReader for RLPReader.RLPItem;\\n\\n    struct BlockHeader {\\n        bytes32 parentHash;\\n        bytes32 ommerHash;\\n        address beneficiary;\\n        bytes32 stateRoot;\\n        bytes32 transactionRoot;\\n        bytes32 receiptsRoot;\\n        uint256 difficulty;\\n        uint256 number;\\n        uint64 gasLimit;\\n        uint64 gasUsed;\\n        uint64 timestamp;\\n        BloomLib.Bloom logsBloom;\\n    }\\n\\n    function hashBlockHeader(BlockHeader memory header) internal pure returns (bytes32) {\\n        bytes[] memory raw = new bytes[](15);\\n        raw[0] = RLPWriter.writeBytes(abi.encodePacked(header.parentHash));\\n        raw[1] = RLPWriter.writeBytes(abi.encodePacked(header.ommerHash));\\n        raw[2] = RLPWriter.writeAddress(header.beneficiary);\\n        raw[3] = RLPWriter.writeBytes(abi.encodePacked(header.stateRoot));\\n        raw[4] = RLPWriter.writeBytes(abi.encodePacked(header.transactionRoot));\\n        raw[5] = RLPWriter.writeBytes(abi.encodePacked(header.receiptsRoot));\\n        raw[6] = RLPWriter.writeBytes(abi.encodePacked(header.logsBloom.data));\\n        raw[7] = RLPWriter.writeUint(header.difficulty);\\n        raw[8] = RLPWriter.writeUint(header.number);\\n        raw[9] = RLPWriter.writeUint(uint256(header.gasLimit));\\n        raw[10] = RLPWriter.writeUint(uint256(header.gasUsed));\\n        raw[11] = RLPWriter.writeUint(uint256(header.timestamp));\\n        raw[12] = RLPWriter.writeBytes(\\\"\\\"); // Extra\\n        raw[13] = RLPWriter.writeBytes(abi.encodePacked(bytes32(0))); // MixDigest\\n        raw[14] = RLPWriter.writeBytes(abi.encodePacked(bytes8(0))); // Nonce\\n        return keccak256(RLPWriter.writeList(raw));\\n    }\\n\\n    struct Transaction {\\n        uint64 nonce;\\n        uint256 gasPrice;\\n        uint64 gas;\\n        address to;\\n        uint256 value;\\n        bytes data;\\n        uint256 v;\\n        uint256 r;\\n        uint256 s;\\n    }\\n\\n    function decodeTransaction(bytes memory data) internal pure returns (Transaction memory transaction) {\\n        RLPReader.RLPItem[] memory decoded = data.toRlpItem().toList();\\n        transaction.nonce = uint64(decoded[0].toUint());\\n        transaction.gasPrice = decoded[1].toUint();\\n        transaction.gas = uint64(decoded[2].toUint());\\n        transaction.to = address(uint160(decoded[3].toUint()));\\n        transaction.value = decoded[4].toUint();\\n        transaction.data = decoded[5].toBytes();\\n        transaction.v = decoded[6].toUint();\\n        transaction.r = decoded[7].toUint();\\n        transaction.s = decoded[8].toUint();\\n    }\\n\\n    function hashTransaction(Transaction memory txn) internal pure returns (bytes32) {\\n        bytes[] memory raw = new bytes[](9);\\n        raw[0] = RLPWriter.writeUint(uint256(txn.nonce));\\n        raw[1] = RLPWriter.writeUint(txn.gasPrice);\\n        raw[2] = RLPWriter.writeUint(uint256(txn.gas));\\n        raw[3] = RLPWriter.writeAddress(txn.to);\\n        raw[4] = RLPWriter.writeUint(txn.value);\\n        raw[5] = RLPWriter.writeBytes(txn.data);\\n        raw[6] = RLPWriter.writeUint(txn.v);\\n        raw[7] = RLPWriter.writeUint(txn.r);\\n        raw[8] = RLPWriter.writeUint(txn.s);\\n        return keccak256(RLPWriter.writeList(raw));\\n    }\\n\\n    struct Account {\\n        uint64 nonce;\\n        uint256 balance;\\n        bytes32 storageRoot;\\n        bytes32 codeHash;\\n    }\\n\\n    function decodeAccount(RLPReader.RLPItem memory encoded) internal pure returns (Account memory proof) {\\n        RLPReader.RLPItem[] memory items = encoded.toList();\\n        require(items.length == 4, \\\"Invalid Account\\\");\\n        proof.nonce = uint64(items[0].toUint());\\n        proof.balance = items[1].toUint();\\n        proof.storageRoot = bytes32(items[2].toUint());\\n        proof.codeHash = bytes32(items[3].toUint());\\n    }\\n\\n    function encodeRLP(Account memory account) internal pure returns (bytes memory) {\\n        bytes[] memory raw = new bytes[](4);\\n        raw[0] = RLPWriter.writeUint(uint256(account.nonce));\\n        raw[1] = RLPWriter.writeUint(account.balance);\\n        raw[2] = RLPWriter.writeBytes(abi.encodePacked(account.storageRoot));\\n        raw[3] = RLPWriter.writeBytes(abi.encodePacked(account.codeHash));\\n        return RLPWriter.writeList(raw);\\n    }\\n\\n    function hashLogEntry(address addr, uint256[] memory topics, bytes memory data) internal pure returns (bytes32) {\\n        bytes[] memory topicRaw = new bytes[](topics.length);\\n        for (uint256 i = 0; i < topics.length; i++) {\\n            topicRaw[i] = RLPWriter.writeBytes(abi.encodePacked(bytes32(topics[i])));\\n        }\\n        bytes[] memory raw = new bytes[](3);\\n        raw[0] = RLPWriter.writeAddress(addr);\\n        raw[1] = RLPWriter.writeBytes(RLPWriter.writeList(topicRaw));\\n        raw[2] = RLPWriter.writeBytes(data);\\n        return keccak256(RLPWriter.writeList(raw));\\n    }\\n}\\n\",\"keccak256\":\"0x4f11333325ad94cd5f673e9d375e033534ab48c8497149add79ceacb69124b77\",\"license\":\"Apache-2.0\"},\"contracts/L1/fraud-proof/verifier/libraries/MemoryLib.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\n\\n/*\\n * Copyright 2022, Specular contributors\\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.0;\\n\\nimport \\\"../../libraries/DeserializationLib.sol\\\";\\nimport \\\"../../libraries/MerkleLib.sol\\\";\\nimport \\\"../../libraries/BytesLib.sol\\\";\\nimport \\\"./OneStepProof.sol\\\";\\n\\nlibrary MemoryLib {\\n    using BytesLib for bytes;\\n\\n    function calcCellNum(uint64 offset, uint64 length) internal pure returns (uint64) {\\n        return (offset + length + 31) / 32 - offset / 32;\\n    }\\n\\n    function getMemoryRoot(bytes memory content) internal pure returns (bytes32) {\\n        uint64 cellNum = MemoryLib.calcCellNum(0, uint64(content.length));\\n        bytes32[] memory elements = new bytes32[](cellNum);\\n        for (uint256 i = 0; i < cellNum - 1; i++) {\\n            elements[i] = content.toBytes32(i * 32);\\n        }\\n        elements[cellNum - 1] = content.toBytes32Pad((cellNum - 1) * 32);\\n        return MerkleLib.create_from_many(elements);\\n    }\\n\\n    function decodeAndVerifyMemoryReadProof(\\n        OneStepProof.StateProof memory stateProof,\\n        bytes calldata encoded,\\n        uint64 offset,\\n        uint64 memoryOffset,\\n        uint64 memoryReadLength\\n    ) internal pure returns (uint64, bytes memory) {\\n        if (stateProof.memSize == 0 || memoryReadLength == 0) {\\n            return (offset, new bytes(memoryReadLength));\\n        }\\n        uint64 startCell = memoryOffset / 32;\\n        uint64 cellNum = calcCellNum(memoryOffset, memoryReadLength);\\n        uint64 memoryCell = calcCellNum(0, stateProof.memSize);\\n        OneStepProof.MemoryMerkleProof memory merkleProof;\\n        {\\n            if (memoryCell <= startCell) {\\n                cellNum += startCell - memoryCell;\\n                OneStepProof.MemoryAppendProof memory appendProof;\\n                (offset, appendProof) = OneStepProof.decodeMemoryAppendProof(encoded, offset, cellNum);\\n                (offset, merkleProof) = OneStepProof.decodeMemoryMerkleProof(encoded, offset);\\n                stateProof.memRoot =\\n                    MerkleLib.try_append_many(stateProof.memRoot, appendProof.appendCells, merkleProof.proof);\\n                if (memoryOffset + memoryReadLength > stateProof.memSize) {\\n                    stateProof.memSize = (memoryOffset + memoryReadLength + 31) / 32 * 32; // Expand by words\\n                }\\n                bytes memory readContent = new bytes(memoryReadLength);\\n                return (offset, readContent);\\n            }\\n        }\\n        {\\n            if (memoryCell >= startCell + cellNum) {\\n                OneStepProof.MemoryReadProof memory readProof;\\n                (offset, readProof) = OneStepProof.decodeMemoryReadProof(encoded, offset, cellNum);\\n                (offset, merkleProof) = OneStepProof.decodeMemoryMerkleProof(encoded, offset);\\n                if (cellNum == 1) {\\n                    MerkleLib.element_exists(stateProof.memRoot, startCell, readProof.cells[0], merkleProof.proof);\\n                    require(\\n                        MerkleLib.element_exists(stateProof.memRoot, startCell, readProof.cells[0], merkleProof.proof),\\n                        \\\"IMP\\\"\\n                    );\\n                } else {\\n                    {\\n                        // avoid stack too deep\\n                        uint256[] memory indices = MerkleLib.get_indices(readProof.cells, merkleProof.proof);\\n                        for (uint64 i = 0; i < cellNum; i++) {\\n                            require(indices[i] == startCell + i, \\\"IMP\\\");\\n                        }\\n                    }\\n                    MerkleLib.elements_exist(stateProof.memRoot, readProof.cells, merkleProof.proof);\\n                    require(MerkleLib.elements_exist(stateProof.memRoot, readProof.cells, merkleProof.proof), \\\"IMP\\\");\\n                }\\n                bytes memory readContent = abi.encodePacked(readProof.cells).slice(memoryOffset % 32, memoryReadLength);\\n                return (offset, readContent);\\n            }\\n        }\\n        uint64 existCellNum = memoryCell - startCell;\\n        OneStepProof.MemoryCombinedReadProof memory combinedReadProof;\\n        (offset, combinedReadProof) =\\n            OneStepProof.decodeMemoryCombinedReadProof(encoded, offset, existCellNum, cellNum - existCellNum);\\n        (offset, merkleProof) = OneStepProof.decodeMemoryMerkleProof(encoded, offset);\\n        if (existCellNum == 1) {\\n            stateProof.memRoot = MerkleLib.try_append_many_using_one(\\n                stateProof.memRoot,\\n                startCell,\\n                combinedReadProof.cells[0],\\n                combinedReadProof.appendCells,\\n                merkleProof.proof\\n            );\\n        } else {\\n            {\\n                // avoid stack too deep\\n                uint256[] memory indices = MerkleLib.get_indices(combinedReadProof.cells, merkleProof.proof);\\n                for (uint64 i = 0; i < existCellNum; i++) {\\n                    require(indices[i] == startCell + i, \\\"IMP\\\");\\n                }\\n            }\\n            stateProof.memRoot = MerkleLib.try_append_many_using_many(\\n                stateProof.memRoot, combinedReadProof.cells, combinedReadProof.appendCells, merkleProof.proof\\n            );\\n        }\\n        if (memoryOffset + memoryReadLength > stateProof.memSize) {\\n            stateProof.memSize = (memoryOffset + memoryReadLength + 31) / 32 * 32; // Expand by words\\n        }\\n        bytes memory readContent = abi.encodePacked(combinedReadProof.cells, combinedReadProof.appendCells).slice(\\n            memoryOffset % 32, memoryReadLength\\n        );\\n        return (offset, readContent);\\n    }\\n\\n    function decodeAndVerifyMemoryLikeReadProofNoAppend(\\n        bytes32 memoryLikeRoot,\\n        uint64 memoryLikeSize,\\n        bytes calldata encoded,\\n        uint64 offset,\\n        uint64 memoryLikeOffset,\\n        uint64 memoryLikeReadLength\\n    ) internal pure returns (uint64, bytes memory) {\\n        if (memoryLikeSize == 0 || memoryLikeReadLength == 0) {\\n            return (offset, new bytes(memoryLikeReadLength));\\n        }\\n        uint64 startCell = memoryLikeOffset / 32;\\n        uint64 cellNum = calcCellNum(memoryLikeOffset, memoryLikeReadLength);\\n        uint64 memoryCell = calcCellNum(0, memoryLikeSize);\\n        {\\n            if (memoryCell <= startCell) {\\n                bytes memory readContent;\\n                readContent = new bytes(memoryLikeReadLength);\\n                return (offset, readContent);\\n            }\\n        }\\n        {\\n            if (memoryCell >= startCell + cellNum) {\\n                bytes memory readContent;\\n                OneStepProof.MemoryReadProof memory readProof;\\n                OneStepProof.MemoryMerkleProof memory merkleProof;\\n                (offset, readProof) = OneStepProof.decodeMemoryReadProof(encoded, offset, cellNum);\\n                (offset, merkleProof) = OneStepProof.decodeMemoryMerkleProof(encoded, offset);\\n                if (cellNum == 1) {\\n                    MerkleLib.element_exists(memoryLikeRoot, startCell, readProof.cells[0], merkleProof.proof);\\n                    require(\\n                        MerkleLib.element_exists(memoryLikeRoot, startCell, readProof.cells[0], merkleProof.proof),\\n                        \\\"IMP\\\"\\n                    );\\n                } else {\\n                    {\\n                        uint256[] memory indices = MerkleLib.get_indices(readProof.cells, merkleProof.proof);\\n                        for (uint64 i = 0; i < cellNum; i++) {\\n                            require(indices[i] == startCell + i, \\\"IMP2\\\");\\n                        }\\n                    }\\n                    MerkleLib.elements_exist(memoryLikeRoot, readProof.cells, merkleProof.proof);\\n                    require(MerkleLib.elements_exist(memoryLikeRoot, readProof.cells, merkleProof.proof), \\\"IMP\\\");\\n                }\\n                readContent = abi.encodePacked(readProof.cells).slice(memoryLikeOffset % 32, memoryLikeReadLength);\\n                return (offset, readContent);\\n            }\\n        }\\n        uint64 existCellNum = memoryCell - startCell;\\n        OneStepProof.MemoryReadProof memory readProof;\\n        OneStepProof.MemoryMerkleProof memory merkleProof;\\n        (offset, readProof) = OneStepProof.decodeMemoryReadProof(encoded, offset, existCellNum);\\n        (offset, merkleProof) = OneStepProof.decodeMemoryMerkleProof(encoded, offset);\\n        if (existCellNum == 1) {\\n            MerkleLib.element_exists(memoryLikeRoot, startCell, readProof.cells[0], merkleProof.proof);\\n            require(MerkleLib.element_exists(memoryLikeRoot, startCell, readProof.cells[0], merkleProof.proof), \\\"IMP\\\");\\n        } else {\\n            {\\n                uint256[] memory indices = MerkleLib.get_indices(readProof.cells, merkleProof.proof);\\n                for (uint64 i = 0; i < cellNum; i++) {\\n                    require(indices[i] == startCell + i, \\\"IMP\\\");\\n                }\\n            }\\n            MerkleLib.elements_exist(memoryLikeRoot, readProof.cells, merkleProof.proof);\\n            require(MerkleLib.elements_exist(memoryLikeRoot, readProof.cells, merkleProof.proof), \\\"IMP\\\");\\n        }\\n        bytes memory padding = new bytes(32 * (cellNum - existCellNum));\\n        bytes memory readContent;\\n        readContent = abi.encodePacked(readProof.cells, padding).slice(memoryLikeOffset % 32, memoryLikeReadLength);\\n        return (offset, readContent);\\n    }\\n\\n    function decodeAndVerifyMemoryWriteProof(\\n        OneStepProof.StateProof memory stateProof,\\n        bytes calldata encoded,\\n        uint64 offset,\\n        uint64 memoryOffset,\\n        uint64 memoryWriteLength\\n    ) internal pure returns (uint64, bytes memory) {\\n        if (memoryWriteLength == 0) {\\n            return (offset, new bytes(0));\\n        }\\n        if (stateProof.memSize == 0) {\\n            // Don't call decodeMemoryWriteProof if memory is empty\\n            // Instead, update memory root and size directly\\n            revert();\\n        }\\n        uint64 startCell = memoryOffset / 32;\\n        uint64 cellNum = calcCellNum(memoryOffset, memoryWriteLength);\\n        uint64 memoryCell = calcCellNum(0, stateProof.memSize);\\n        OneStepProof.MemoryMerkleProof memory merkleProof;\\n\\n        {\\n            if (memoryCell <= startCell) {\\n                cellNum += startCell - memoryCell;\\n                OneStepProof.MemoryAppendProof memory appendProof;\\n                (offset, appendProof) = OneStepProof.decodeMemoryAppendProof(encoded, offset, cellNum);\\n                (offset, merkleProof) = OneStepProof.decodeMemoryMerkleProof(encoded, offset);\\n                if (cellNum == 1) {\\n                    stateProof.memRoot =\\n                        MerkleLib.try_append_one(stateProof.memRoot, appendProof.appendCells[0], merkleProof.proof);\\n                } else {\\n                    stateProof.memRoot =\\n                        MerkleLib.try_append_many(stateProof.memRoot, appendProof.appendCells, merkleProof.proof);\\n                }\\n                if (memoryOffset + memoryWriteLength > stateProof.memSize) {\\n                    stateProof.memSize = (memoryOffset + memoryWriteLength + 31) / 32 * 32; // Expand by words\\n                }\\n                bytes memory writeContent =\\n                    abi.encodePacked(appendProof.appendCells).slice(memoryOffset % 32, memoryWriteLength);\\n                return (offset, writeContent);\\n            }\\n        }\\n        {\\n            if (memoryCell >= startCell + cellNum) {\\n                OneStepProof.MemoryWriteProof memory writeProof;\\n                (offset, writeProof) = OneStepProof.decodeMemoryWriteProof(encoded, offset, cellNum);\\n                (offset, merkleProof) = OneStepProof.decodeMemoryMerkleProof(encoded, offset);\\n                if (cellNum == 1) {\\n                    stateProof.memRoot = MerkleLib.try_update_one(\\n                        stateProof.memRoot,\\n                        startCell,\\n                        writeProof.cells[0],\\n                        writeProof.updatedCells[0],\\n                        merkleProof.proof\\n                    );\\n                } else {\\n                    {\\n                        // Avoid stack too deep\\n                        uint256[] memory indices = MerkleLib.get_indices(writeProof.cells, merkleProof.proof);\\n                        for (uint64 i = 0; i < cellNum; i++) {\\n                            require(indices[i] == startCell + i, \\\"IMP\\\");\\n                        }\\n                    }\\n                    stateProof.memRoot = MerkleLib.try_update_many(\\n                        stateProof.memRoot, writeProof.cells, writeProof.updatedCells, merkleProof.proof\\n                    );\\n                }\\n                bytes memory writeContent =\\n                    abi.encodePacked(writeProof.updatedCells).slice(memoryOffset % 32, memoryWriteLength);\\n                return (offset, writeContent);\\n            }\\n        }\\n        uint64 existCellNum = memoryCell - startCell;\\n        OneStepProof.MemoryCombinedWriteProof memory combinedWriteProof;\\n        (offset, combinedWriteProof) =\\n            OneStepProof.decodeMemoryCombinedWriteProof(encoded, offset, existCellNum, cellNum - existCellNum);\\n        if (cellNum == 1) {\\n            stateProof.memRoot = MerkleLib.try_update_one_and_append_many(\\n                stateProof.memRoot,\\n                startCell,\\n                combinedWriteProof.cells[0],\\n                combinedWriteProof.updatedCells[0],\\n                combinedWriteProof.appendCells,\\n                merkleProof.proof\\n            );\\n        } else {\\n            {\\n                // avoid stack too deep\\n                uint256[] memory indices = MerkleLib.get_indices(combinedWriteProof.cells, merkleProof.proof);\\n                for (uint64 i = 0; i < cellNum; i++) {\\n                    require(indices[i] == startCell + i, \\\"IMP\\\");\\n                }\\n            }\\n            stateProof.memRoot = MerkleLib.try_update_many_and_append_many(\\n                stateProof.memRoot,\\n                combinedWriteProof.cells,\\n                combinedWriteProof.updatedCells,\\n                combinedWriteProof.appendCells,\\n                merkleProof.proof\\n            );\\n        }\\n        if (memoryOffset + memoryWriteLength > stateProof.memSize) {\\n            stateProof.memSize = (memoryOffset + memoryWriteLength + 31) / 32 * 32; // Expand by words\\n        }\\n        bytes memory writeContent = abi.encodePacked(combinedWriteProof.updatedCells, combinedWriteProof.appendCells)\\n            .slice(memoryOffset % 32, memoryWriteLength);\\n        return (offset, writeContent);\\n    }\\n}\\n\",\"keccak256\":\"0x4dbce765ce53e496d00a664726fc755288ceb0f6867e27de2f8e674db98d589c\",\"license\":\"Apache-2.0\"},\"contracts/L1/fraud-proof/verifier/libraries/OneStepProof.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\n\\n/*\\n * Copyright 2022, Specular contributors\\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.0;\\n\\nimport \\\"../../libraries/RLPReader.sol\\\";\\nimport \\\"../../libraries/BytesLib.sol\\\";\\nimport \\\"./BloomLib.sol\\\";\\nimport \\\"./VerificationContext.sol\\\";\\n\\nlibrary OneStepProof {\\n    using BytesLib for bytes;\\n    using RLPReader for RLPReader.RLPItem;\\n    using RLPReader for RLPReader.Iterator;\\n    using RLPReader for bytes;\\n    using VerificationContext for VerificationContext.Context;\\n\\n    // [encode rule]\\n    struct StateProof {\\n        uint64 blockNumber; // Block number of current transaction [always]\\n        uint64 transactionIdx; // Transaction index in block [always]\\n        uint16 depth; // Current call depth [always]\\n        uint64 gas; // Gas left in the current call [always]\\n        uint64 refund; // Gas refund accumulated in the current transaction [always]\\n        bytes32 lastDepthHash; // The state hash of the last depth call frame [always]\\n        address contractAddress; // Current executing contract address [depth > 1]\\n        address caller; // Current caller [depth > 1]\\n        uint256 value; // Current call value [depth > 1]\\n        uint8 callFlag; // Current call type [depth > 1]\\n        uint64 out; // Offset of the return data of current call to be copied to the last depth call frame [depth > 1]\\n        uint64 outSize; // Size of the return data of current call to be copied to the last depth call frame [depth > 1]\\n        uint64 pc; // Current program counter [always]\\n        uint8 opCode; // Current opcode to be executed [always]\\n        bytes32 codeHash; // Current executing contract code hash [always]\\n        uint64 stackSize; // Size of the stack [always]\\n        bytes32 stackHash; // Commitment of the stack [always]\\n        uint64 memSize; // Size of the memory [always]\\n        bytes32 memRoot; // Commitment of the memory [memSize > 0]\\n        uint64 inputDataSize; // Size of the call data [depth > 1]\\n        bytes32 inputDataRoot; // Commitment of the return data [depth > 1 && inputDataSize > 0]\\n        uint64 returnDataSize; // Size of the return data [always]\\n        bytes32 returnDataRoot; // Commitment of the return data [returnDataSize > 0]\\n        bytes32 committedGlobalStateRoot; // Commitment of the global MPT state at the start of transaction [always]\\n        bytes32 globalStateRoot; // Commitment of the global MPT state [always]\\n        bytes32 selfDestructAcc; // Commitment of the self destructed contracts in the current transaction [always]\\n        bytes32 logAcc; // Commitment of the logs emitted in the current transaction [always]\\n        bytes32 blockHashRoot; // Commitment of the 256 previous blockhash in the current block [always]\\n        bytes32 accessListRoot; // Commitment of the access list in the current transaction [always]\\n    }\\n\\n    function decodeStateProof(VerificationContext.Context memory ctx, bytes calldata encoded, uint64 offset)\\n        internal\\n        pure\\n        returns (uint64, StateProof memory proof)\\n    {\\n        uint64 remainLength = uint64(encoded.length) - offset;\\n        uint64 stateProofLen = 323;\\n        require(remainLength >= stateProofLen, \\\"Proof Underflow (State)\\\");\\n        proof.blockNumber = encoded.toUint64(offset);\\n        proof.transactionIdx = encoded.toUint64(offset + 8);\\n        proof.depth = encoded.toUint16(offset + 16);\\n        proof.gas = encoded.toUint64(offset + 18);\\n        proof.refund = encoded.toUint64(offset + 26);\\n        proof.lastDepthHash = encoded.toBytes32(offset + 34);\\n        offset = offset + 66;\\n        if (proof.depth > 1) {\\n            stateProofLen += 97;\\n            require(remainLength >= stateProofLen, \\\"Proof Underflow (State)\\\");\\n            proof.contractAddress = encoded.toAddress(offset);\\n            proof.caller = encoded.toAddress(offset + 20);\\n            proof.value = encoded.toUint256(offset + 40);\\n            proof.callFlag = encoded.toUint8(offset + 72);\\n            proof.out = encoded.toUint64(offset + 73);\\n            proof.outSize = encoded.toUint64(offset + 81);\\n            offset += 89;\\n        } else {\\n            proof.contractAddress = ctx.getRecipient();\\n            proof.caller = ctx.getOrigin();\\n            proof.value = ctx.getValue();\\n            if (ctx.getRecipient() == address(0)) {\\n                proof.callFlag = 4;\\n            } else {\\n                proof.callFlag = 0;\\n            }\\n        }\\n        proof.pc = encoded.toUint64(offset);\\n        proof.opCode = encoded.toUint8(offset + 8);\\n        proof.codeHash = encoded.toBytes32(offset + 9);\\n        proof.stackSize = encoded.toUint64(offset + 41);\\n        offset += 49;\\n        if (proof.stackSize != 0) {\\n            stateProofLen += 32;\\n            require(remainLength >= stateProofLen, \\\"Proof Underflow (State)\\\");\\n            proof.stackHash = encoded.toBytes32(offset);\\n            offset += 32;\\n        }\\n        proof.memSize = encoded.toUint64(offset);\\n        offset += 8;\\n        if (proof.memSize != 0) {\\n            stateProofLen += 32;\\n            require(remainLength >= stateProofLen, \\\"Proof Underflow (State)\\\");\\n            proof.memRoot = encoded.toBytes32(offset);\\n            offset += 32;\\n        }\\n        if (proof.depth > 1) {\\n            proof.inputDataSize = encoded.toUint64(offset);\\n            offset += 8;\\n            if (proof.inputDataSize != 0) {\\n                stateProofLen += 32;\\n                require(remainLength >= stateProofLen, \\\"Proof Underflow (State)\\\");\\n                proof.inputDataRoot = encoded.toBytes32(offset);\\n                offset += 32;\\n            }\\n        } else {\\n            proof.inputDataSize = ctx.getInputSize();\\n            proof.inputDataRoot = ctx.getInputRoot();\\n        }\\n        proof.returnDataSize = encoded.toUint64(offset);\\n        offset += 8;\\n        if (proof.returnDataSize != 0) {\\n            stateProofLen += 32;\\n            require(remainLength >= stateProofLen, \\\"Proof Underflow (State)\\\");\\n            proof.returnDataRoot = encoded.toBytes32(offset);\\n            offset += 32;\\n        }\\n        proof.committedGlobalStateRoot = encoded.toBytes32(offset);\\n        proof.globalStateRoot = encoded.toBytes32(offset + 32);\\n        proof.selfDestructAcc = encoded.toBytes32(offset + 64);\\n        proof.logAcc = encoded.toBytes32(offset + 96);\\n        proof.blockHashRoot = encoded.toBytes32(offset + 128);\\n        proof.accessListRoot = encoded.toBytes32(offset + 160);\\n        return (offset + 192, proof);\\n    }\\n\\n    function encodeStateProof(StateProof memory proof) internal pure returns (bytes memory encoded) {\\n        encoded = encoded.concat(abi.encodePacked(proof.blockNumber));\\n        encoded = encoded.concat(abi.encodePacked(proof.transactionIdx));\\n        encoded = encoded.concat(abi.encodePacked(proof.depth));\\n        encoded = encoded.concat(abi.encodePacked(proof.gas));\\n        encoded = encoded.concat(abi.encodePacked(proof.refund));\\n        encoded = encoded.concat(abi.encodePacked(proof.lastDepthHash));\\n        if (proof.depth > 1) {\\n            encoded = encoded.concat(abi.encodePacked(proof.contractAddress));\\n            encoded = encoded.concat(abi.encodePacked(proof.caller));\\n            encoded = encoded.concat(abi.encodePacked(proof.value));\\n            encoded = encoded.concat(abi.encodePacked(proof.callFlag));\\n            encoded = encoded.concat(abi.encodePacked(proof.out));\\n            encoded = encoded.concat(abi.encodePacked(proof.outSize));\\n        }\\n        encoded = encoded.concat(abi.encodePacked(proof.pc));\\n        encoded = encoded.concat(abi.encodePacked(proof.opCode));\\n        encoded = encoded.concat(abi.encodePacked(proof.codeHash));\\n        encoded = encoded.concat(abi.encodePacked(proof.stackSize));\\n        if (proof.stackSize != 0) {\\n            encoded = encoded.concat(abi.encodePacked(proof.stackHash));\\n        }\\n        encoded = encoded.concat(abi.encodePacked(proof.memSize));\\n        if (proof.memSize != 0) {\\n            encoded = encoded.concat(abi.encodePacked(proof.memRoot));\\n        }\\n        if (proof.depth > 1) {\\n            encoded = encoded.concat(abi.encodePacked(proof.inputDataSize));\\n            if (proof.inputDataSize != 0) {\\n                encoded = encoded.concat(abi.encodePacked(proof.inputDataRoot));\\n            }\\n        }\\n        encoded = encoded.concat(abi.encodePacked(proof.returnDataSize));\\n        if (proof.returnDataSize != 0) {\\n            encoded = encoded.concat(abi.encodePacked(proof.returnDataRoot));\\n        }\\n        encoded = encoded.concat(abi.encodePacked(proof.committedGlobalStateRoot));\\n        encoded = encoded.concat(abi.encodePacked(proof.globalStateRoot));\\n        encoded = encoded.concat(abi.encodePacked(proof.selfDestructAcc));\\n        encoded = encoded.concat(abi.encodePacked(proof.logAcc));\\n        encoded = encoded.concat(abi.encodePacked(proof.blockHashRoot));\\n        encoded = encoded.concat(abi.encodePacked(proof.accessListRoot));\\n    }\\n\\n    function hashStateProof(StateProof memory proof) internal pure returns (bytes32) {\\n        if (proof.depth == 0) {\\n            // When returning/reverting from depth 1, we can't directly return an InterStateProof\\n            // Therefore we reuse some of the fields in the IntraStateProof to store an InterStateProof\\n            // The field mappings are as follows:\\n            InterStateProof memory interProof;\\n            interProof.blockNumber = proof.blockNumber;\\n            interProof.transactionIdx = proof.transactionIdx;\\n            interProof.globalStateRoot = proof.globalStateRoot;\\n            interProof.cumulativeGasUsed = proof.value;\\n            interProof.blockGasUsed = uint256(proof.lastDepthHash);\\n            interProof.blockHashRoot = proof.blockHashRoot;\\n            interProof.transactionTrieRoot = proof.selfDestructAcc;\\n            interProof.receiptTrieRoot = proof.logAcc;\\n            return hashInterStateProof(interProof);\\n        }\\n        return keccak256(encodeStateProof(proof));\\n    }\\n\\n    struct InterStateProof {\\n        uint64 blockNumber;\\n        uint64 transactionIdx;\\n        bytes32 globalStateRoot;\\n        uint256 cumulativeGasUsed;\\n        uint256 blockGasUsed;\\n        bytes32 blockHashRoot;\\n        bytes32 transactionTrieRoot;\\n        bytes32 receiptTrieRoot;\\n        BloomLib.Bloom logsBloom;\\n    }\\n\\n    function decodeInterStateProof(bytes calldata encoded, uint64 offset)\\n        internal\\n        pure\\n        returns (uint64, InterStateProof memory proof)\\n    {\\n        require(encoded.length - offset >= 464, \\\"Proof Underflow (Inter)\\\");\\n        proof.blockNumber = encoded.toUint64(offset);\\n        proof.transactionIdx = encoded.toUint64(offset + 8);\\n        proof.globalStateRoot = encoded.toBytes32(offset + 16);\\n        proof.cumulativeGasUsed = encoded.toUint64(offset + 48);\\n        proof.blockGasUsed = encoded.toUint64(offset + 80);\\n        proof.blockHashRoot = encoded.toBytes32(offset + 112);\\n        proof.transactionTrieRoot = encoded.toBytes32(offset + 144);\\n        proof.receiptTrieRoot = encoded.toBytes32(offset + 176);\\n        proof.logsBloom = BloomLib.decodeBloom(encoded, offset + 208);\\n        return (offset + 464, proof);\\n    }\\n\\n    function encodeInterStateProof(InterStateProof memory proof) internal pure returns (bytes memory encoded) {\\n        encoded = encoded.concat(abi.encodePacked(proof.blockNumber));\\n        encoded = encoded.concat(abi.encodePacked(proof.transactionIdx));\\n        encoded = encoded.concat(abi.encodePacked(proof.globalStateRoot));\\n        encoded = encoded.concat(abi.encodePacked(proof.cumulativeGasUsed));\\n        encoded = encoded.concat(abi.encodePacked(proof.blockGasUsed));\\n        encoded = encoded.concat(abi.encodePacked(proof.blockHashRoot));\\n        encoded = encoded.concat(abi.encodePacked(proof.transactionTrieRoot));\\n        encoded = encoded.concat(abi.encodePacked(proof.receiptTrieRoot));\\n        encoded = encoded.concat(abi.encodePacked(proof.logsBloom.data));\\n    }\\n\\n    function hashInterStateProof(InterStateProof memory proof) internal pure returns (bytes32) {\\n        return keccak256(encodeInterStateProof(proof));\\n    }\\n\\n    struct BlockStateProof {\\n        uint64 blockNumber;\\n        bytes32 globalStateRoot;\\n        uint256 cumulativeGasUsed;\\n        bytes32 blockHashRoot;\\n    }\\n\\n    function decodeBlockStateProof(bytes calldata encoded, uint64 offset)\\n        internal\\n        pure\\n        returns (uint64, BlockStateProof memory proof)\\n    {\\n        require(encoded.length - offset >= 104, \\\"Proof Underflow (Block)\\\");\\n        proof.blockNumber = encoded.toUint64(offset);\\n        proof.globalStateRoot = encoded.toBytes32(offset + 8);\\n        proof.cumulativeGasUsed = encoded.toUint64(offset + 40);\\n        proof.blockHashRoot = encoded.toBytes32(offset + 72);\\n        return (offset + 104, proof);\\n    }\\n\\n    function encodeBlockStateProof(BlockStateProof memory proof) internal pure returns (bytes memory encoded) {\\n        encoded = encoded.concat(abi.encodePacked(proof.blockNumber));\\n        encoded = encoded.concat(abi.encodePacked(proof.globalStateRoot));\\n        encoded = encoded.concat(abi.encodePacked(proof.cumulativeGasUsed));\\n        encoded = encoded.concat(abi.encodePacked(proof.blockHashRoot));\\n    }\\n\\n    function hashBlockStateProof(BlockStateProof memory proof) internal pure returns (bytes32) {\\n        return keccak256(encodeBlockStateProof(proof));\\n    }\\n\\n    struct CodeProof {\\n        uint64 ptr;\\n        uint64 size;\\n    }\\n\\n    function decodeCodeProof(bytes calldata encoded, uint64 offset)\\n        internal\\n        pure\\n        returns (uint64, CodeProof memory proof)\\n    {\\n        require(encoded.length - offset >= 8, \\\"Proof Underflow (Code)\\\");\\n        // Decode bytecode size in bytes\\n        uint64 contentSize = encoded.toUint64(offset);\\n        require(encoded.length - offset >= 8 + contentSize, \\\"Proof Underflow (Code)\\\");\\n        offset += 8;\\n        proof.ptr = offset;\\n        proof.size = contentSize;\\n        return (offset + contentSize, proof);\\n    }\\n\\n    function getOpCodeAt(CodeProof memory proof, bytes calldata encoded, uint64 idx) internal pure returns (uint8) {\\n        if (idx >= proof.size) {\\n            return 0;\\n        }\\n        return uint8(encoded[proof.ptr + idx]);\\n    }\\n\\n    function getCodeSlice(CodeProof memory proof, bytes calldata encoded, uint64 offset, uint64 size)\\n        internal\\n        pure\\n        returns (bytes memory)\\n    {\\n        if (offset + size > proof.size) {\\n            return encoded.slice(proof.ptr + offset, size).concat(new bytes(size - (proof.size - offset)));\\n        }\\n        return encoded.slice(proof.ptr + offset, size);\\n    }\\n\\n    function hashCodeProof(CodeProof memory proof, bytes calldata encoded) internal pure returns (bytes32) {\\n        return keccak256(encoded[proof.ptr:proof.ptr + proof.size]);\\n    }\\n\\n    struct StackProof {\\n        // The elements popped in the step\\n        uint256[] pops;\\n        // The stack hash after popping above elements\\n        bytes32 stackHashAfterPops;\\n    }\\n\\n    function decodeStackProof(bytes calldata encoded, uint64 offset, uint64 popNum)\\n        internal\\n        pure\\n        returns (uint64, StackProof memory proof)\\n    {\\n        if (popNum == 0) {\\n            // No StackProof needed for popNum == 0\\n            return (offset, proof);\\n        }\\n        require(encoded.length - offset >= 32 * (popNum + 1), \\\"Proof Underflow (Stack)\\\");\\n        proof.pops = new uint256[](popNum);\\n        // Decode popped elements\\n        for (uint64 i = 0; i < popNum; i++) {\\n            proof.pops[i] = encoded.toUint256(offset);\\n            offset += 32;\\n        }\\n        // Decode stackHashAfterPops\\n        proof.stackHashAfterPops = encoded.toBytes32(offset);\\n        offset += 32;\\n        return (offset, proof);\\n    }\\n\\n    function encodeStackProof(StackProof memory proof) internal pure returns (bytes memory encoded) {\\n        for (uint64 i = 0; i < proof.pops.length; i++) {\\n            encoded = encoded.concat(abi.encodePacked(proof.pops[i]));\\n        }\\n        encoded = encoded.concat(abi.encodePacked(proof.stackHashAfterPops));\\n    }\\n\\n    struct MemoryMerkleProof {\\n        bytes32[] proof;\\n    }\\n\\n    function decodeMemoryMerkleProof(bytes calldata encoded, uint64 offset)\\n        internal\\n        pure\\n        returns (uint64, MemoryMerkleProof memory proof)\\n    {\\n        require(encoded.length - offset >= 8, \\\"Proof Underflow\\\");\\n        uint64 len = encoded.toUint64(offset);\\n        offset += 8;\\n        require(encoded.length - offset >= 32 * len, \\\"Proof Underflow\\\");\\n        proof.proof = new bytes32[](len);\\n        for (uint64 i = 0; i < len; i++) {\\n            proof.proof[i] = encoded.toBytes32(offset);\\n            offset += 32;\\n        }\\n        return (offset, proof);\\n    }\\n\\n    struct MemoryReadProof {\\n        bytes32[] cells;\\n    }\\n\\n    function decodeMemoryReadProof(bytes calldata encoded, uint64 offset, uint64 cellNum)\\n        internal\\n        pure\\n        returns (uint64, MemoryReadProof memory proof)\\n    {\\n        require(encoded.length - offset >= 32 * cellNum, \\\"Proof Underflow\\\");\\n        proof.cells = new bytes32[](cellNum);\\n        for (uint64 i = 0; i < cellNum; i++) {\\n            proof.cells[i] = encoded.toBytes32(offset);\\n            offset += 32;\\n        }\\n        return (offset, proof);\\n    }\\n\\n    struct MemoryWriteProof {\\n        bytes32[] cells;\\n        bytes32[] updatedCells;\\n    }\\n\\n    function decodeMemoryWriteProof(bytes calldata encoded, uint64 offset, uint64 cellNum)\\n        internal\\n        pure\\n        returns (uint64, MemoryWriteProof memory proof)\\n    {\\n        require(encoded.length - offset >= 64 * cellNum, \\\"Proof Underflow\\\");\\n        proof.cells = new bytes32[](cellNum);\\n        for (uint64 i = 0; i < cellNum; i++) {\\n            proof.cells[i] = encoded.toBytes32(offset);\\n            offset += 32;\\n        }\\n        proof.updatedCells = new bytes32[](cellNum);\\n        for (uint64 i = 0; i < cellNum; i++) {\\n            proof.updatedCells[i] = encoded.toBytes32(offset);\\n            offset += 32;\\n        }\\n        return (offset, proof);\\n    }\\n\\n    struct MemoryAppendProof {\\n        bytes32[] appendCells;\\n    }\\n\\n    function decodeMemoryAppendProof(bytes calldata encoded, uint64 offset, uint64 cellNum)\\n        internal\\n        pure\\n        returns (uint64, MemoryAppendProof memory proof)\\n    {\\n        require(encoded.length - offset >= 32 * cellNum, \\\"Proof Underflow\\\");\\n        proof.appendCells = new bytes32[](cellNum);\\n        for (uint64 i = 0; i < cellNum; i++) {\\n            proof.appendCells[i] = encoded.toBytes32(offset);\\n            offset += 32;\\n        }\\n        return (offset, proof);\\n    }\\n\\n    struct MemoryCombinedReadProof {\\n        bytes32[] cells;\\n        bytes32[] appendCells;\\n    }\\n\\n    function decodeMemoryCombinedReadProof(bytes calldata encoded, uint64 offset, uint64 cellNum, uint64 appendCellNum)\\n        internal\\n        pure\\n        returns (uint64, MemoryCombinedReadProof memory proof)\\n    {\\n        require(encoded.length - offset >= 32 * (cellNum + appendCellNum), \\\"Proof Underflow\\\");\\n        proof.cells = new bytes32[](cellNum);\\n        for (uint64 i = 0; i < cellNum; i++) {\\n            proof.cells[i] = encoded.toBytes32(offset);\\n            offset += 32;\\n        }\\n        proof.appendCells = new bytes32[](appendCellNum);\\n        for (uint64 i = 0; i < appendCellNum; i++) {\\n            proof.appendCells[i] = encoded.toBytes32(offset);\\n            offset += 32;\\n        }\\n        return (offset, proof);\\n    }\\n\\n    struct MemoryCombinedWriteProof {\\n        bytes32[] cells;\\n        bytes32[] updatedCells;\\n        bytes32[] appendCells;\\n    }\\n\\n    function decodeMemoryCombinedWriteProof(bytes calldata encoded, uint64 offset, uint64 cellNum, uint64 appendCellNum)\\n        internal\\n        pure\\n        returns (uint64, MemoryCombinedWriteProof memory proof)\\n    {\\n        require(encoded.length - offset >= 32 * (2 * cellNum + appendCellNum), \\\"Proof Underflow\\\");\\n        proof.cells = new bytes32[](cellNum);\\n        for (uint64 i = 0; i < cellNum; i++) {\\n            proof.cells[i] = encoded.toBytes32(offset);\\n            offset += 32;\\n        }\\n        proof.updatedCells = new bytes32[](cellNum);\\n        for (uint64 i = 0; i < cellNum; i++) {\\n            proof.updatedCells[i] = encoded.toBytes32(offset);\\n            offset += 32;\\n        }\\n        proof.appendCells = new bytes32[](appendCellNum);\\n        for (uint64 i = 0; i < appendCellNum; i++) {\\n            proof.appendCells[i] = encoded.toBytes32(offset);\\n            offset += 32;\\n        }\\n        return (offset, proof);\\n    }\\n\\n    // For MPT proof, receipt proof\\n    struct RLPProof {\\n        RLPReader.RLPItem proof;\\n    }\\n\\n    function decodeRLPProof(bytes calldata encoded, uint64 offset)\\n        internal\\n        pure\\n        returns (uint64, RLPProof memory proof)\\n    {\\n        require(encoded.length - offset >= 8, \\\"Proof Underflow\\\");\\n        uint64 len = encoded.toUint64(offset);\\n        offset += 8;\\n        require(encoded.length - offset >= len, \\\"Proof Underflow\\\");\\n        proof.proof = encoded.slice(offset, len).toRlpItem();\\n        return (offset + len, proof);\\n    }\\n\\n    struct BlockHashProof {\\n        bytes32 blockHash;\\n    }\\n\\n    function decodeBlockHashProof(bytes calldata encoded, uint64 offset)\\n        internal\\n        pure\\n        returns (uint64, BlockHashProof memory proof)\\n    {\\n        require(encoded.length - offset >= 32, \\\"Proof Underflow\\\");\\n        proof.blockHash = encoded.toBytes32(offset);\\n        return (offset + 32, proof);\\n    }\\n\\n    struct BlockHashMerkleProof {\\n        uint64 path;\\n        bytes32[] proof;\\n    }\\n\\n    function decodeBlockHashMerkleProof(bytes memory encoded, uint64 offset)\\n        internal\\n        pure\\n        returns (uint64, BlockHashMerkleProof memory proof)\\n    {\\n        require(encoded.length - offset >= 9, \\\"Proof Underflow\\\");\\n        proof.path = encoded.toUint64(offset);\\n        uint8 len = encoded.toUint8(offset + 8);\\n        offset += 9;\\n        require(encoded.length - offset >= 32 * len, \\\"Proof Underflow\\\");\\n        proof.proof = new bytes32[](len);\\n        for (uint64 i = 0; i < len; i++) {\\n            proof.proof[i] = encoded.toBytes32(offset);\\n            offset += 32;\\n        }\\n        return (offset, proof);\\n    }\\n\\n    struct LogProof {\\n        bytes32 accumulateHash;\\n        BloomLib.Bloom bloom;\\n    }\\n\\n    function decodeLogProof(bytes calldata encoded, uint64 offset)\\n        internal\\n        pure\\n        returns (uint64, LogProof memory proof)\\n    {\\n        require(encoded.length - offset >= 288, \\\"Proof Underflow\\\");\\n        proof.accumulateHash = encoded.toBytes32(offset);\\n        proof.bloom = BloomLib.decodeBloom(encoded, offset + 32);\\n        return (offset + 288, proof);\\n    }\\n\\n    function hashLogProof(LogProof memory proof) internal pure returns (bytes32) {\\n        return keccak256(abi.encodePacked(proof.accumulateHash, proof.bloom.data));\\n    }\\n\\n    struct SelfDestructSetProof {\\n        address[] contracts;\\n    }\\n\\n    function decodeSelfDestructSetProof(bytes calldata encoded, uint64 offset)\\n        internal\\n        pure\\n        returns (uint64, SelfDestructSetProof memory proof)\\n    {\\n        require(encoded.length - offset >= 8, \\\"Proof Underflow\\\");\\n        uint64 len = encoded.toUint64(offset);\\n        offset += 8;\\n        require(encoded.length - offset >= 20 * len, \\\"Proof Underflow\\\");\\n        proof.contracts = new address[](len);\\n        for (uint64 i = 0; i < len; i++) {\\n            proof.contracts[i] = encoded.toAddress(offset);\\n            offset += 20;\\n        }\\n        return (offset, proof);\\n    }\\n}\\n\",\"keccak256\":\"0x62ab225aa64668d73fe77eb0cd364240958325d6a7b985989069e198f5f2506b\",\"license\":\"Apache-2.0\"},\"contracts/L1/fraud-proof/verifier/libraries/Params.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\n\\n/*\\n * Copyright 2022, Specular contributors\\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.0;\\n\\nlibrary Params {\\n    // Verifier\\n    uint8 constant V_STACK_OP = 0;\\n    uint8 constant V_ENVIRONMENTAL_OP = 1;\\n    uint8 constant V_MEMORY_OP = 2;\\n    uint8 constant V_STORAGE_OP = 3;\\n    uint8 constant V_CALL_OP = 4;\\n    uint8 constant V_INVALID_OP = 5;\\n    uint8 constant V_INTER_TX = 6;\\n    uint8 constant V_BLOCK_INIT = 7;\\n    uint8 constant V_BLOCK_FINAL = 8;\\n\\n    // Gas\\n    uint64 constant G_ZERO = 0;\\n    uint64 constant G_JUMPDEST = 1;\\n    uint64 constant G_BASE = 2;\\n    uint64 constant G_VERYLOW = 3;\\n    uint64 constant G_LOW = 5;\\n    uint64 constant G_MID = 8;\\n    uint64 constant G_HIGH = 10;\\n    uint64 constant G_EXTCODE = 700;\\n    uint64 constant G_BALANCE = 700;\\n    uint64 constant G_SLOAD = 800;\\n    uint64 constant G_SSET = 20000;\\n    uint64 constant G_SRESET = 5000;\\n    uint64 constant R_SCLEAR = 15000;\\n    uint64 constant R_SELFDESTRUCT = 24000;\\n    uint64 constant G_SELFDESTRUCT = 5000;\\n    uint64 constant G_CREATE = 32000;\\n    uint64 constant G_CODEDEPOSIT = 200;\\n    uint64 constant G_CALL = 700;\\n    uint64 constant G_CALLVALUE = 9000;\\n    uint64 constant G_CALLSTIPEND = 2300;\\n    uint64 constant G_NEWACCOUNT = 25000;\\n    uint64 constant G_EXP = 10;\\n    uint64 constant G_EXPBYTE = 50;\\n    uint64 constant G_MEMORY = 3;\\n    uint64 constant G_TXCREATE = 32000;\\n    uint64 constant G_TXDATAZERO = 4;\\n    uint64 constant G_TXDATANONZERO = 16;\\n    uint64 constant G_TRANSACTION = 21000;\\n    uint64 constant G_LOG = 375;\\n    uint64 constant G_LOGDATA = 8;\\n    uint64 constant G_LOGTOPIC = 375;\\n    uint64 constant G_KECCAK = 30;\\n    uint64 constant G_KECCAKWORD = 6;\\n    uint64 constant G_COPY = 3;\\n    uint64 constant G_BLOCKHASH = 20;\\n    uint64 constant G_QUADDIVISOR = 20;\\n\\n    // Stack\\n    uint64 constant STACK_LIMIT = 1024;\\n\\n    bytes32 constant EMPTY_TRIE_ROOT = 0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421;\\n    bytes32 constant EMPTY_CODE_HASH = 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470;\\n    bytes32 constant EMPTY_UNCLE_HASH = 0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347;\\n    uint64 constant RECENT_BLOCK_HASHES_LENGTH = 256;\\n}\\n\",\"keccak256\":\"0x0ffb44d6f81d7281286b6f90b15908e965de720e3ca832cdf268c373ee9aa1fb\",\"license\":\"Apache-2.0\"},\"contracts/L1/fraud-proof/verifier/libraries/VerificationContext.sol\":{\"content\":\"// SPDX-License-Identifier: Apache-2.0\\n\\n/*\\n * Copyright 2022, Specular contributors\\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.0;\\n\\nimport \\\"../../libraries/DeserializationLib.sol\\\";\\nimport \\\"../../libraries/BytesLib.sol\\\";\\nimport \\\"../../libraries/MerkleLib.sol\\\";\\n\\nimport \\\"./MemoryLib.sol\\\";\\nimport \\\"./EVMTypesLib.sol\\\";\\n\\nlibrary VerificationContext {\\n    using BytesLib for bytes;\\n    using EVMTypesLib for EVMTypesLib.Transaction;\\n\\n    struct Context {\\n        address coinbase;\\n        uint256 timestamp;\\n        uint256 number;\\n        address origin;\\n        EVMTypesLib.Transaction transaction;\\n        bytes32 inputRoot;\\n        bytes32 txHash;\\n    }\\n\\n    function newContext(bytes calldata proof) internal view returns (Context memory ctx) {\\n//        inbox.verifyTxInclusion(proof);\\n//        ctx.coinbase = inbox.sequencerAddress();\\n        ctx.coinbase = address(0); // TODO FIXME\\n        uint256 offset = 0;\\n        uint256 txDataLength;\\n        (offset, ctx.origin) = DeserializationLib.deserializeAddress(proof, offset);\\n        (offset, ctx.number) = DeserializationLib.deserializeUint256(proof, offset);\\n        (offset, ctx.timestamp) = DeserializationLib.deserializeUint256(proof, offset);\\n        (offset, txDataLength) = DeserializationLib.deserializeUint256(proof, offset);\\n        bytes memory txData = bytes(proof[offset:txDataLength]);\\n        ctx.transaction = EVMTypesLib.decodeTransaction(txData);\\n    }\\n\\n    function getCoinbase(Context memory ctx) internal pure returns (address) {\\n        return ctx.coinbase;\\n    }\\n\\n    function getTimestamp(Context memory ctx) internal pure returns (uint256) {\\n        return ctx.timestamp;\\n    }\\n\\n    function getBlockNumber(Context memory ctx) internal pure returns (uint256) {\\n        return ctx.number;\\n    }\\n\\n    function getDifficulty(Context memory) internal pure returns (uint256) {\\n        return 1;\\n    }\\n\\n    function getGasLimit(Context memory) internal pure returns (uint64) {\\n        return 80000000;\\n    }\\n\\n    function getChainID(Context memory) internal pure returns (uint256) {\\n        return 13527;\\n    }\\n\\n    // Transaction\\n    function getOrigin(Context memory ctx) internal pure returns (address) {\\n        return ctx.origin;\\n    }\\n\\n    function getRecipient(Context memory ctx) internal pure returns (address) {\\n        return ctx.transaction.to;\\n    }\\n\\n    function getValue(Context memory ctx) internal pure returns (uint256) {\\n        return ctx.transaction.value;\\n    }\\n\\n    function getGas(Context memory ctx) internal pure returns (uint64) {\\n        return ctx.transaction.gas;\\n    }\\n\\n    function getGasPrice(Context memory ctx) internal pure returns (uint256) {\\n        return ctx.transaction.gasPrice;\\n    }\\n\\n    function getInput(Context memory ctx) internal pure returns (bytes memory) {\\n        return ctx.transaction.data;\\n    }\\n\\n    function getInputSize(Context memory ctx) internal pure returns (uint64) {\\n        return uint64(ctx.transaction.data.length);\\n    }\\n\\n    function getInputRoot(Context memory ctx) internal pure returns (bytes32) {\\n        if (ctx.inputRoot == 0x0) {\\n            ctx.inputRoot = MemoryLib.getMemoryRoot(ctx.transaction.data);\\n        }\\n        return ctx.inputRoot;\\n    }\\n\\n    function getTxHash(Context memory ctx) internal pure returns (bytes32) {\\n        if (ctx.txHash == 0x0) {\\n            ctx.txHash = ctx.transaction.hashTransaction();\\n        }\\n        return ctx.transaction.hashTransaction();\\n    }\\n}\\n\",\"keccak256\":\"0x6d6c6af5ddc7d9af49703ddbb96358a952537ecaec3a1d32ab0272dddf419017\",\"license\":\"Apache-2.0\"}},\"version\":1}",
  "bytecode": "0x608060405234801561001057600080fd5b5061001961001e565b6100de565b600054610100900460ff161561008a5760405162461bcd60e51b815260206004820152602760248201527f496e697469616c697a61626c653a20636f6e747261637420697320696e697469604482015266616c697a696e6760c81b606482015260840160405180910390fd5b60005460ff90811610156100dc576000805460ff191660ff9081179091556040519081527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b565b610dda806100ed6000396000f3fe608060405234801561001057600080fd5b50600436106100f55760003560e01c8063625eb72e116100975780638da5cb5b116100665780638da5cb5b146101e25780639d765195146101f3578063aa8841a214610206578063f2fde38b1461021957600080fd5b8063625eb72e1461019e5780636ab263d0146101bf578063715018a6146101d25780638129fc1c146101da57600080fd5b80633f1bf192116100d35780633f1bf192146101525780634539aaef1461016557806353660e701461017857806354f5b8581461018b57600080fd5b806317facb7d146100fa578063199efa461461012a5780632fb8ff971461013d575b600080fd5b606a5461010d906001600160a01b031681565b6040516001600160a01b0390911681526020015b60405180910390f35b606c5461010d906001600160a01b031681565b61015061014b366004610850565b61022c565b005b606d5461010d906001600160a01b031681565b60695461010d906001600160a01b031681565b60685461010d906001600160a01b031681565b606b5461010d906001600160a01b031681565b6101b16101ac366004610a93565b6103ee565b604051908152602001610121565b60675461010d906001600160a01b031681565b610150610584565b610150610598565b6033546001600160a01b031661010d565b60665461010d906001600160a01b031681565b60655461010d906001600160a01b031681565b610150610227366004610b92565b6106a9565b61023461071f565b60ff82166007141561025f57606580546001600160a01b0319166001600160a01b0383161790555050565b60ff82166008141561028a57606680546001600160a01b0319166001600160a01b0383161790555050565b60ff8216600614156102b557606780546001600160a01b0319166001600160a01b0383161790555050565b60ff82166102dc57606880546001600160a01b0319166001600160a01b0383161790555050565b60ff82166001141561030757606980546001600160a01b0319166001600160a01b0383161790555050565b60ff82166002141561033257606a80546001600160a01b0319166001600160a01b0383161790555050565b60ff82166003141561035d57606b80546001600160a01b0319166001600160a01b0383161790555050565b60ff82166004141561038857606c80546001600160a01b0319166001600160a01b0383161790555050565b60ff8216600514156103b357606d80546001600160a01b0319166001600160a01b0383161790555050565b60405162461bcd60e51b815260206004820152600b60248201526a756e726561636861626c6560a81b60448201526064015b60405180910390fd5b60008060ff86166007141561040f57506065546001600160a01b03166104f7565b60ff86166008141561042d57506066546001600160a01b03166104f7565b60ff86166006141561044b57506067546001600160a01b03166104f7565b60ff861661046557506068546001600160a01b03166104f7565b60ff86166001141561048357506069546001600160a01b03166104f7565b60ff8616600214156104a15750606a546001600160a01b03166104f7565b60ff8616600314156104bf5750606b546001600160a01b03166104f7565b60ff8616600414156104dd5750606c546001600160a01b03166104f7565b60ff8616600514156103b35750606d546001600160a01b03165b60405163084e2cf960e21b81526001600160a01b03821690632138b3e490610529908a90899089908990600401610c2c565b60206040518083038186803b15801561054157600080fd5b505afa158015610555573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105799190610d40565b979650505050505050565b61058c61071f565b6105966000610779565b565b600054610100900460ff16158080156105b85750600054600160ff909116105b806105d25750303b1580156105d2575060005460ff166001145b6106355760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b60648201526084016103e5565b6000805460ff191660011790558015610658576000805461ff0019166101001790555b6106606107cb565b80156106a6576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b50565b6106b161071f565b6001600160a01b0381166107165760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b60648201526084016103e5565b6106a681610779565b6033546001600160a01b031633146105965760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016103e5565b603380546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b600054610100900460ff166107f25760405162461bcd60e51b81526004016103e590610d59565b610596600054610100900460ff1661081c5760405162461bcd60e51b81526004016103e590610d59565b61059633610779565b803560ff8116811461083657600080fd5b919050565b6001600160a01b03811681146106a657600080fd5b6000806040838503121561086357600080fd5b61086c83610825565b9150602083013561087c8161083b565b809150509250929050565b634e487b7160e01b600052604160045260246000fd5b604051610120810167ffffffffffffffff811182821017156108c1576108c1610887565b60405290565b60405160e0810167ffffffffffffffff811182821017156108c1576108c1610887565b80356108368161083b565b803567ffffffffffffffff8116811461083657600080fd5b600082601f83011261091e57600080fd5b813567ffffffffffffffff8082111561093957610939610887565b604051601f8301601f19908116603f0116810190828211818310171561096157610961610887565b8160405283815286602085880101111561097a57600080fd5b836020870160208301376000602085830101528094505050505092915050565b600061012082840312156109ad57600080fd5b6109b561089d565b90506109c0826108f5565b8152602082013560208201526109d8604083016108f5565b60408201526109e9606083016108ea565b60608201526080820135608082015260a082013567ffffffffffffffff811115610a1257600080fd5b610a1e8482850161090d565b60a08301525060c082013560c082015260e082013560e082015261010080830135818301525092915050565b60008083601f840112610a5c57600080fd5b50813567ffffffffffffffff811115610a7457600080fd5b602083019150836020828501011115610a8c57600080fd5b9250929050565b600080600080600060808688031215610aab57600080fd5b853567ffffffffffffffff80821115610ac357600080fd5b9087019060e0828a031215610ad757600080fd5b610adf6108c7565b610ae8836108ea565b81526020830135602082015260408301356040820152610b0a606084016108ea565b6060820152608083013582811115610b2157600080fd5b610b2d8b82860161099a565b60808301525060a083013560a082015260c083013560c082015280975050610b5760208901610825565b9550604088013594506060880135915080821115610b7457600080fd5b50610b8188828901610a4a565b969995985093965092949392505050565b600060208284031215610ba457600080fd5b8135610baf8161083b565b9392505050565b6000815180845260005b81811015610bdc57602081850181015186830182015201610bc0565b81811115610bee576000602083870101525b50601f01601f19169290920160200192915050565b81835281816020850137506000828201602090810191909152601f909101601f19169091010190565b606080825285516001600160a01b03908116838301526020870151608080850191909152604088015160a0850152918701511660c083015285015160e080830152805167ffffffffffffffff166101408301526000906020810151610160840152604081015167ffffffffffffffff81166101808501525060608101516001600160a01b0381166101a08501525060808101516101c084015260a0810151610120806101e0860152610ce2610260860183610bb6565b915060c083015161020086015260e08301516102208601526101008084015161024087015260a08a0151818701525060c089015181860152508660208501528381036040850152610d34818688610c03565b98975050505050505050565b600060208284031215610d5257600080fd5b5051919050565b6020808252602b908201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960408201526a6e697469616c697a696e6760a81b60608201526080019056fea26469706673582212200bd100fa3344ca78ee347abeec803c882c250645acec9b28242d0fa1a9fb251e64736f6c63430008090033",
  "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106100f55760003560e01c8063625eb72e116100975780638da5cb5b116100665780638da5cb5b146101e25780639d765195146101f3578063aa8841a214610206578063f2fde38b1461021957600080fd5b8063625eb72e1461019e5780636ab263d0146101bf578063715018a6146101d25780638129fc1c146101da57600080fd5b80633f1bf192116100d35780633f1bf192146101525780634539aaef1461016557806353660e701461017857806354f5b8581461018b57600080fd5b806317facb7d146100fa578063199efa461461012a5780632fb8ff971461013d575b600080fd5b606a5461010d906001600160a01b031681565b6040516001600160a01b0390911681526020015b60405180910390f35b606c5461010d906001600160a01b031681565b61015061014b366004610850565b61022c565b005b606d5461010d906001600160a01b031681565b60695461010d906001600160a01b031681565b60685461010d906001600160a01b031681565b606b5461010d906001600160a01b031681565b6101b16101ac366004610a93565b6103ee565b604051908152602001610121565b60675461010d906001600160a01b031681565b610150610584565b610150610598565b6033546001600160a01b031661010d565b60665461010d906001600160a01b031681565b60655461010d906001600160a01b031681565b610150610227366004610b92565b6106a9565b61023461071f565b60ff82166007141561025f57606580546001600160a01b0319166001600160a01b0383161790555050565b60ff82166008141561028a57606680546001600160a01b0319166001600160a01b0383161790555050565b60ff8216600614156102b557606780546001600160a01b0319166001600160a01b0383161790555050565b60ff82166102dc57606880546001600160a01b0319166001600160a01b0383161790555050565b60ff82166001141561030757606980546001600160a01b0319166001600160a01b0383161790555050565b60ff82166002141561033257606a80546001600160a01b0319166001600160a01b0383161790555050565b60ff82166003141561035d57606b80546001600160a01b0319166001600160a01b0383161790555050565b60ff82166004141561038857606c80546001600160a01b0319166001600160a01b0383161790555050565b60ff8216600514156103b357606d80546001600160a01b0319166001600160a01b0383161790555050565b60405162461bcd60e51b815260206004820152600b60248201526a756e726561636861626c6560a81b60448201526064015b60405180910390fd5b60008060ff86166007141561040f57506065546001600160a01b03166104f7565b60ff86166008141561042d57506066546001600160a01b03166104f7565b60ff86166006141561044b57506067546001600160a01b03166104f7565b60ff861661046557506068546001600160a01b03166104f7565b60ff86166001141561048357506069546001600160a01b03166104f7565b60ff8616600214156104a15750606a546001600160a01b03166104f7565b60ff8616600314156104bf5750606b546001600160a01b03166104f7565b60ff8616600414156104dd5750606c546001600160a01b03166104f7565b60ff8616600514156103b35750606d546001600160a01b03165b60405163084e2cf960e21b81526001600160a01b03821690632138b3e490610529908a90899089908990600401610c2c565b60206040518083038186803b15801561054157600080fd5b505afa158015610555573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105799190610d40565b979650505050505050565b61058c61071f565b6105966000610779565b565b600054610100900460ff16158080156105b85750600054600160ff909116105b806105d25750303b1580156105d2575060005460ff166001145b6106355760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b60648201526084016103e5565b6000805460ff191660011790558015610658576000805461ff0019166101001790555b6106606107cb565b80156106a6576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b50565b6106b161071f565b6001600160a01b0381166107165760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b60648201526084016103e5565b6106a681610779565b6033546001600160a01b031633146105965760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016103e5565b603380546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b600054610100900460ff166107f25760405162461bcd60e51b81526004016103e590610d59565b610596600054610100900460ff1661081c5760405162461bcd60e51b81526004016103e590610d59565b61059633610779565b803560ff8116811461083657600080fd5b919050565b6001600160a01b03811681146106a657600080fd5b6000806040838503121561086357600080fd5b61086c83610825565b9150602083013561087c8161083b565b809150509250929050565b634e487b7160e01b600052604160045260246000fd5b604051610120810167ffffffffffffffff811182821017156108c1576108c1610887565b60405290565b60405160e0810167ffffffffffffffff811182821017156108c1576108c1610887565b80356108368161083b565b803567ffffffffffffffff8116811461083657600080fd5b600082601f83011261091e57600080fd5b813567ffffffffffffffff8082111561093957610939610887565b604051601f8301601f19908116603f0116810190828211818310171561096157610961610887565b8160405283815286602085880101111561097a57600080fd5b836020870160208301376000602085830101528094505050505092915050565b600061012082840312156109ad57600080fd5b6109b561089d565b90506109c0826108f5565b8152602082013560208201526109d8604083016108f5565b60408201526109e9606083016108ea565b60608201526080820135608082015260a082013567ffffffffffffffff811115610a1257600080fd5b610a1e8482850161090d565b60a08301525060c082013560c082015260e082013560e082015261010080830135818301525092915050565b60008083601f840112610a5c57600080fd5b50813567ffffffffffffffff811115610a7457600080fd5b602083019150836020828501011115610a8c57600080fd5b9250929050565b600080600080600060808688031215610aab57600080fd5b853567ffffffffffffffff80821115610ac357600080fd5b9087019060e0828a031215610ad757600080fd5b610adf6108c7565b610ae8836108ea565b81526020830135602082015260408301356040820152610b0a606084016108ea565b6060820152608083013582811115610b2157600080fd5b610b2d8b82860161099a565b60808301525060a083013560a082015260c083013560c082015280975050610b5760208901610825565b9550604088013594506060880135915080821115610b7457600080fd5b50610b8188828901610a4a565b969995985093965092949392505050565b600060208284031215610ba457600080fd5b8135610baf8161083b565b9392505050565b6000815180845260005b81811015610bdc57602081850181015186830182015201610bc0565b81811115610bee576000602083870101525b50601f01601f19169290920160200192915050565b81835281816020850137506000828201602090810191909152601f909101601f19169091010190565b606080825285516001600160a01b03908116838301526020870151608080850191909152604088015160a0850152918701511660c083015285015160e080830152805167ffffffffffffffff166101408301526000906020810151610160840152604081015167ffffffffffffffff81166101808501525060608101516001600160a01b0381166101a08501525060808101516101c084015260a0810151610120806101e0860152610ce2610260860183610bb6565b915060c083015161020086015260e08301516102208601526101008084015161024087015260a08a0151818701525060c089015181860152508660208501528381036040850152610d34818688610c03565b98975050505050505050565b600060208284031215610d5257600080fd5b5051919050565b6020808252602b908201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960408201526a6e697469616c697a696e6760a81b60608201526080019056fea26469706673582212200bd100fa3344ca78ee347abeec803c882c250645acec9b28242d0fa1a9fb251e64736f6c63430008090033",
  "devdoc": {
    "kind": "dev",
    "methods": {
      "constructor": {
        "custom:oz-upgrades-unsafe-allow": "constructor"
      },
      "owner()": {
        "details": "Returns the address of the current owner."
      },
      "renounceOwnership()": {
        "details": "Leaves the contract without owner. It will not be possible to call `onlyOwner` functions anymore. Can only be called by the current owner. NOTE: Renouncing ownership will leave the contract without an owner, thereby removing any functionality that is only available to the owner."
      },
      "transferOwnership(address)": {
        "details": "Transfers ownership of the contract to a new account (`newOwner`). Can only be called by the current owner."
      }
    },
    "version": 1
  },
  "userdoc": {
    "kind": "user",
    "methods": {},
    "version": 1
  },
  "storageLayout": {
    "storage": [
      {
        "astId": 216,
        "contract": "contracts/L1/fraud-proof/verifier/VerifierEntry.sol:VerifierEntry",
        "label": "_initialized",
        "offset": 0,
        "slot": "0",
        "type": "t_uint8"
      },
      {
        "astId": 219,
        "contract": "contracts/L1/fraud-proof/verifier/VerifierEntry.sol:VerifierEntry",
        "label": "_initializing",
        "offset": 1,
        "slot": "0",
        "type": "t_bool"
      },
      {
        "astId": 2492,
        "contract": "contracts/L1/fraud-proof/verifier/VerifierEntry.sol:VerifierEntry",
        "label": "__gap",
        "offset": 0,
        "slot": "1",
        "type": "t_array(t_uint256)50_storage"
      },
      {
        "astId": 10,
        "contract": "contracts/L1/fraud-proof/verifier/VerifierEntry.sol:VerifierEntry",
        "label": "_owner",
        "offset": 0,
        "slot": "51",
        "type": "t_address"
      },
      {
        "astId": 130,
        "contract": "contracts/L1/fraud-proof/verifier/VerifierEntry.sol:VerifierEntry",
        "label": "__gap",
        "offset": 0,
        "slot": "52",
        "type": "t_array(t_uint256)49_storage"
      },
      {
        "astId": 24982,
        "contract": "contracts/L1/fraud-proof/verifier/VerifierEntry.sol:VerifierEntry",
        "label": "blockInitiationVerifier",
        "offset": 0,
        "slot": "101",
        "type": "t_contract(IVerifier)24947"
      },
      {
        "astId": 24985,
        "contract": "contracts/L1/fraud-proof/verifier/VerifierEntry.sol:VerifierEntry",
        "label": "blockFinalizationVerifier",
        "offset": 0,
        "slot": "102",
        "type": "t_contract(IVerifier)24947"
      },
      {
        "astId": 24988,
        "contract": "contracts/L1/fraud-proof/verifier/VerifierEntry.sol:VerifierEntry",
        "label": "interTxVerifier",
        "offset": 0,
        "slot": "103",
        "type": "t_contract(IVerifier)24947"
      },
      {
        "astId": 24991,
        "contract": "contracts/L1/fraud-proof/verifier/VerifierEntry.sol:VerifierEntry",
        "label": "stackOpVerifier",
        "offset": 0,
        "slot": "104",
        "type": "t_contract(IVerifier)24947"
      },
      {
        "astId": 24994,
        "contract": "contracts/L1/fraud-proof/verifier/VerifierEntry.sol:VerifierEntry",
        "label": "environmentalOpVerifier",
        "offset": 0,
        "slot": "105",
        "type": "t_contract(IVerifier)24947"
      },
      {
        "astId": 24997,
        "contract": "contracts/L1/fraud-proof/verifier/VerifierEntry.sol:VerifierEntry",
        "label": "memoryOpVerifier",
        "offset": 0,
        "slot": "106",
        "type": "t_contract(IVerifier)24947"
      },
      {
        "astId": 25000,
        "contract": "contracts/L1/fraud-proof/verifier/VerifierEntry.sol:VerifierEntry",
        "label": "storageOpVerifier",
        "offset": 0,
        "slot": "107",
        "type": "t_contract(IVerifier)24947"
      },
      {
        "astId": 25003,
        "contract": "contracts/L1/fraud-proof/verifier/VerifierEntry.sol:VerifierEntry",
        "label": "callOpVerifier",
        "offset": 0,
        "slot": "108",
        "type": "t_contract(IVerifier)24947"
      },
      {
        "astId": 25006,
        "contract": "contracts/L1/fraud-proof/verifier/VerifierEntry.sol:VerifierEntry",
        "label": "invalidOpVerifier",
        "offset": 0,
        "slot": "109",
        "type": "t_contract(IVerifier)24947"
      }
    ],
    "types": {
      "t_address": {
        "encoding": "inplace",
        "label": "address",
        "numberOfBytes": "20"
      },
      "t_array(t_uint256)49_storage": {
        "base": "t_uint256",
        "encoding": "inplace",
        "label": "uint256[49]",
        "numberOfBytes": "1568"
      },
      "t_array(t_uint256)50_storage": {
        "base": "t_uint256",
        "encoding": "inplace",
        "label": "uint256[50]",
        "numberOfBytes": "1600"
      },
      "t_bool": {
        "encoding": "inplace",
        "label": "bool",
        "numberOfBytes": "1"
      },
      "t_contract(IVerifier)24947": {
        "encoding": "inplace",
        "label": "contract IVerifier",
        "numberOfBytes": "20"
      },
      "t_uint256": {
        "encoding": "inplace",
        "label": "uint256",
        "numberOfBytes": "32"
      },
      "t_uint8": {
        "encoding": "inplace",
        "label": "uint8",
        "numberOfBytes": "1"
      }
    }
  }
}