{
  "address": "0x1c15fcA66a14eB2de5cDCf0BF1f45580b58ca5AC",
  "abi": [
    {
      "inputs": [],
      "stateMutability": "nonpayable",
      "type": "constructor"
    },
    {
      "anonymous": false,
      "inputs": [
        {
          "indexed": false,
          "internalType": "bytes32",
          "name": "msgHash",
          "type": "bytes32"
        }
      ],
      "name": "RelayedMessage",
      "type": "event"
    },
    {
      "anonymous": false,
      "inputs": [
        {
          "indexed": false,
          "internalType": "bytes",
          "name": "message",
          "type": "bytes"
        }
      ],
      "name": "SentMessage",
      "type": "event"
    },
    {
      "inputs": [
        {
          "internalType": "address",
          "name": "_libAddressManager",
          "type": "address"
        }
      ],
      "name": "initialize",
      "outputs": [],
      "stateMutability": "nonpayable",
      "type": "function"
    },
    {
      "inputs": [],
      "name": "messageNonce",
      "outputs": [
        {
          "internalType": "uint256",
          "name": "",
          "type": "uint256"
        }
      ],
      "stateMutability": "view",
      "type": "function"
    },
    {
      "inputs": [
        {
          "internalType": "address",
          "name": "_target",
          "type": "address"
        },
        {
          "internalType": "address",
          "name": "_sender",
          "type": "address"
        },
        {
          "internalType": "bytes",
          "name": "_message",
          "type": "bytes"
        },
        {
          "internalType": "uint256",
          "name": "_messageNonce",
          "type": "uint256"
        },
        {
          "components": [
            {
              "internalType": "bytes32",
              "name": "stateRoot",
              "type": "bytes32"
            },
            {
              "components": [
                {
                  "internalType": "uint256",
                  "name": "batchIndex",
                  "type": "uint256"
                },
                {
                  "internalType": "bytes32",
                  "name": "batchRoot",
                  "type": "bytes32"
                },
                {
                  "internalType": "uint256",
                  "name": "batchSize",
                  "type": "uint256"
                },
                {
                  "internalType": "uint256",
                  "name": "prevTotalElements",
                  "type": "uint256"
                },
                {
                  "internalType": "bytes",
                  "name": "extraData",
                  "type": "bytes"
                }
              ],
              "internalType": "struct Lib_OVMCodec.ChainBatchHeader",
              "name": "stateRootBatchHeader",
              "type": "tuple"
            },
            {
              "components": [
                {
                  "internalType": "uint256",
                  "name": "index",
                  "type": "uint256"
                },
                {
                  "internalType": "bytes32[]",
                  "name": "siblings",
                  "type": "bytes32[]"
                }
              ],
              "internalType": "struct Lib_OVMCodec.ChainInclusionProof",
              "name": "stateRootProof",
              "type": "tuple"
            },
            {
              "internalType": "bytes",
              "name": "stateTrieWitness",
              "type": "bytes"
            },
            {
              "internalType": "bytes",
              "name": "storageTrieWitness",
              "type": "bytes"
            }
          ],
          "internalType": "struct iOVM_L1CrossDomainMessenger.L2MessageInclusionProof",
          "name": "_proof",
          "type": "tuple"
        }
      ],
      "name": "relayMessage",
      "outputs": [],
      "stateMutability": "nonpayable",
      "type": "function"
    },
    {
      "inputs": [
        {
          "internalType": "bytes32",
          "name": "",
          "type": "bytes32"
        }
      ],
      "name": "relayedMessages",
      "outputs": [
        {
          "internalType": "bool",
          "name": "",
          "type": "bool"
        }
      ],
      "stateMutability": "view",
      "type": "function"
    },
    {
      "inputs": [
        {
          "internalType": "address",
          "name": "_target",
          "type": "address"
        },
        {
          "internalType": "address",
          "name": "_sender",
          "type": "address"
        },
        {
          "internalType": "bytes",
          "name": "_message",
          "type": "bytes"
        },
        {
          "internalType": "uint256",
          "name": "_messageNonce",
          "type": "uint256"
        },
        {
          "internalType": "uint32",
          "name": "_gasLimit",
          "type": "uint32"
        }
      ],
      "name": "replayMessage",
      "outputs": [],
      "stateMutability": "nonpayable",
      "type": "function"
    },
    {
      "inputs": [
        {
          "internalType": "string",
          "name": "_name",
          "type": "string"
        }
      ],
      "name": "resolve",
      "outputs": [
        {
          "internalType": "address",
          "name": "_contract",
          "type": "address"
        }
      ],
      "stateMutability": "view",
      "type": "function"
    },
    {
      "inputs": [
        {
          "internalType": "address",
          "name": "_target",
          "type": "address"
        },
        {
          "internalType": "bytes",
          "name": "_message",
          "type": "bytes"
        },
        {
          "internalType": "uint32",
          "name": "_gasLimit",
          "type": "uint32"
        }
      ],
      "name": "sendMessage",
      "outputs": [],
      "stateMutability": "nonpayable",
      "type": "function"
    },
    {
      "inputs": [
        {
          "internalType": "bytes32",
          "name": "",
          "type": "bytes32"
        }
      ],
      "name": "sentMessages",
      "outputs": [
        {
          "internalType": "bool",
          "name": "",
          "type": "bool"
        }
      ],
      "stateMutability": "view",
      "type": "function"
    },
    {
      "inputs": [
        {
          "internalType": "bytes32",
          "name": "",
          "type": "bytes32"
        }
      ],
      "name": "successfulMessages",
      "outputs": [
        {
          "internalType": "bool",
          "name": "",
          "type": "bool"
        }
      ],
      "stateMutability": "view",
      "type": "function"
    },
    {
      "inputs": [],
      "name": "xDomainMessageSender",
      "outputs": [
        {
          "internalType": "address",
          "name": "",
          "type": "address"
        }
      ],
      "stateMutability": "view",
      "type": "function"
    }
  ],
  "transactionHash": "0x58185415b9f46e832c94156c7ff7c404e0bd4e41bf72422cd4da96647cd75f9e",
  "receipt": {
    "to": null,
    "from": "0x558ba9b8d78713fbf768c1f8a584485B4003f43F",
    "contractAddress": "0x2c299baBfF749D06abd68653769Dc1119C401bFF",
    "transactionIndex": 3,
    "gasUsed": "2165184",
    "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
    "blockHash": "0xa32e80c913e7a984d2d98e55cedf5835a409847785ddedfca99c7c17cf0f7add",
    "transactionHash": "0x58185415b9f46e832c94156c7ff7c404e0bd4e41bf72422cd4da96647cd75f9e",
    "logs": [],
    "blockNumber": 4573442,
    "cumulativeGasUsed": "2405923",
    "status": 1,
    "byzantium": true
  },
  "args": [],
  "solcInputHash": "cebcb515c1a9c570d96e0b8f6fd237e2",
  "metadata": "{\"compiler\":{\"version\":\"0.7.6+commit.7338295f\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"msgHash\",\"type\":\"bytes32\"}],\"name\":\"RelayedMessage\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"message\",\"type\":\"bytes\"}],\"name\":\"SentMessage\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_libAddressManager\",\"type\":\"address\"}],\"name\":\"initialize\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"messageNonce\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_target\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_sender\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_message\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"_messageNonce\",\"type\":\"uint256\"},{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"stateRoot\",\"type\":\"bytes32\"},{\"components\":[{\"internalType\":\"uint256\",\"name\":\"batchIndex\",\"type\":\"uint256\"},{\"internalType\":\"bytes32\",\"name\":\"batchRoot\",\"type\":\"bytes32\"},{\"internalType\":\"uint256\",\"name\":\"batchSize\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"prevTotalElements\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"extraData\",\"type\":\"bytes\"}],\"internalType\":\"struct Lib_OVMCodec.ChainBatchHeader\",\"name\":\"stateRootBatchHeader\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint256\",\"name\":\"index\",\"type\":\"uint256\"},{\"internalType\":\"bytes32[]\",\"name\":\"siblings\",\"type\":\"bytes32[]\"}],\"internalType\":\"struct Lib_OVMCodec.ChainInclusionProof\",\"name\":\"stateRootProof\",\"type\":\"tuple\"},{\"internalType\":\"bytes\",\"name\":\"stateTrieWitness\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"storageTrieWitness\",\"type\":\"bytes\"}],\"internalType\":\"struct iOVM_L1CrossDomainMessenger.L2MessageInclusionProof\",\"name\":\"_proof\",\"type\":\"tuple\"}],\"name\":\"relayMessage\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"name\":\"relayedMessages\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_target\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_sender\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_message\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"_messageNonce\",\"type\":\"uint256\"},{\"internalType\":\"uint32\",\"name\":\"_gasLimit\",\"type\":\"uint32\"}],\"name\":\"replayMessage\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"_name\",\"type\":\"string\"}],\"name\":\"resolve\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"_contract\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_target\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_message\",\"type\":\"bytes\"},{\"internalType\":\"uint32\",\"name\":\"_gasLimit\",\"type\":\"uint32\"}],\"name\":\"sendMessage\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"name\":\"sentMessages\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"name\":\"successfulMessages\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"xDomainMessageSender\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"details\":\"This contract lives on L1. It sends L1->L2 messages into L2, and relays L2->L1 messages from L2 to their target on L1.\",\"kind\":\"dev\",\"methods\":{\"initialize(address)\":{\"params\":{\"_libAddressManager\":\"Address of the Address Manager.\"}},\"relayMessage(address,address,bytes,uint256,(bytes32,(uint256,bytes32,uint256,uint256,bytes),(uint256,bytes32[]),bytes,bytes))\":{\"params\":{\"_message\":\"Message to send to the target.\",\"_messageNonce\":\"Nonce for the provided message.\",\"_proof\":\"Inclusion proof for the given message.\",\"_sender\":\"Message sender address.\",\"_target\":\"Target contract address.\"}},\"replayMessage(address,address,bytes,uint256,uint32)\":{\"params\":{\"_gasLimit\":\"Gas limit for the provided message.\",\"_message\":\"Message to send to the target.\",\"_messageNonce\":\"Nonce for the provided message.\",\"_sender\":\"Original sender address.\",\"_target\":\"Target contract address.\"}},\"sendMessage(address,bytes,uint32)\":{\"params\":{\"_gasLimit\":\"Gas limit for the provided message.\",\"_message\":\"Message to send to the target.\",\"_target\":\"Target contract address.\"}}},\"title\":\"OVM_L1CrossDomainMessenger\",\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"constructor\":{\"notice\":\"Pass a default zero address to the address resolver. This will be updated when initialized.\"},\"relayMessage(address,address,bytes,uint256,(bytes32,(uint256,bytes32,uint256,uint256,bytes),(uint256,bytes32[]),bytes,bytes))\":{\"notice\":\"Relays a cross domain message to a contract.\"},\"replayMessage(address,address,bytes,uint256,uint32)\":{\"notice\":\"Replays a cross domain message to the target messenger.\"},\"sendMessage(address,bytes,uint32)\":{\"notice\":\"Sends a cross domain message to the target messenger.\"}},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/optimistic-ethereum/OVM/bridge/OVM_L1CrossDomainMessenger.sol\":\"OVM_L1CrossDomainMessenger\"},\"evmVersion\":\"istanbul\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"contracts/optimistic-ethereum/OVM/bridge/OVM_BaseCrossDomainMessenger.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// +build ovm\\npragma solidity >0.5.0 <0.8.0;\\npragma experimental ABIEncoderV2;\\n\\n/* Interface Imports */\\nimport { iOVM_BaseCrossDomainMessenger } from \\\"../../iOVM/bridge/iOVM_BaseCrossDomainMessenger.sol\\\";\\n\\n/* Library Imports */\\nimport { Lib_ReentrancyGuard } from \\\"../../libraries/utils/Lib_ReentrancyGuard.sol\\\";\\n\\n/**\\n * @title OVM_BaseCrossDomainMessenger\\n */\\nabstract contract OVM_BaseCrossDomainMessenger is iOVM_BaseCrossDomainMessenger, Lib_ReentrancyGuard {\\n\\n    /**********************\\n     * Contract Variables *\\n     **********************/\\n\\n    mapping (bytes32 => bool) public relayedMessages;\\n    mapping (bytes32 => bool) public successfulMessages;\\n    mapping (bytes32 => bool) public sentMessages;\\n    uint256 public messageNonce;\\n    address override public xDomainMessageSender;\\n\\n    /********************\\n     * Public Functions *\\n     ********************/\\n\\n    constructor() Lib_ReentrancyGuard() internal {}\\n\\n    /**\\n     * Sends a cross domain message to the target messenger.\\n     * @param _target Target contract address.\\n     * @param _message Message to send to the target.\\n     * @param _gasLimit Gas limit for the provided message.\\n     */\\n    function sendMessage(\\n        address _target,\\n        bytes memory _message,\\n        uint32 _gasLimit\\n    )\\n        override\\n        public\\n    {\\n        bytes memory xDomainCalldata = _getXDomainCalldata(\\n            _target,\\n            msg.sender,\\n            _message,\\n            messageNonce\\n        );\\n\\n        messageNonce += 1;\\n        sentMessages[keccak256(xDomainCalldata)] = true;\\n\\n        _sendXDomainMessage(xDomainCalldata, _gasLimit);\\n        emit SentMessage(xDomainCalldata);\\n    }\\n\\n    /**********************\\n     * Internal Functions *\\n     **********************/\\n\\n    /**\\n     * Generates the correct cross domain calldata for a message.\\n     * @param _target Target contract address.\\n     * @param _sender Message sender address.\\n     * @param _message Message to send to the target.\\n     * @param _messageNonce Nonce for the provided message.\\n     * @return ABI encoded cross domain calldata.\\n     */\\n    function _getXDomainCalldata(\\n        address _target,\\n        address _sender,\\n        bytes memory _message,\\n        uint256 _messageNonce\\n    )\\n        internal\\n        pure\\n        returns (\\n            bytes memory\\n        )\\n    {\\n        return abi.encodeWithSignature(\\n            \\\"relayMessage(address,address,bytes,uint256)\\\",\\n            _target,\\n            _sender,\\n            _message,\\n            _messageNonce\\n        );\\n    }\\n\\n    /**\\n     * Sends a cross domain message.\\n     * @param _message Message to send.\\n     * @param _gasLimit Gas limit for the provided message.\\n     */\\n    function _sendXDomainMessage(\\n        bytes memory _message,\\n        uint256 _gasLimit\\n    )\\n        virtual\\n        internal\\n    {\\n        revert(\\\"Implement me in child contracts!\\\");\\n    }\\n}\\n\",\"keccak256\":\"0x25c5521fb5cd66f91aa927b7c199cd2006ba6a2c3857b17e53e2d0727334ea2c\",\"license\":\"MIT\"},\"contracts/optimistic-ethereum/OVM/bridge/OVM_L1CrossDomainMessenger.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >0.5.0 <0.8.0;\\npragma experimental ABIEncoderV2;\\n\\n/* Library Imports */\\nimport { Lib_OVMCodec } from \\\"../../libraries/codec/Lib_OVMCodec.sol\\\";\\nimport { Lib_AddressResolver } from \\\"../../libraries/resolver/Lib_AddressResolver.sol\\\";\\nimport { Lib_AddressManager } from \\\"../../libraries/resolver/Lib_AddressManager.sol\\\";\\nimport { Lib_SecureMerkleTrie } from \\\"../../libraries/trie/Lib_SecureMerkleTrie.sol\\\";\\nimport { Lib_ReentrancyGuard } from \\\"../../libraries/utils/Lib_ReentrancyGuard.sol\\\";\\n\\n/* Interface Imports */\\nimport { iOVM_L1CrossDomainMessenger } from \\\"../../iOVM/bridge/iOVM_L1CrossDomainMessenger.sol\\\";\\nimport { iOVM_CanonicalTransactionChain } from \\\"../../iOVM/chain/iOVM_CanonicalTransactionChain.sol\\\";\\nimport { iOVM_StateCommitmentChain } from \\\"../../iOVM/chain/iOVM_StateCommitmentChain.sol\\\";\\n\\n/* Contract Imports */\\nimport { OVM_BaseCrossDomainMessenger } from \\\"./OVM_BaseCrossDomainMessenger.sol\\\";\\n\\n/**\\n * @title OVM_L1CrossDomainMessenger\\n * @dev This contract lives on L1. It sends L1->L2 messages into L2, and relays L2->L1 messages from L2 to their target on L1.\\n */\\ncontract OVM_L1CrossDomainMessenger is iOVM_L1CrossDomainMessenger, OVM_BaseCrossDomainMessenger, Lib_AddressResolver {\\n\\n    /***************\\n     * Constructor *\\n     ***************/\\n\\n    /**\\n     * Pass a default zero address to the address resolver. This will be updated when initialized.\\n     */\\n    constructor()\\n        Lib_AddressResolver(address(0))\\n    {}\\n\\n    /**\\n     * @param _libAddressManager Address of the Address Manager.\\n     */\\n    function initialize(\\n        address _libAddressManager\\n    )\\n        public\\n    {\\n        require(address(libAddressManager) == address(0), \\\"L1CrossDomainMessenger already intialized.\\\");\\n        libAddressManager = Lib_AddressManager(_libAddressManager);\\n    }\\n\\n\\n    /**********************\\n     * Function Modifiers *\\n     **********************/\\n\\n    /**\\n     * Modifier to enforce that, if configured, only the OVM_L2MessageRelayer contract may successfully call a method.\\n     */\\n    modifier onlyRelayer() {\\n        address relayer = resolve(\\\"OVM_L2MessageRelayer\\\");\\n        if (relayer != address(0)) {\\n            require(\\n                msg.sender == relayer,\\n                \\\"Only OVM_L2MessageRelayer can relay L2-to-L1 messages.\\\"\\n            );\\n        }\\n        _;\\n    }\\n\\n\\n    /********************\\n     * Public Functions *\\n     ********************/\\n\\n    /**\\n     * Relays a cross domain message to a contract.\\n     * @inheritdoc iOVM_L1CrossDomainMessenger\\n     */\\n    function relayMessage(\\n        address _target,\\n        address _sender,\\n        bytes memory _message,\\n        uint256 _messageNonce,\\n        L2MessageInclusionProof memory _proof\\n    )\\n        override\\n        public\\n        nonReentrant\\n        onlyRelayer()\\n    {\\n        bytes memory xDomainCalldata = _getXDomainCalldata(\\n            _target,\\n            _sender,\\n            _message,\\n            _messageNonce\\n        );\\n\\n        require(\\n            _verifyXDomainMessage(\\n                xDomainCalldata,\\n                _proof\\n            ) == true,\\n            \\\"Provided message could not be verified.\\\"\\n        );\\n\\n        bytes32 xDomainCalldataHash = keccak256(xDomainCalldata);\\n\\n        require(\\n            successfulMessages[xDomainCalldataHash] == false,\\n            \\\"Provided message has already been received.\\\"\\n        );\\n\\n        xDomainMessageSender = _sender;\\n        (bool success, ) = _target.call(_message);\\n\\n        // Mark the message as received if the call was successful. Ensures that a message can be\\n        // relayed multiple times in the case that the call reverted.\\n        if (success == true) {\\n            successfulMessages[xDomainCalldataHash] = true;\\n            emit RelayedMessage(xDomainCalldataHash);\\n        }\\n\\n        // Store an identifier that can be used to prove that the given message was relayed by some\\n        // user. Gives us an easy way to pay relayers for their work.\\n        bytes32 relayId = keccak256(\\n            abi.encodePacked(\\n                xDomainCalldata,\\n                msg.sender,\\n                block.number\\n            )\\n        );\\n        relayedMessages[relayId] = true;\\n    }\\n\\n    /**\\n     * Replays a cross domain message to the target messenger.\\n     * @inheritdoc iOVM_L1CrossDomainMessenger\\n     */\\n    function replayMessage(\\n        address _target,\\n        address _sender,\\n        bytes memory _message,\\n        uint256 _messageNonce,\\n        uint32 _gasLimit\\n    )\\n        override\\n        public\\n    {\\n        bytes memory xDomainCalldata = _getXDomainCalldata(\\n            _target,\\n            _sender,\\n            _message,\\n            _messageNonce\\n        );\\n\\n        require(\\n            sentMessages[keccak256(xDomainCalldata)] == true,\\n            \\\"Provided message has not already been sent.\\\"\\n        );\\n\\n        _sendXDomainMessage(xDomainCalldata, _gasLimit);\\n    }\\n\\n\\n    /**********************\\n     * Internal Functions *\\n     **********************/\\n\\n    /**\\n     * Verifies that the given message is valid.\\n     * @param _xDomainCalldata Calldata to verify.\\n     * @param _proof Inclusion proof for the message.\\n     * @return Whether or not the provided message is valid.\\n     */\\n    function _verifyXDomainMessage(\\n        bytes memory _xDomainCalldata,\\n        L2MessageInclusionProof memory _proof\\n    )\\n        internal\\n        view\\n        returns (\\n            bool\\n        )\\n    {\\n        return (\\n            _verifyStateRootProof(_proof)\\n            && _verifyStorageProof(_xDomainCalldata, _proof)\\n        );\\n    }\\n\\n    /**\\n     * Verifies that the state root within an inclusion proof is valid.\\n     * @param _proof Message inclusion proof.\\n     * @return Whether or not the provided proof is valid.\\n     */\\n    function _verifyStateRootProof(\\n        L2MessageInclusionProof memory _proof\\n    )\\n        internal\\n        view\\n        returns (\\n            bool\\n        )\\n    {\\n        iOVM_StateCommitmentChain ovmStateCommitmentChain = iOVM_StateCommitmentChain(resolve(\\\"OVM_StateCommitmentChain\\\"));\\n\\n        return (\\n            ovmStateCommitmentChain.insideFraudProofWindow(_proof.stateRootBatchHeader) == false\\n            && ovmStateCommitmentChain.verifyStateCommitment(\\n                _proof.stateRoot,\\n                _proof.stateRootBatchHeader,\\n                _proof.stateRootProof\\n            )\\n        );\\n    }\\n\\n    /**\\n     * Verifies that the storage proof within an inclusion proof is valid.\\n     * @param _xDomainCalldata Encoded message calldata.\\n     * @param _proof Message inclusion proof.\\n     * @return Whether or not the provided proof is valid.\\n     */\\n    function _verifyStorageProof(\\n        bytes memory _xDomainCalldata,\\n        L2MessageInclusionProof memory _proof\\n    )\\n        internal\\n        view\\n        returns (\\n            bool\\n        )\\n    {\\n        bytes32 storageKey = keccak256(\\n            abi.encodePacked(\\n                keccak256(\\n                    abi.encodePacked(\\n                        _xDomainCalldata,\\n                        resolve(\\\"OVM_L2CrossDomainMessenger\\\")\\n                    )\\n                ),\\n                uint256(0)\\n            )\\n        );\\n\\n        (\\n            bool exists,\\n            bytes memory encodedMessagePassingAccount\\n        ) = Lib_SecureMerkleTrie.get(\\n            abi.encodePacked(0x4200000000000000000000000000000000000000),\\n            _proof.stateTrieWitness,\\n            _proof.stateRoot\\n        );\\n\\n        require(\\n            exists == true,\\n            \\\"Message passing precompile has not been initialized or invalid proof provided.\\\"\\n        );\\n\\n        Lib_OVMCodec.EVMAccount memory account = Lib_OVMCodec.decodeEVMAccount(\\n            encodedMessagePassingAccount\\n        );\\n\\n        return Lib_SecureMerkleTrie.verifyInclusionProof(\\n            abi.encodePacked(storageKey),\\n            abi.encodePacked(uint8(1)),\\n            _proof.storageTrieWitness,\\n            account.storageRoot\\n        );\\n    }\\n\\n    /**\\n     * Sends a cross domain message.\\n     * @param _message Message to send.\\n     * @param _gasLimit OVM gas limit for the message.\\n     */\\n    function _sendXDomainMessage(\\n        bytes memory _message,\\n        uint256 _gasLimit\\n    )\\n        override\\n        internal\\n    {\\n        iOVM_CanonicalTransactionChain(resolve(\\\"OVM_CanonicalTransactionChain\\\")).enqueue(\\n            resolve(\\\"OVM_L2CrossDomainMessenger\\\"),\\n            _gasLimit,\\n            _message\\n        );\\n    }\\n}\\n\",\"keccak256\":\"0x62ead80db43d27db3da44f44b9edc1ecfd041134f8422036ddfb499fc324cfe4\",\"license\":\"MIT\"},\"contracts/optimistic-ethereum/iOVM/bridge/iOVM_BaseCrossDomainMessenger.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// +build ovm\\npragma solidity >0.5.0 <0.8.0;\\npragma experimental ABIEncoderV2;\\n\\n/**\\n * @title iOVM_BaseCrossDomainMessenger\\n */\\ninterface iOVM_BaseCrossDomainMessenger {\\n\\n    /**********\\n     * Events *\\n     **********/\\n    event SentMessage(bytes message);\\n    event RelayedMessage(bytes32 msgHash);\\n\\n    /**********************\\n     * Contract Variables *\\n     **********************/\\n    function xDomainMessageSender() external view returns (address);\\n\\n    /********************\\n     * Public Functions *\\n     ********************/\\n\\n    /**\\n     * Sends a cross domain message to the target messenger.\\n     * @param _target Target contract address.\\n     * @param _message Message to send to the target.\\n     * @param _gasLimit Gas limit for the provided message.\\n     */\\n    function sendMessage(\\n        address _target,\\n        bytes calldata _message,\\n        uint32 _gasLimit\\n    ) external;\\n}\\n\",\"keccak256\":\"0x5da9f0957057d97fb45e514c6d247724e645d8f05c1c2b958cb360ecd9dbce50\",\"license\":\"MIT\"},\"contracts/optimistic-ethereum/iOVM/bridge/iOVM_L1CrossDomainMessenger.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >0.5.0 <0.8.0;\\npragma experimental ABIEncoderV2;\\n\\n/* Library Imports */\\nimport { Lib_OVMCodec } from \\\"../../libraries/codec/Lib_OVMCodec.sol\\\";\\n\\n/* Interface Imports */\\nimport { iOVM_BaseCrossDomainMessenger } from \\\"./iOVM_BaseCrossDomainMessenger.sol\\\";\\n\\n/**\\n * @title iOVM_L1CrossDomainMessenger\\n */\\ninterface iOVM_L1CrossDomainMessenger is iOVM_BaseCrossDomainMessenger {\\n\\n    /*******************\\n     * Data Structures *\\n     *******************/\\n\\n    struct L2MessageInclusionProof {\\n        bytes32 stateRoot;\\n        Lib_OVMCodec.ChainBatchHeader stateRootBatchHeader;\\n        Lib_OVMCodec.ChainInclusionProof stateRootProof;\\n        bytes stateTrieWitness;\\n        bytes storageTrieWitness;\\n    }\\n\\n\\n    /********************\\n     * Public Functions *\\n     ********************/\\n\\n    /**\\n     * Relays a cross domain message to a contract.\\n     * @param _target Target contract address.\\n     * @param _sender Message sender address.\\n     * @param _message Message to send to the target.\\n     * @param _messageNonce Nonce for the provided message.\\n     * @param _proof Inclusion proof for the given message.\\n     */\\n    function relayMessage(\\n        address _target,\\n        address _sender,\\n        bytes memory _message,\\n        uint256 _messageNonce,\\n        L2MessageInclusionProof memory _proof\\n    ) external;\\n\\n    /**\\n     * Replays a cross domain message to the target messenger.\\n     * @param _target Target contract address.\\n     * @param _sender Original sender address.\\n     * @param _message Message to send to the target.\\n     * @param _messageNonce Nonce for the provided message.\\n     * @param _gasLimit Gas limit for the provided message.\\n     */\\n    function replayMessage(\\n        address _target,\\n        address _sender,\\n        bytes memory _message,\\n        uint256 _messageNonce,\\n        uint32 _gasLimit\\n    ) external;\\n}\\n\",\"keccak256\":\"0x51fb52c2a5ed1d3491a68431eb034aebe17f261c6dce7c7b4631a4f01b0b8bb8\",\"license\":\"MIT\"},\"contracts/optimistic-ethereum/iOVM/chain/iOVM_CanonicalTransactionChain.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >0.5.0 <0.8.0;\\npragma experimental ABIEncoderV2;\\n\\n/* Library Imports */\\nimport { Lib_OVMCodec } from \\\"../../libraries/codec/Lib_OVMCodec.sol\\\";\\n\\n/**\\n * @title iOVM_CanonicalTransactionChain\\n */\\ninterface iOVM_CanonicalTransactionChain {\\n\\n    /**********\\n     * Events *\\n     **********/\\n\\n    event TransactionEnqueued(\\n        address _l1TxOrigin,\\n        address _target,\\n        uint256 _gasLimit,\\n        bytes _data,\\n        uint256 _queueIndex,\\n        uint256 _timestamp\\n    );\\n\\n    event QueueBatchAppended(\\n        uint256 _startingQueueIndex,\\n        uint256 _numQueueElements,\\n        uint256 _totalElements\\n    );\\n\\n    event SequencerBatchAppended(\\n        uint256 _startingQueueIndex,\\n        uint256 _numQueueElements,\\n        uint256 _totalElements\\n    );\\n\\n    event TransactionBatchAppended(\\n        uint256 indexed _batchIndex,\\n        bytes32 _batchRoot,\\n        uint256 _batchSize,\\n        uint256 _prevTotalElements,\\n        bytes _extraData\\n    );\\n\\n\\n    /***********\\n     * Structs *\\n     ***********/\\n\\n    struct BatchContext {\\n        uint256 numSequencedTransactions;\\n        uint256 numSubsequentQueueTransactions;\\n        uint256 timestamp;\\n        uint256 blockNumber;\\n    }\\n\\n\\n    /********************\\n     * Public Functions *\\n     ********************/\\n\\n    /**\\n     * Retrieves the total number of elements submitted.\\n     * @return _totalElements Total submitted elements.\\n     */\\n    function getTotalElements()\\n        external\\n        view\\n        returns (\\n            uint256 _totalElements\\n        );\\n\\n    /**\\n     * Retrieves the total number of batches submitted.\\n     * @return _totalBatches Total submitted batches.\\n     */\\n    function getTotalBatches()\\n        external\\n        view\\n        returns (\\n            uint256 _totalBatches\\n        );\\n\\n    /**\\n     * Returns the index of the next element to be enqueued.\\n     * @return Index for the next queue element.\\n     */\\n    function getNextQueueIndex()\\n        external\\n        view\\n        returns (\\n            uint40\\n        );\\n\\n    /**\\n     * Get the number of queue elements which have not yet been included.\\n     * @return Length of the queue.\\n     */\\n    function getNumPendingQueueElements()\\n        external\\n        view\\n        returns (\\n            uint40\\n        );\\n\\n    /**\\n     * Retrieves the length of the queue, including\\n     * both pending and canonical transactions.\\n     * @return Length of the queue.\\n     */\\n    function getQueueLength()\\n        external\\n        view\\n        returns (\\n            uint40\\n        );\\n\\n    /**\\n     * Gets the queue element at a particular index.\\n     * @param _index Index of the queue element to access.\\n     * @return _element Queue element at the given index.\\n     */\\n    function getQueueElement(\\n        uint256 _index\\n    )\\n        external\\n        view\\n        returns (\\n            Lib_OVMCodec.QueueElement memory _element\\n        );\\n\\n    /**\\n     * Adds a transaction to the queue.\\n     * @param _target Target contract to send the transaction to.\\n     * @param _gasLimit Gas limit for the given transaction.\\n     * @param _data Transaction data.\\n     */\\n    function enqueue(\\n        address _target,\\n        uint256 _gasLimit,\\n        bytes memory _data\\n    )\\n        external;\\n\\n    /**\\n     * Appends a given number of queued transactions as a single batch.\\n     * @param _numQueuedTransactions Number of transactions to append.\\n     */\\n    function appendQueueBatch(\\n        uint256 _numQueuedTransactions\\n    )\\n        external;\\n\\n    /**\\n     * Allows the sequencer to append a batch of transactions.\\n     * @dev This function uses a custom encoding scheme for efficiency reasons.\\n     * .param _shouldStartAtElement Specific batch we expect to start appending to.\\n     * .param _totalElementsToAppend Total number of batch elements we expect to append.\\n     * .param _contexts Array of batch contexts.\\n     * .param _transactionDataFields Array of raw transaction data.\\n     */\\n    function appendSequencerBatch(\\n        // uint40 _shouldStartAtElement,\\n        // uint24 _totalElementsToAppend,\\n        // BatchContext[] _contexts,\\n        // bytes[] _transactionDataFields\\n    )\\n        external;\\n\\n    /**\\n     * Verifies whether a transaction is included in the chain.\\n     * @param _transaction Transaction to verify.\\n     * @param _txChainElement Transaction chain element corresponding to the transaction.\\n     * @param _batchHeader Header of the batch the transaction was included in.\\n     * @param _inclusionProof Inclusion proof for the provided transaction chain element.\\n     * @return True if the transaction exists in the CTC, false if not.\\n     */\\n    function verifyTransaction(\\n        Lib_OVMCodec.Transaction memory _transaction,\\n        Lib_OVMCodec.TransactionChainElement memory _txChainElement,\\n        Lib_OVMCodec.ChainBatchHeader memory _batchHeader,\\n        Lib_OVMCodec.ChainInclusionProof memory _inclusionProof\\n    )\\n        external\\n        view\\n        returns (\\n            bool\\n        );\\n}\\n\",\"keccak256\":\"0x82a4e62286c8bc5e2d3de33f66d9b707cb9636e553dca54b5e95277bd794a934\",\"license\":\"MIT\"},\"contracts/optimistic-ethereum/iOVM/chain/iOVM_StateCommitmentChain.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >0.5.0 <0.8.0;\\npragma experimental ABIEncoderV2;\\n\\n/* Library Imports */\\nimport { Lib_OVMCodec } from \\\"../../libraries/codec/Lib_OVMCodec.sol\\\";\\n\\n/**\\n * @title iOVM_StateCommitmentChain\\n */\\ninterface iOVM_StateCommitmentChain {\\n\\n    /**********\\n     * Events *\\n     **********/\\n\\n    event StateBatchAppended(\\n        uint256 indexed _batchIndex,\\n        bytes32 _batchRoot,\\n        uint256 _batchSize,\\n        uint256 _prevTotalElements,\\n        bytes _extraData\\n    );\\n\\n    event StateBatchDeleted(\\n        uint256 indexed _batchIndex,\\n        bytes32 _batchRoot\\n    );\\n\\n\\n    /********************\\n     * Public Functions *\\n     ********************/\\n\\n    /**\\n     * Retrieves the total number of elements submitted.\\n     * @return _totalElements Total submitted elements.\\n     */\\n    function getTotalElements()\\n        external\\n        view\\n        returns (\\n            uint256 _totalElements\\n        );\\n\\n    /**\\n     * Retrieves the total number of batches submitted.\\n     * @return _totalBatches Total submitted batches.\\n     */\\n    function getTotalBatches()\\n        external\\n        view\\n        returns (\\n            uint256 _totalBatches\\n        );\\n\\n    /**\\n     * Retrieves the timestamp of the last batch submitted by the sequencer.\\n     * @return _lastSequencerTimestamp Last sequencer batch timestamp.\\n     */\\n    function getLastSequencerTimestamp()\\n        external\\n        view\\n        returns (\\n            uint256 _lastSequencerTimestamp\\n        );\\n\\n    /**\\n     * Appends a batch of state roots to the chain.\\n     * @param _batch Batch of state roots.\\n     * @param _shouldStartAtElement Index of the element at which this batch should start.\\n     */\\n    function appendStateBatch(\\n        bytes32[] calldata _batch,\\n        uint256 _shouldStartAtElement\\n    )\\n        external;\\n\\n    /**\\n     * Deletes all state roots after (and including) a given batch.\\n     * @param _batchHeader Header of the batch to start deleting from.\\n     */\\n    function deleteStateBatch(\\n        Lib_OVMCodec.ChainBatchHeader memory _batchHeader\\n    )\\n        external;\\n\\n    /**\\n     * Verifies a batch inclusion proof.\\n     * @param _element Hash of the element to verify a proof for.\\n     * @param _batchHeader Header of the batch in which the element was included.\\n     * @param _proof Merkle inclusion proof for the element.\\n     */\\n    function verifyStateCommitment(\\n        bytes32 _element,\\n        Lib_OVMCodec.ChainBatchHeader memory _batchHeader,\\n        Lib_OVMCodec.ChainInclusionProof memory _proof\\n    )\\n        external\\n        view\\n        returns (\\n            bool _verified\\n        );\\n\\n    /**\\n     * Checks whether a given batch is still inside its fraud proof window.\\n     * @param _batchHeader Header of the batch to check.\\n     * @return _inside Whether or not the batch is inside the fraud proof window.\\n     */\\n    function insideFraudProofWindow(\\n        Lib_OVMCodec.ChainBatchHeader memory _batchHeader\\n    )\\n        external\\n        view\\n        returns (\\n            bool _inside\\n        );\\n}\\n\",\"keccak256\":\"0x6646d6ff392b81aab52a7a277e91540819464751de0af5afd1962094b2e92448\",\"license\":\"MIT\"},\"contracts/optimistic-ethereum/libraries/codec/Lib_OVMCodec.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >0.5.0 <0.8.0;\\npragma experimental ABIEncoderV2;\\n\\n/* Library Imports */\\nimport { Lib_RLPReader } from \\\"../rlp/Lib_RLPReader.sol\\\";\\nimport { Lib_RLPWriter } from \\\"../rlp/Lib_RLPWriter.sol\\\";\\nimport { Lib_BytesUtils } from \\\"../utils/Lib_BytesUtils.sol\\\";\\nimport { Lib_Bytes32Utils } from \\\"../utils/Lib_Bytes32Utils.sol\\\";\\nimport { Lib_SafeExecutionManagerWrapper } from \\\"../../libraries/wrappers/Lib_SafeExecutionManagerWrapper.sol\\\";\\n\\n/**\\n * @title Lib_OVMCodec\\n */\\nlibrary Lib_OVMCodec {\\n\\n    /*************\\n     * Constants *\\n     *************/\\n\\n    bytes constant internal RLP_NULL_BYTES = hex'80';\\n    bytes constant internal NULL_BYTES = bytes('');\\n\\n    // Ring buffer IDs\\n    bytes32 constant internal RING_BUFFER_SCC_BATCHES = keccak256(\\\"RING_BUFFER_SCC_BATCHES\\\");\\n    bytes32 constant internal RING_BUFFER_CTC_BATCHES = keccak256(\\\"RING_BUFFER_CTC_BATCHES\\\");\\n    bytes32 constant internal RING_BUFFER_CTC_QUEUE = keccak256(\\\"RING_BUFFER_CTC_QUEUE\\\");\\n\\n\\n    /*********\\n     * Enums *\\n     *********/\\n\\n    enum EOASignatureType {\\n        EIP155_TRANSACTON,\\n        ETH_SIGNED_MESSAGE\\n    }\\n\\n    enum QueueOrigin {\\n        SEQUENCER_QUEUE,\\n        L1TOL2_QUEUE\\n    }\\n\\n\\n    /***********\\n     * Structs *\\n     ***********/\\n\\n    struct Account {\\n        uint256 nonce;\\n        uint256 balance;\\n        bytes32 storageRoot;\\n        bytes32 codeHash;\\n        address ethAddress;\\n        bool isFresh;\\n    }\\n\\n    struct EVMAccount {\\n        uint256 nonce;\\n        uint256 balance;\\n        bytes32 storageRoot;\\n        bytes32 codeHash;\\n    }\\n\\n    struct ChainBatchHeader {\\n        uint256 batchIndex;\\n        bytes32 batchRoot;\\n        uint256 batchSize;\\n        uint256 prevTotalElements;\\n        bytes extraData;\\n    }\\n\\n    struct ChainInclusionProof {\\n        uint256 index;\\n        bytes32[] siblings;\\n    }\\n\\n    struct Transaction {\\n        uint256 timestamp;\\n        uint256 blockNumber;\\n        QueueOrigin l1QueueOrigin;\\n        address l1TxOrigin;\\n        address entrypoint;\\n        uint256 gasLimit;\\n        bytes data;\\n    }\\n\\n    struct TransactionChainElement {\\n        bool isSequenced;\\n        uint256 queueIndex;  // QUEUED TX ONLY\\n        uint256 timestamp;   // SEQUENCER TX ONLY\\n        uint256 blockNumber; // SEQUENCER TX ONLY\\n        bytes txData;        // SEQUENCER TX ONLY\\n    }\\n\\n    struct QueueElement {\\n        bytes32 queueRoot;\\n        uint40 timestamp;\\n        uint40 blockNumber;\\n    }\\n\\n    struct EIP155Transaction {\\n        uint256 nonce;\\n        uint256 gasPrice;\\n        uint256 gasLimit;\\n        address to;\\n        uint256 value;\\n        bytes data;\\n        uint256 chainId;\\n    }\\n\\n\\n    /*********************************************\\n     * Internal Functions: Encoding and Decoding *\\n     *********************************************/\\n\\n    /**\\n     * Decodes an EOA transaction (i.e., native Ethereum RLP encoding).\\n     * @param _transaction Encoded EOA transaction.\\n     * @return _decoded Transaction decoded into a struct.\\n     */\\n    function decodeEIP155Transaction(\\n        bytes memory _transaction,\\n        bool _isEthSignedMessage\\n    )\\n        internal\\n        pure\\n        returns (\\n            EIP155Transaction memory _decoded\\n        )\\n    {\\n        if (_isEthSignedMessage) {\\n            (\\n                uint256 _nonce,\\n                uint256 _gasLimit,\\n                uint256 _gasPrice,\\n                uint256 _chainId,\\n                address _to,\\n                bytes memory _data\\n            ) = abi.decode(\\n                _transaction,\\n                (uint256, uint256, uint256, uint256, address ,bytes)\\n            );\\n            return EIP155Transaction({\\n                nonce: _nonce,\\n                gasPrice: _gasPrice,\\n                gasLimit: _gasLimit,\\n                to: _to,\\n                value: 0,\\n                data: _data,\\n                chainId: _chainId\\n            });\\n        } else {\\n            Lib_RLPReader.RLPItem[] memory decoded = Lib_RLPReader.readList(_transaction);\\n\\n            return EIP155Transaction({\\n                nonce: Lib_RLPReader.readUint256(decoded[0]),\\n                gasPrice: Lib_RLPReader.readUint256(decoded[1]),\\n                gasLimit: Lib_RLPReader.readUint256(decoded[2]),\\n                to: Lib_RLPReader.readAddress(decoded[3]),\\n                value: Lib_RLPReader.readUint256(decoded[4]),\\n                data: Lib_RLPReader.readBytes(decoded[5]),\\n                chainId:  Lib_RLPReader.readUint256(decoded[6])\\n            });\\n        }\\n    }\\n\\n    function decompressEIP155Transaction(\\n        bytes memory _transaction\\n    )\\n        internal\\n        returns (\\n            EIP155Transaction memory _decompressed\\n        )\\n    {\\n        return EIP155Transaction({\\n            gasLimit: Lib_BytesUtils.toUint24(_transaction, 0),\\n            gasPrice: uint256(Lib_BytesUtils.toUint24(_transaction, 3)) * 1000000,\\n            nonce: Lib_BytesUtils.toUint24(_transaction, 6),\\n            to: Lib_BytesUtils.toAddress(_transaction, 9),\\n            data: Lib_BytesUtils.slice(_transaction, 29),\\n            chainId: Lib_SafeExecutionManagerWrapper.safeCHAINID(),\\n            value: 0\\n        });\\n    }\\n\\n    /**\\n     * Encodes an EOA transaction back into the original transaction.\\n     * @param _transaction EIP155transaction to encode.\\n     * @param _isEthSignedMessage Whether or not this was an eth signed message.\\n     * @return Encoded transaction.\\n     */\\n    function encodeEIP155Transaction(\\n        EIP155Transaction memory _transaction,\\n        bool _isEthSignedMessage\\n    )\\n        internal\\n        pure\\n        returns (\\n            bytes memory\\n        )\\n    {\\n        if (_isEthSignedMessage) {\\n            return abi.encode(\\n                _transaction.nonce,\\n                _transaction.gasLimit,\\n                _transaction.gasPrice,\\n                _transaction.chainId,\\n                _transaction.to,\\n                _transaction.data\\n            );\\n        } else {\\n            bytes[] memory raw = new bytes[](9);\\n\\n            raw[0] = Lib_RLPWriter.writeUint(_transaction.nonce);\\n            raw[1] = Lib_RLPWriter.writeUint(_transaction.gasPrice);\\n            raw[2] = Lib_RLPWriter.writeUint(_transaction.gasLimit);\\n            if (_transaction.to == address(0)) {\\n                raw[3] = Lib_RLPWriter.writeBytes('');\\n            } else {\\n                raw[3] = Lib_RLPWriter.writeAddress(_transaction.to);\\n            }\\n            raw[4] = Lib_RLPWriter.writeUint(0);\\n            raw[5] = Lib_RLPWriter.writeBytes(_transaction.data);\\n            raw[6] = Lib_RLPWriter.writeUint(_transaction.chainId);\\n            raw[7] = Lib_RLPWriter.writeBytes(bytes(''));\\n            raw[8] = Lib_RLPWriter.writeBytes(bytes(''));\\n\\n            return Lib_RLPWriter.writeList(raw);\\n        }\\n    }\\n\\n    /**\\n     * Encodes a standard OVM transaction.\\n     * @param _transaction OVM transaction to encode.\\n     * @return _encoded Encoded transaction bytes.\\n     */\\n    function encodeTransaction(\\n        Transaction memory _transaction\\n    )\\n        internal\\n        pure\\n        returns (\\n            bytes memory _encoded\\n        )\\n    {\\n        return abi.encodePacked(\\n            _transaction.timestamp,\\n            _transaction.blockNumber,\\n            _transaction.l1QueueOrigin,\\n            _transaction.l1TxOrigin,\\n            _transaction.entrypoint,\\n            _transaction.gasLimit,\\n            _transaction.data\\n        );\\n    }\\n\\n    /**\\n     * Hashes a standard OVM transaction.\\n     * @param _transaction OVM transaction to encode.\\n     * @return _hash Hashed transaction\\n     */\\n    function hashTransaction(\\n        Transaction memory _transaction\\n    )\\n        internal\\n        pure\\n        returns (\\n            bytes32 _hash\\n        )\\n    {\\n        return keccak256(encodeTransaction(_transaction));\\n    }\\n\\n    /**\\n     * Converts an OVM account to an EVM account.\\n     * @param _in OVM account to convert.\\n     * @return _out Converted EVM account.\\n     */\\n    function toEVMAccount(\\n        Account memory _in\\n    )\\n        internal\\n        pure\\n        returns (\\n            EVMAccount memory _out\\n        )\\n    {\\n        return EVMAccount({\\n            nonce: _in.nonce,\\n            balance: _in.balance,\\n            storageRoot: _in.storageRoot,\\n            codeHash: _in.codeHash\\n        });\\n    }\\n\\n    /**\\n     * @notice RLP-encodes an account state struct.\\n     * @param _account Account state struct.\\n     * @return _encoded RLP-encoded account state.\\n     */\\n    function encodeEVMAccount(\\n        EVMAccount memory _account\\n    )\\n        internal\\n        pure\\n        returns (\\n            bytes memory _encoded\\n        )\\n    {\\n        bytes[] memory raw = new bytes[](4);\\n\\n        // Unfortunately we can't create this array outright because\\n        // Lib_RLPWriter.writeList will reject fixed-size arrays. Assigning\\n        // index-by-index circumvents this issue.\\n        raw[0] = Lib_RLPWriter.writeBytes(\\n            Lib_Bytes32Utils.removeLeadingZeros(\\n                bytes32(_account.nonce)\\n            )\\n        );\\n        raw[1] = Lib_RLPWriter.writeBytes(\\n            Lib_Bytes32Utils.removeLeadingZeros(\\n                bytes32(_account.balance)\\n            )\\n        );\\n        raw[2] = Lib_RLPWriter.writeBytes(abi.encodePacked(_account.storageRoot));\\n        raw[3] = Lib_RLPWriter.writeBytes(abi.encodePacked(_account.codeHash));\\n\\n        return Lib_RLPWriter.writeList(raw);\\n    }\\n\\n    /**\\n     * @notice Decodes an RLP-encoded account state into a useful struct.\\n     * @param _encoded RLP-encoded account state.\\n     * @return _account Account state struct.\\n     */\\n    function decodeEVMAccount(\\n        bytes memory _encoded\\n    )\\n        internal\\n        pure\\n        returns (\\n            EVMAccount memory _account\\n        )\\n    {\\n        Lib_RLPReader.RLPItem[] memory accountState = Lib_RLPReader.readList(_encoded);\\n\\n        return EVMAccount({\\n            nonce: Lib_RLPReader.readUint256(accountState[0]),\\n            balance: Lib_RLPReader.readUint256(accountState[1]),\\n            storageRoot: Lib_RLPReader.readBytes32(accountState[2]),\\n            codeHash: Lib_RLPReader.readBytes32(accountState[3])\\n        });\\n    }\\n\\n    /**\\n     * Calculates a hash for a given batch header.\\n     * @param _batchHeader Header to hash.\\n     * @return _hash Hash of the header.\\n     */\\n    function hashBatchHeader(\\n        Lib_OVMCodec.ChainBatchHeader memory _batchHeader\\n    )\\n        internal\\n        pure\\n        returns (\\n            bytes32 _hash\\n        )\\n    {\\n        return keccak256(\\n            abi.encode(\\n                _batchHeader.batchRoot,\\n                _batchHeader.batchSize,\\n                _batchHeader.prevTotalElements,\\n                _batchHeader.extraData\\n            )\\n        );\\n    }\\n}\\n\",\"keccak256\":\"0x19d78734777b4998f1544e235cf3934f20c5055cd76c2bd60bf0f6dacdd72b3a\",\"license\":\"MIT\"},\"contracts/optimistic-ethereum/libraries/resolver/Lib_AddressManager.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// +build ovm\\npragma solidity >0.5.0 <0.8.0;\\n\\n/* Contract Imports */\\nimport { Ownable } from \\\"./Lib_Ownable.sol\\\";\\n\\n/**\\n * @title Lib_AddressManager\\n */\\ncontract Lib_AddressManager is Ownable {\\n\\n    /**********\\n     * Events *\\n     **********/\\n\\n    event AddressSet(\\n        string _name,\\n        address _newAddress\\n    );\\n\\n    /*******************************************\\n     * Contract Variables: Internal Accounting *\\n     *******************************************/\\n\\n    mapping (bytes32 => address) private addresses;\\n\\n\\n    /********************\\n     * Public Functions *\\n     ********************/\\n\\n    function setAddress(\\n        string memory _name,\\n        address _address\\n    )\\n        public\\n        onlyOwner\\n    {\\n        emit AddressSet(_name, _address);\\n        addresses[_getNameHash(_name)] = _address;\\n    }\\n\\n    function getAddress(\\n        string memory _name\\n    )\\n        public\\n        view\\n        returns (address)\\n    {\\n        return addresses[_getNameHash(_name)];\\n    }\\n\\n\\n    /**********************\\n     * Internal Functions *\\n     **********************/\\n\\n    function _getNameHash(\\n        string memory _name\\n    )\\n        internal\\n        pure\\n        returns (\\n            bytes32 _hash\\n        )\\n    {\\n        return keccak256(abi.encodePacked(_name));\\n    }\\n}\\n\",\"keccak256\":\"0xdf802e1cc6474df913626991e9fca3835c620a519f397afe04bf9c260e723257\",\"license\":\"MIT\"},\"contracts/optimistic-ethereum/libraries/resolver/Lib_AddressResolver.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// +build ovm\\npragma solidity >0.5.0 <0.8.0;\\n\\n/* Library Imports */\\nimport { Lib_AddressManager } from \\\"./Lib_AddressManager.sol\\\";\\n\\n/**\\n * @title Lib_AddressResolver\\n */\\ncontract Lib_AddressResolver {\\n\\n    /*******************************************\\n     * Contract Variables: Contract References *\\n     *******************************************/\\n\\n    Lib_AddressManager internal libAddressManager;\\n\\n\\n    /***************\\n     * Constructor *\\n     ***************/\\n\\n    /**\\n     * @param _libAddressManager Address of the Lib_AddressManager.\\n     */\\n    constructor(\\n        address _libAddressManager\\n    ) public {\\n        libAddressManager = Lib_AddressManager(_libAddressManager);\\n    }\\n\\n\\n    /********************\\n     * Public Functions *\\n     ********************/\\n\\n    function resolve(\\n        string memory _name\\n    )\\n        public\\n        view\\n        returns (\\n            address _contract\\n        )\\n    {\\n        return libAddressManager.getAddress(_name);\\n    }\\n}\\n\",\"keccak256\":\"0xf3b9d78b309ddeec259ce3e0e1cfdef3ca40938e9a81971b28ce2b8ea327f533\",\"license\":\"MIT\"},\"contracts/optimistic-ethereum/libraries/resolver/Lib_Ownable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// +build ovm\\npragma solidity >0.5.0 <0.8.0;\\n\\n/**\\n * @title Ownable\\n * @dev Adapted from https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/access/Ownable.sol\\n */\\nabstract contract Ownable {\\n\\n    /*************\\n     * Variables *\\n     *************/\\n\\n    address public owner;\\n\\n\\n    /**********\\n     * Events *\\n     **********/\\n\\n    event OwnershipTransferred(\\n        address indexed previousOwner,\\n        address indexed newOwner\\n    );\\n\\n\\n    /***************\\n     * Constructor *\\n     ***************/\\n\\n    constructor() internal {\\n        owner = msg.sender;\\n        emit OwnershipTransferred(address(0), owner);\\n    }\\n\\n\\n    /**********************\\n     * Function Modifiers *\\n     **********************/\\n\\n    modifier onlyOwner() {\\n        require(\\n            owner == msg.sender,\\n            \\\"Ownable: caller is not the owner\\\"\\n        );\\n        _;\\n    }\\n\\n\\n    /********************\\n     * Public Functions *\\n     ********************/\\n\\n    function renounceOwnership()\\n        public\\n        virtual\\n        onlyOwner\\n    {\\n        emit OwnershipTransferred(owner, address(0));\\n        owner = address(0);\\n    }\\n\\n    function transferOwnership(address _newOwner)\\n        public\\n        virtual\\n        onlyOwner\\n    {\\n        require(\\n            _newOwner != address(0),\\n            \\\"Ownable: new owner cannot be the zero address\\\"\\n        );\\n\\n        emit OwnershipTransferred(owner, _newOwner);\\n        owner = _newOwner;\\n    }\\n}\\n\",\"keccak256\":\"0xe0409fbd236d16ca6be439d9d97dd36d0d9a0697ee0062d49588b9d29c248e47\",\"license\":\"MIT\"},\"contracts/optimistic-ethereum/libraries/rlp/Lib_RLPReader.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.7.0;\\n\\n/**\\n * @title Lib_RLPReader\\n * @dev Adapted from \\\"RLPReader\\\" by Hamdi Allam (hamdi.allam97@gmail.com).\\n */\\nlibrary Lib_RLPReader {\\n\\n    /*************\\n     * Constants *\\n     *************/\\n\\n    uint256 constant internal MAX_LIST_LENGTH = 32;\\n\\n\\n    /*********\\n     * Enums *\\n     *********/\\n\\n    enum RLPItemType {\\n        DATA_ITEM,\\n        LIST_ITEM\\n    }\\n\\n    \\n    /***********\\n     * Structs *\\n     ***********/\\n\\n    struct RLPItem {\\n        uint256 length;\\n        uint256 ptr;\\n    }\\n    \\n\\n    /**********************\\n     * Internal Functions *\\n     **********************/\\n    \\n    /**\\n     * Converts bytes to a reference to memory position and length.\\n     * @param _in Input bytes to convert.\\n     * @return Output memory reference.\\n     */\\n    function toRLPItem(\\n        bytes memory _in\\n    )\\n        internal\\n        pure\\n        returns (\\n            RLPItem memory\\n        )\\n    {\\n        uint256 ptr;\\n        assembly {\\n            ptr := add(_in, 32)\\n        }\\n\\n        return RLPItem({\\n            length: _in.length,\\n            ptr: ptr\\n        });\\n    }\\n\\n    /**\\n     * Reads an RLP list value into a list of RLP items.\\n     * @param _in RLP list value.\\n     * @return Decoded RLP list items.\\n     */\\n    function readList(\\n        RLPItem memory _in\\n    )\\n        internal\\n        pure\\n        returns (\\n            RLPItem[] memory\\n        )\\n    {\\n        (\\n            uint256 listOffset,\\n            ,\\n            RLPItemType itemType\\n        ) = _decodeLength(_in);\\n\\n        require(\\n            itemType == RLPItemType.LIST_ITEM,\\n            \\\"Invalid RLP list value.\\\"\\n        );\\n\\n        // Solidity in-memory arrays can't be increased in size, but *can* be decreased in size by\\n        // writing to the length. Since we can't know the number of RLP items without looping over\\n        // the entire input, we'd have to loop twice to accurately size this array. It's easier to\\n        // simply set a reasonable maximum list length and decrease the size before we finish.\\n        RLPItem[] memory out = new RLPItem[](MAX_LIST_LENGTH);\\n\\n        uint256 itemCount = 0;\\n        uint256 offset = listOffset;\\n        while (offset < _in.length) {\\n            require(\\n                itemCount < MAX_LIST_LENGTH,\\n                \\\"Provided RLP list exceeds max list length.\\\"\\n            );\\n\\n            (\\n                uint256 itemOffset,\\n                uint256 itemLength,\\n            ) = _decodeLength(RLPItem({\\n                length: _in.length - offset,\\n                ptr: _in.ptr + offset\\n            }));\\n\\n            out[itemCount] = RLPItem({\\n                length: itemLength + itemOffset,\\n                ptr: _in.ptr + offset\\n            });\\n\\n            itemCount += 1;\\n            offset += itemOffset + itemLength;\\n        }\\n\\n        // Decrease the array size to match the actual item count.\\n        assembly {\\n            mstore(out, itemCount)\\n        }\\n\\n        return out;\\n    }\\n\\n    /**\\n     * Reads an RLP list value into a list of RLP items.\\n     * @param _in RLP list value.\\n     * @return Decoded RLP list items.\\n     */\\n    function readList(\\n        bytes memory _in\\n    )\\n        internal\\n        pure\\n        returns (\\n            RLPItem[] memory\\n        )\\n    {\\n        return readList(\\n            toRLPItem(_in)\\n        );\\n    }\\n\\n    /**\\n     * Reads an RLP bytes value into bytes.\\n     * @param _in RLP bytes value.\\n     * @return Decoded bytes.\\n     */\\n    function readBytes(\\n        RLPItem memory _in\\n    )\\n        internal\\n        pure\\n        returns (\\n            bytes memory\\n        )\\n    {\\n        (\\n            uint256 itemOffset,\\n            uint256 itemLength,\\n            RLPItemType itemType\\n        ) = _decodeLength(_in);\\n\\n        require(\\n            itemType == RLPItemType.DATA_ITEM,\\n            \\\"Invalid RLP bytes value.\\\"\\n        );\\n\\n        return _copy(_in.ptr, itemOffset, itemLength);\\n    }\\n\\n    /**\\n     * Reads an RLP bytes value into bytes.\\n     * @param _in RLP bytes value.\\n     * @return Decoded bytes.\\n     */\\n    function readBytes(\\n        bytes memory _in\\n    )\\n        internal\\n        pure\\n        returns (\\n            bytes memory\\n        )\\n    {\\n        return readBytes(\\n            toRLPItem(_in)\\n        );\\n    }\\n\\n    /**\\n     * Reads an RLP string value into a string.\\n     * @param _in RLP string value.\\n     * @return Decoded string.\\n     */\\n    function readString(\\n        RLPItem memory _in\\n    )\\n        internal\\n        pure\\n        returns (\\n            string memory\\n        )\\n    {\\n        return string(readBytes(_in));\\n    }\\n\\n    /**\\n     * Reads an RLP string value into a string.\\n     * @param _in RLP string value.\\n     * @return Decoded string.\\n     */\\n    function readString(\\n        bytes memory _in\\n    )\\n        internal\\n        pure\\n        returns (\\n            string memory\\n        )\\n    {\\n        return readString(\\n            toRLPItem(_in)\\n        );\\n    }\\n\\n    /**\\n     * Reads an RLP bytes32 value into a bytes32.\\n     * @param _in RLP bytes32 value.\\n     * @return Decoded bytes32.\\n     */\\n    function readBytes32(\\n        RLPItem memory _in\\n    )\\n        internal\\n        pure\\n        returns (\\n            bytes32\\n        )\\n    {\\n        require(\\n            _in.length <= 33,\\n            \\\"Invalid RLP bytes32 value.\\\"\\n        );\\n\\n        (\\n            uint256 itemOffset,\\n            uint256 itemLength,\\n            RLPItemType itemType\\n        ) = _decodeLength(_in);\\n\\n        require(\\n            itemType == RLPItemType.DATA_ITEM,\\n            \\\"Invalid RLP bytes32 value.\\\"\\n        );\\n\\n        uint256 ptr = _in.ptr + itemOffset;\\n        bytes32 out;\\n        assembly {\\n            out := mload(ptr)\\n\\n            // Shift the bytes over to match the item size.\\n            if lt(itemLength, 32) {\\n                out := div(out, exp(256, sub(32, itemLength)))\\n            }\\n        }\\n\\n        return out;\\n    }\\n\\n    /**\\n     * Reads an RLP bytes32 value into a bytes32.\\n     * @param _in RLP bytes32 value.\\n     * @return Decoded bytes32.\\n     */\\n    function readBytes32(\\n        bytes memory _in\\n    )\\n        internal\\n        pure\\n        returns (\\n            bytes32\\n        )\\n    {\\n        return readBytes32(\\n            toRLPItem(_in)\\n        );\\n    }\\n\\n    /**\\n     * Reads an RLP uint256 value into a uint256.\\n     * @param _in RLP uint256 value.\\n     * @return Decoded uint256.\\n     */\\n    function readUint256(\\n        RLPItem memory _in\\n    )\\n        internal\\n        pure\\n        returns (\\n            uint256\\n        )\\n    {\\n        return uint256(readBytes32(_in));\\n    }\\n\\n    /**\\n     * Reads an RLP uint256 value into a uint256.\\n     * @param _in RLP uint256 value.\\n     * @return Decoded uint256.\\n     */\\n    function readUint256(\\n        bytes memory _in\\n    )\\n        internal\\n        pure\\n        returns (\\n            uint256\\n        )\\n    {\\n        return readUint256(\\n            toRLPItem(_in)\\n        );\\n    }\\n\\n    /**\\n     * Reads an RLP bool value into a bool.\\n     * @param _in RLP bool value.\\n     * @return Decoded bool.\\n     */\\n    function readBool(\\n        RLPItem memory _in\\n    )\\n        internal\\n        pure\\n        returns (\\n            bool\\n        )\\n    {\\n        require(\\n            _in.length == 1,\\n            \\\"Invalid RLP boolean value.\\\"\\n        );\\n\\n        uint256 ptr = _in.ptr;\\n        uint256 out;\\n        assembly {\\n            out := byte(0, mload(ptr))\\n        }\\n\\n        return out != 0;\\n    }\\n\\n    /**\\n     * Reads an RLP bool value into a bool.\\n     * @param _in RLP bool value.\\n     * @return Decoded bool.\\n     */\\n    function readBool(\\n        bytes memory _in\\n    )\\n        internal\\n        pure\\n        returns (\\n            bool\\n        )\\n    {\\n        return readBool(\\n            toRLPItem(_in)\\n        );\\n    }\\n\\n    /**\\n     * Reads an RLP address value into a address.\\n     * @param _in RLP address value.\\n     * @return Decoded address.\\n     */\\n    function readAddress(\\n        RLPItem memory _in\\n    )\\n        internal\\n        pure\\n        returns (\\n            address\\n        )\\n    {\\n        if (_in.length == 1) {\\n            return address(0);\\n        }\\n\\n        require(\\n            _in.length == 21,\\n            \\\"Invalid RLP address value.\\\"\\n        );\\n\\n        return address(readUint256(_in));\\n    }\\n\\n    /**\\n     * Reads an RLP address value into a address.\\n     * @param _in RLP address value.\\n     * @return Decoded address.\\n     */\\n    function readAddress(\\n        bytes memory _in\\n    )\\n        internal\\n        pure\\n        returns (\\n            address\\n        )\\n    {\\n        return readAddress(\\n            toRLPItem(_in)\\n        );\\n    }\\n\\n    /**\\n     * Reads the raw bytes of an RLP item.\\n     * @param _in RLP item to read.\\n     * @return Raw RLP bytes.\\n     */\\n    function readRawBytes(\\n        RLPItem memory _in\\n    )\\n        internal\\n        pure\\n        returns (\\n            bytes memory\\n        )\\n    {\\n        return _copy(_in);\\n    }\\n\\n\\n    /*********************\\n     * Private Functions *\\n     *********************/\\n\\n    /**\\n     * Decodes the length of an RLP item.\\n     * @param _in RLP item to decode.\\n     * @return Offset of the encoded data.\\n     * @return Length of the encoded data.\\n     * @return RLP item type (LIST_ITEM or DATA_ITEM).\\n     */\\n    function _decodeLength(\\n        RLPItem memory _in\\n    )\\n        private\\n        pure\\n        returns (\\n            uint256,\\n            uint256,\\n            RLPItemType\\n        )\\n    {\\n        require(\\n            _in.length > 0,\\n            \\\"RLP item cannot be null.\\\"\\n        );\\n\\n        uint256 ptr = _in.ptr;\\n        uint256 prefix;\\n        assembly {\\n            prefix := byte(0, mload(ptr))\\n        }\\n\\n        if (prefix <= 0x7f) {\\n            // Single byte.\\n\\n            return (0, 1, RLPItemType.DATA_ITEM);\\n        } else if (prefix <= 0xb7) {\\n            // Short string.\\n\\n            uint256 strLen = prefix - 0x80;\\n            \\n            require(\\n                _in.length > strLen,\\n                \\\"Invalid RLP short string.\\\"\\n            );\\n\\n            return (1, strLen, RLPItemType.DATA_ITEM);\\n        } else if (prefix <= 0xbf) {\\n            // Long string.\\n            uint256 lenOfStrLen = prefix - 0xb7;\\n\\n            require(\\n                _in.length > lenOfStrLen,\\n                \\\"Invalid RLP long string length.\\\"\\n            );\\n\\n            uint256 strLen;\\n            assembly {\\n                // Pick out the string length.\\n                strLen := div(\\n                    mload(add(ptr, 1)),\\n                    exp(256, sub(32, lenOfStrLen))\\n                )\\n            }\\n\\n            require(\\n                _in.length > lenOfStrLen + strLen,\\n                \\\"Invalid RLP long string.\\\"\\n            );\\n\\n            return (1 + lenOfStrLen, strLen, RLPItemType.DATA_ITEM);\\n        } else if (prefix <= 0xf7) {\\n            // Short list.\\n            uint256 listLen = prefix - 0xc0;\\n\\n            require(\\n                _in.length > listLen,\\n                \\\"Invalid RLP short list.\\\"\\n            );\\n\\n            return (1, listLen, RLPItemType.LIST_ITEM);\\n        } else {\\n            // Long list.\\n            uint256 lenOfListLen = prefix - 0xf7;\\n\\n            require(\\n                _in.length > lenOfListLen,\\n                \\\"Invalid RLP long list length.\\\"\\n            );\\n\\n            uint256 listLen;\\n            assembly {\\n                // Pick out the list length.\\n                listLen := div(\\n                    mload(add(ptr, 1)),\\n                    exp(256, sub(32, lenOfListLen))\\n                )\\n            }\\n\\n            require(\\n                _in.length > lenOfListLen + listLen,\\n                \\\"Invalid RLP long list.\\\"\\n            );\\n\\n            return (1 + lenOfListLen, listLen, RLPItemType.LIST_ITEM);\\n        }\\n    }\\n\\n    /**\\n     * Copies the bytes from a memory location.\\n     * @param _src Pointer to the location to read from.\\n     * @param _offset Offset to start reading from.\\n     * @param _length Number of bytes to read.\\n     * @return Copied bytes.\\n     */\\n    function _copy(\\n        uint256 _src,\\n        uint256 _offset,\\n        uint256 _length\\n    )\\n        private\\n        pure\\n        returns (\\n            bytes memory\\n        )\\n    {\\n        bytes memory out = new bytes(_length);\\n        if (out.length == 0) {\\n            return out;\\n        }\\n\\n        uint256 src = _src + _offset;\\n        uint256 dest;\\n        assembly {\\n            dest := add(out, 32)\\n        }\\n\\n        // Copy over as many complete words as we can.\\n        for (uint256 i = 0; i < _length / 32; i++) {\\n            assembly {\\n                mstore(dest, mload(src))\\n            }\\n\\n            src += 32;\\n            dest += 32;\\n        }\\n\\n        // Pick out the remaining bytes.\\n        uint256 mask = 256 ** (32 - (_length % 32)) - 1;\\n        assembly {\\n            mstore(\\n                dest,\\n                or(\\n                    and(mload(src), not(mask)),\\n                    and(mload(dest), mask)\\n                )\\n            )\\n        }\\n\\n        return out;\\n    }\\n\\n    /**\\n     * Copies an RLP item into bytes.\\n     * @param _in RLP item to copy.\\n     * @return Copied bytes.\\n     */\\n    function _copy(\\n        RLPItem memory _in\\n    )\\n        private\\n        pure\\n        returns (\\n            bytes memory\\n        )\\n    {\\n        return _copy(_in.ptr, 0, _in.length);\\n    }\\n}\\n\",\"keccak256\":\"0x8338f7b6e5f0ded8fc36d9088fd127ee53ae4040ca3f4838eb6123f642d38c62\",\"license\":\"MIT\"},\"contracts/optimistic-ethereum/libraries/rlp/Lib_RLPWriter.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.7.0;\\npragma experimental ABIEncoderV2;\\n\\n/* Library Imports */\\nimport { Lib_BytesUtils } from \\\"../utils/Lib_BytesUtils.sol\\\";\\n\\n/**\\n * @title Lib_RLPWriter\\n * @author Bakaoh (with modifications)\\n */\\nlibrary Lib_RLPWriter {\\n\\n    /**********************\\n     * Internal Functions *\\n     **********************/\\n\\n    /**\\n     * RLP encodes a byte string.\\n     * @param _in The byte string to encode.\\n     * @return _out The RLP encoded string in bytes.\\n     */\\n    function writeBytes(\\n        bytes memory _in\\n    )\\n        internal\\n        pure\\n        returns (\\n            bytes memory _out\\n        )\\n    {\\n        bytes memory encoded;\\n\\n        if (_in.length == 1 && uint8(_in[0]) < 128) {\\n            encoded = _in;\\n        } else {\\n            encoded = Lib_BytesUtils.concat(_writeLength(_in.length, 128), _in);\\n        }\\n\\n        return encoded;\\n    }\\n\\n    /**\\n     * RLP encodes a list of RLP encoded byte byte strings.\\n     * @param _in The list of RLP encoded byte strings.\\n     * @return _out The RLP encoded list of items in bytes.\\n     */\\n    function writeList(\\n        bytes[] memory _in\\n    )\\n        internal\\n        pure\\n        returns (\\n            bytes memory _out\\n        )\\n    {\\n        bytes memory list = _flatten(_in);\\n        return Lib_BytesUtils.concat(_writeLength(list.length, 192), list);\\n    }\\n\\n    /**\\n     * RLP encodes a string.\\n     * @param _in The string to encode.\\n     * @return _out The RLP encoded string in bytes.\\n     */\\n    function writeString(\\n        string memory _in\\n    )\\n        internal\\n        pure\\n        returns (\\n            bytes memory _out\\n        )\\n    {\\n        return writeBytes(bytes(_in));\\n    }\\n\\n    /**\\n     * RLP encodes an address.\\n     * @param _in The address to encode.\\n     * @return _out The RLP encoded address in bytes.\\n     */\\n    function writeAddress(\\n        address _in\\n    )\\n        internal\\n        pure\\n        returns (\\n            bytes memory _out\\n        )\\n    {\\n        return writeBytes(abi.encodePacked(_in));\\n    }\\n\\n    /**\\n     * RLP encodes a uint.\\n     * @param _in The uint256 to encode.\\n     * @return _out The RLP encoded uint256 in bytes.\\n     */\\n    function writeUint(\\n        uint256 _in\\n    )\\n        internal\\n        pure\\n        returns (\\n            bytes memory _out\\n        )\\n    {\\n        return writeBytes(_toBinary(_in));\\n    }\\n\\n    /**\\n     * RLP encodes a bool.\\n     * @param _in The bool to encode.\\n     * @return _out The RLP encoded bool in bytes.\\n     */\\n    function writeBool(\\n        bool _in\\n    )\\n        internal\\n        pure\\n        returns (\\n            bytes memory _out\\n        )\\n    {\\n        bytes memory encoded = new bytes(1);\\n        encoded[0] = (_in ? bytes1(0x01) : bytes1(0x80));\\n        return encoded;\\n    }\\n\\n\\n    /*********************\\n     * Private Functions *\\n     *********************/\\n\\n    /**\\n     * Encode the first byte, followed by the `len` in binary form if `length` is more than 55.\\n     * @param _len The length of the string or the payload.\\n     * @param _offset 128 if item is string, 192 if item is list.\\n     * @return _encoded RLP encoded bytes.\\n     */\\n    function _writeLength(\\n        uint256 _len,\\n        uint256 _offset\\n    )\\n        private\\n        pure\\n        returns (\\n            bytes memory _encoded\\n        )\\n    {\\n        bytes memory encoded;\\n\\n        if (_len < 56) {\\n            encoded = new bytes(1);\\n            encoded[0] = byte(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] = byte(uint8(lenLen) + uint8(_offset) + 55);\\n            for(i = 1; i <= lenLen; i++) {\\n                encoded[i] = byte(uint8((_len / (256**(lenLen-i))) % 256));\\n            }\\n        }\\n\\n        return encoded;\\n    }\\n\\n    /**\\n     * Encode integer in big endian binary form with no leading zeroes.\\n     * @notice TODO: This should be optimized with assembly to save gas costs.\\n     * @param _x The integer to encode.\\n     * @return _binary RLP encoded bytes.\\n     */\\n    function _toBinary(\\n        uint256 _x\\n    )\\n        private\\n        pure\\n        returns (\\n            bytes memory _binary\\n        )\\n    {\\n        bytes memory b = abi.encodePacked(_x);\\n\\n        uint256 i = 0;\\n        for (; i < 32; i++) {\\n            if (b[i] != 0) {\\n                break;\\n            }\\n        }\\n\\n        bytes memory res = new bytes(32 - i);\\n        for (uint256 j = 0; j < res.length; j++) {\\n            res[j] = b[i++];\\n        }\\n\\n        return res;\\n    }\\n\\n    /**\\n     * Copies a piece of memory to another location.\\n     * @notice From: https://github.com/Arachnid/solidity-stringutils/blob/master/src/strings.sol.\\n     * @param _dest Destination location.\\n     * @param _src Source location.\\n     * @param _len Length of memory to copy.\\n     */\\n    function _memcpy(\\n        uint256 _dest,\\n        uint256 _src,\\n        uint256 _len\\n    )\\n        private\\n        pure\\n    {\\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 = 256 ** (32 - len) - 1;\\n        assembly {\\n            let srcpart := and(mload(src), not(mask))\\n            let destpart := and(mload(dest), mask)\\n            mstore(dest, or(destpart, srcpart))\\n        }\\n    }\\n\\n    /**\\n     * Flattens a list of byte strings into one byte string.\\n     * @notice From: https://github.com/sammayo/solidity-rlp-encoder/blob/master/RLPEncode.sol.\\n     * @param _list List of byte strings to flatten.\\n     * @return _flattened The flattened byte string.\\n     */\\n    function _flatten(\\n        bytes[] memory _list\\n    )\\n        private\\n        pure\\n        returns (\\n            bytes memory _flattened\\n        )\\n    {\\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 { flattenedPtr := add(flattened, 0x20) }\\n\\n        for(i = 0; i < _list.length; i++) {\\n            bytes memory item = _list[i];\\n\\n            uint256 listPtr;\\n            assembly { listPtr := add(item, 0x20)}\\n\\n            _memcpy(flattenedPtr, listPtr, item.length);\\n            flattenedPtr += _list[i].length;\\n        }\\n\\n        return flattened;\\n    }\\n}\",\"keccak256\":\"0x6d1aaef567f8a91bb965b95a95637f433a1f0ac4cf0bc1e209cdb1dd5b0f204b\",\"license\":\"MIT\"},\"contracts/optimistic-ethereum/libraries/trie/Lib_MerkleTrie.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.7.0;\\n\\n/* Library Imports */\\nimport { Lib_BytesUtils } from \\\"../utils/Lib_BytesUtils.sol\\\";\\nimport { Lib_RLPReader } from \\\"../rlp/Lib_RLPReader.sol\\\";\\nimport { Lib_RLPWriter } from \\\"../rlp/Lib_RLPWriter.sol\\\";\\n\\n/**\\n * @title Lib_MerkleTrie\\n */\\nlibrary Lib_MerkleTrie {\\n\\n    /*******************\\n     * Data Structures *\\n     *******************/\\n\\n    enum NodeType {\\n        BranchNode,\\n        ExtensionNode,\\n        LeafNode\\n    }\\n\\n    struct TrieNode {\\n        bytes encoded;\\n        Lib_RLPReader.RLPItem[] decoded;\\n    }\\n\\n\\n    /**********************\\n     * Contract Constants *\\n     **********************/\\n\\n    // TREE_RADIX determines the number of elements per branch node.\\n    uint256 constant TREE_RADIX = 16;\\n    // Branch nodes have TREE_RADIX elements plus an additional `value` slot.\\n    uint256 constant BRANCH_NODE_LENGTH = TREE_RADIX + 1;\\n    // Leaf nodes and extension nodes always have two elements, a `path` and a `value`.\\n    uint256 constant LEAF_OR_EXTENSION_NODE_LENGTH = 2;\\n\\n    // Prefixes are prepended to the `path` within a leaf or extension node and\\n    // allow us to differentiate between the two node types. `ODD` or `EVEN` is\\n    // determined by the number of nibbles within the unprefixed `path`. If the\\n    // number of nibbles if even, we need to insert an extra padding nibble so\\n    // the resulting prefixed `path` has an even number of nibbles.\\n    uint8 constant PREFIX_EXTENSION_EVEN = 0;\\n    uint8 constant PREFIX_EXTENSION_ODD = 1;\\n    uint8 constant PREFIX_LEAF_EVEN = 2;\\n    uint8 constant PREFIX_LEAF_ODD = 3;\\n\\n    // Just a utility constant. RLP represents `NULL` as 0x80.\\n    bytes1 constant RLP_NULL = bytes1(0x80);\\n    bytes constant RLP_NULL_BYTES = hex'80';\\n    bytes32 constant internal KECCAK256_RLP_NULL_BYTES = keccak256(RLP_NULL_BYTES);\\n\\n\\n    /**********************\\n     * Internal Functions *\\n     **********************/\\n\\n    /**\\n     * @notice Verifies a proof that a given key/value pair is present in the\\n     * Merkle trie.\\n     * @param _key Key of the node to search for, as a hex string.\\n     * @param _value Value of the node to search for, as a hex string.\\n     * @param _proof Merkle trie inclusion proof for the desired node. Unlike\\n     * traditional Merkle trees, this proof is executed top-down and consists\\n     * of a list of RLP-encoded nodes that make a path down to the target node.\\n     * @param _root Known root of the Merkle trie. Used to verify that the\\n     * included proof is correctly constructed.\\n     * @return _verified `true` if the k/v pair exists in the trie, `false` otherwise.\\n     */\\n    function verifyInclusionProof(\\n        bytes memory _key,\\n        bytes memory _value,\\n        bytes memory _proof,\\n        bytes32 _root\\n    )\\n        internal\\n        pure\\n        returns (\\n            bool _verified\\n        )\\n    {\\n        (\\n            bool exists,\\n            bytes memory value\\n        ) = get(_key, _proof, _root);\\n\\n        return (\\n            exists && Lib_BytesUtils.equal(_value, value)\\n        );\\n    }\\n\\n    /**\\n     * @notice Verifies a proof that a given key is *not* present in\\n     * the Merkle trie.\\n     * @param _key Key of the node to search for, as a hex string.\\n     * @param _proof Merkle trie inclusion proof for the node *nearest* the\\n     * target node.\\n     * @param _root Known root of the Merkle trie. Used to verify that the\\n     * included proof is correctly constructed.\\n     * @return _verified `true` if the key is absent in the trie, `false` otherwise.\\n     */\\n    function verifyExclusionProof(\\n        bytes memory _key,\\n        bytes memory _proof,\\n        bytes32 _root\\n    )\\n        internal\\n        pure\\n        returns (\\n            bool _verified\\n        )\\n    {\\n        (\\n            bool exists,\\n        ) = get(_key, _proof, _root);\\n\\n        return exists == false;\\n    }\\n\\n    /**\\n     * @notice Updates a Merkle trie and returns a new root hash.\\n     * @param _key Key of the node to update, as a hex string.\\n     * @param _value Value of the node to update, as a hex string.\\n     * @param _proof Merkle trie inclusion proof for the node *nearest* the\\n     * target node. If the key exists, we can simply update the value.\\n     * Otherwise, we need to modify the trie to handle the new k/v pair.\\n     * @param _root Known root of the Merkle trie. Used to verify that the\\n     * included proof is correctly constructed.\\n     * @return _updatedRoot Root hash of the newly constructed trie.\\n     */\\n    function update(\\n        bytes memory _key,\\n        bytes memory _value,\\n        bytes memory _proof,\\n        bytes32 _root\\n    )\\n        internal\\n        pure\\n        returns (\\n            bytes32 _updatedRoot\\n        )\\n    {\\n        // Special case when inserting the very first node.\\n        if (_root == KECCAK256_RLP_NULL_BYTES) {\\n            return getSingleNodeRootHash(_key, _value);\\n        }\\n\\n        TrieNode[] memory proof = _parseProof(_proof);\\n        (uint256 pathLength, bytes memory keyRemainder, ) = _walkNodePath(proof, _key, _root);\\n        TrieNode[] memory newPath = _getNewPath(proof, pathLength, keyRemainder, _value);\\n\\n        return _getUpdatedTrieRoot(newPath, _key);\\n    }\\n\\n    /**\\n     * @notice Retrieves the value associated with a given key.\\n     * @param _key Key to search for, as hex bytes.\\n     * @param _proof Merkle trie inclusion proof for the key.\\n     * @param _root Known root of the Merkle trie.\\n     * @return _exists Whether or not the key exists.\\n     * @return _value Value of the key if it exists.\\n     */\\n    function get(\\n        bytes memory _key,\\n        bytes memory _proof,\\n        bytes32 _root\\n    )\\n        internal\\n        pure\\n        returns (\\n            bool _exists,\\n            bytes memory _value\\n        )\\n    {\\n        TrieNode[] memory proof = _parseProof(_proof);\\n        (uint256 pathLength, bytes memory keyRemainder, bool isFinalNode) = _walkNodePath(proof, _key, _root);\\n\\n        bool exists = keyRemainder.length == 0;\\n\\n        require(\\n            exists || isFinalNode,\\n            \\\"Provided proof is invalid.\\\"\\n        );\\n\\n        bytes memory value = exists ? _getNodeValue(proof[pathLength - 1]) : bytes('');\\n\\n        return (\\n            exists,\\n            value\\n        );\\n    }\\n\\n    /**\\n     * Computes the root hash for a trie with a single node.\\n     * @param _key Key for the single node.\\n     * @param _value Value for the single node.\\n     * @return _updatedRoot Hash of the trie.\\n     */\\n    function getSingleNodeRootHash(\\n        bytes memory _key,\\n        bytes memory _value\\n    )\\n        internal\\n        pure\\n        returns (\\n            bytes32 _updatedRoot\\n        )\\n    {\\n        return keccak256(_makeLeafNode(\\n            Lib_BytesUtils.toNibbles(_key),\\n            _value\\n        ).encoded);\\n    }\\n\\n\\n    /*********************\\n     * Private Functions *\\n     *********************/\\n\\n    /**\\n     * @notice Walks through a proof using a provided key.\\n     * @param _proof Inclusion proof to walk through.\\n     * @param _key Key to use for the walk.\\n     * @param _root Known root of the trie.\\n     * @return _pathLength Length of the final path\\n     * @return _keyRemainder Portion of the key remaining after the walk.\\n     * @return _isFinalNode Whether or not we've hit a dead end.\\n     */\\n    function _walkNodePath(\\n        TrieNode[] memory _proof,\\n        bytes memory _key,\\n        bytes32 _root\\n    )\\n        private\\n        pure\\n        returns (\\n            uint256 _pathLength,\\n            bytes memory _keyRemainder,\\n            bool _isFinalNode\\n        )\\n    {\\n        uint256 pathLength = 0;\\n        bytes memory key = Lib_BytesUtils.toNibbles(_key);\\n\\n        bytes32 currentNodeID = _root;\\n        uint256 currentKeyIndex = 0;\\n        uint256 currentKeyIncrement = 0;\\n        TrieNode memory currentNode;\\n\\n        // Proof is top-down, so we start at the first element (root).\\n        for (uint256 i = 0; i < _proof.length; i++) {\\n            currentNode = _proof[i];\\n            currentKeyIndex += currentKeyIncrement;\\n\\n            // Keep track of the proof elements we actually need.\\n            // It's expensive to resize arrays, so this simply reduces gas costs.\\n            pathLength += 1;\\n\\n            if (currentKeyIndex == 0) {\\n                // First proof element is always the root node.\\n                require(\\n                    keccak256(currentNode.encoded) == currentNodeID,\\n                    \\\"Invalid root hash\\\"\\n                );\\n            } else if (currentNode.encoded.length >= 32) {\\n                // Nodes 32 bytes or larger are hashed inside branch nodes.\\n                require(\\n                    keccak256(currentNode.encoded) == currentNodeID,\\n                    \\\"Invalid large internal hash\\\"\\n                );\\n            } else {\\n                // Nodes smaller than 31 bytes aren't hashed.\\n                require(\\n                    Lib_BytesUtils.toBytes32(currentNode.encoded) == currentNodeID,\\n                    \\\"Invalid internal node hash\\\"\\n                );\\n            }\\n\\n            if (currentNode.decoded.length == BRANCH_NODE_LENGTH) {\\n                if (currentKeyIndex == key.length) {\\n                    // We've hit the end of the key, meaning the value should be within this branch node.\\n                    break;\\n                } else {\\n                    // We're not at the end of the key yet.\\n                    // Figure out what the next node ID should be and continue.\\n                    uint8 branchKey = uint8(key[currentKeyIndex]);\\n                    Lib_RLPReader.RLPItem memory nextNode = currentNode.decoded[branchKey];\\n                    currentNodeID = _getNodeID(nextNode);\\n                    currentKeyIncrement = 1;\\n                    continue;\\n                }\\n            } else if (currentNode.decoded.length == LEAF_OR_EXTENSION_NODE_LENGTH) {\\n                bytes memory path = _getNodePath(currentNode);\\n                uint8 prefix = uint8(path[0]);\\n                uint8 offset = 2 - prefix % 2;\\n                bytes memory pathRemainder = Lib_BytesUtils.slice(path, offset);\\n                bytes memory keyRemainder = Lib_BytesUtils.slice(key, currentKeyIndex);\\n                uint256 sharedNibbleLength = _getSharedNibbleLength(pathRemainder, keyRemainder);\\n\\n                if (prefix == PREFIX_LEAF_EVEN || prefix == PREFIX_LEAF_ODD) {\\n                    if (\\n                        pathRemainder.length == sharedNibbleLength &&\\n                        keyRemainder.length == sharedNibbleLength\\n                    ) {\\n                        // The key within this leaf matches our key exactly.\\n                        // Increment the key index to reflect that we have no remainder.\\n                        currentKeyIndex += sharedNibbleLength;\\n                    }\\n\\n                    // We've hit a leaf node, so our next node should be NULL.\\n                    currentNodeID = bytes32(RLP_NULL);\\n                    break;\\n                } else if (prefix == PREFIX_EXTENSION_EVEN || prefix == PREFIX_EXTENSION_ODD) {\\n                    if (sharedNibbleLength == 0) {\\n                        // Our extension node doesn't share any part of our key.\\n                        // We've hit the end of this path, updates will need to modify this extension.\\n                        currentNodeID = bytes32(RLP_NULL);\\n                        break;\\n                    } else {\\n                        // Our extension shares some nibbles.\\n                        // Carry on to the next node.\\n                        currentNodeID = _getNodeID(currentNode.decoded[1]);\\n                        currentKeyIncrement = sharedNibbleLength;\\n                        continue;\\n                    }\\n                } else {\\n                    revert(\\\"Received a node with an unknown prefix\\\");\\n                }\\n            } else {\\n                revert(\\\"Received an unparseable node.\\\");\\n            }\\n        }\\n\\n        // If our node ID is NULL, then we're at a dead end.\\n        bool isFinalNode = currentNodeID == bytes32(RLP_NULL);\\n        return (pathLength, Lib_BytesUtils.slice(key, currentKeyIndex), isFinalNode);\\n    }\\n\\n    /**\\n     * @notice Creates new nodes to support a k/v pair insertion into a given\\n     * Merkle trie path.\\n     * @param _path Path to the node nearest the k/v pair.\\n     * @param _pathLength Length of the path. Necessary because the provided\\n     * path may include additional nodes (e.g., it comes directly from a proof)\\n     * and we can't resize in-memory arrays without costly duplication.\\n     * @param _keyRemainder Portion of the initial key that must be inserted\\n     * into the trie.\\n     * @param _value Value to insert at the given key.\\n     * @return _newPath A new path with the inserted k/v pair and extra supporting nodes.\\n     */\\n    function _getNewPath(\\n        TrieNode[] memory _path,\\n        uint256 _pathLength,\\n        bytes memory _keyRemainder,\\n        bytes memory _value\\n    )\\n        private\\n        pure\\n        returns (\\n            TrieNode[] memory _newPath\\n        )\\n    {\\n        bytes memory keyRemainder = _keyRemainder;\\n\\n        // Most of our logic depends on the status of the last node in the path.\\n        TrieNode memory lastNode = _path[_pathLength - 1];\\n        NodeType lastNodeType = _getNodeType(lastNode);\\n\\n        // Create an array for newly created nodes.\\n        // We need up to three new nodes, depending on the contents of the last node.\\n        // Since array resizing is expensive, we'll keep track of the size manually.\\n        // We're using an explicit `totalNewNodes += 1` after insertions for clarity.\\n        TrieNode[] memory newNodes = new TrieNode[](3);\\n        uint256 totalNewNodes = 0;\\n\\n        if (keyRemainder.length == 0 && lastNodeType == NodeType.LeafNode) {\\n            // We've found a leaf node with the given key.\\n            // Simply need to update the value of the node to match.\\n            newNodes[totalNewNodes] = _makeLeafNode(_getNodeKey(lastNode), _value);\\n            totalNewNodes += 1;\\n        } else if (lastNodeType == NodeType.BranchNode) {\\n            if (keyRemainder.length == 0) {\\n                // We've found a branch node with the given key.\\n                // Simply need to update the value of the node to match.\\n                newNodes[totalNewNodes] = _editBranchValue(lastNode, _value);\\n                totalNewNodes += 1;\\n            } else {\\n                // We've found a branch node, but it doesn't contain our key.\\n                // Reinsert the old branch for now.\\n                newNodes[totalNewNodes] = lastNode;\\n                totalNewNodes += 1;\\n                // Create a new leaf node, slicing our remainder since the first byte points\\n                // to our branch node.\\n                newNodes[totalNewNodes] = _makeLeafNode(Lib_BytesUtils.slice(keyRemainder, 1), _value);\\n                totalNewNodes += 1;\\n            }\\n        } else {\\n            // Our last node is either an extension node or a leaf node with a different key.\\n            bytes memory lastNodeKey = _getNodeKey(lastNode);\\n            uint256 sharedNibbleLength = _getSharedNibbleLength(lastNodeKey, keyRemainder);\\n\\n            if (sharedNibbleLength != 0) {\\n                // We've got some shared nibbles between the last node and our key remainder.\\n                // We'll need to insert an extension node that covers these shared nibbles.\\n                bytes memory nextNodeKey = Lib_BytesUtils.slice(lastNodeKey, 0, sharedNibbleLength);\\n                newNodes[totalNewNodes] = _makeExtensionNode(nextNodeKey, _getNodeHash(_value));\\n                totalNewNodes += 1;\\n\\n                // Cut down the keys since we've just covered these shared nibbles.\\n                lastNodeKey = Lib_BytesUtils.slice(lastNodeKey, sharedNibbleLength);\\n                keyRemainder = Lib_BytesUtils.slice(keyRemainder, sharedNibbleLength);\\n            }\\n\\n            // Create an empty branch to fill in.\\n            TrieNode memory newBranch = _makeEmptyBranchNode();\\n\\n            if (lastNodeKey.length == 0) {\\n                // Key remainder was larger than the key for our last node.\\n                // The value within our last node is therefore going to be shifted into\\n                // a branch value slot.\\n                newBranch = _editBranchValue(newBranch, _getNodeValue(lastNode));\\n            } else {\\n                // Last node key was larger than the key remainder.\\n                // We're going to modify some index of our branch.\\n                uint8 branchKey = uint8(lastNodeKey[0]);\\n                // Move on to the next nibble.\\n                lastNodeKey = Lib_BytesUtils.slice(lastNodeKey, 1);\\n\\n                if (lastNodeType == NodeType.LeafNode) {\\n                    // We're dealing with a leaf node.\\n                    // We'll modify the key and insert the old leaf node into the branch index.\\n                    TrieNode memory modifiedLastNode = _makeLeafNode(lastNodeKey, _getNodeValue(lastNode));\\n                    newBranch = _editBranchIndex(newBranch, branchKey, _getNodeHash(modifiedLastNode.encoded));\\n                } else if (lastNodeKey.length != 0) {\\n                    // We're dealing with a shrinking extension node.\\n                    // We need to modify the node to decrease the size of the key.\\n                    TrieNode memory modifiedLastNode = _makeExtensionNode(lastNodeKey, _getNodeValue(lastNode));\\n                    newBranch = _editBranchIndex(newBranch, branchKey, _getNodeHash(modifiedLastNode.encoded));\\n                } else {\\n                    // We're dealing with an unnecessary extension node.\\n                    // We're going to delete the node entirely.\\n                    // Simply insert its current value into the branch index.\\n                    newBranch = _editBranchIndex(newBranch, branchKey, _getNodeValue(lastNode));\\n                }\\n            }\\n\\n            if (keyRemainder.length == 0) {\\n                // We've got nothing left in the key remainder.\\n                // Simply insert the value into the branch value slot.\\n                newBranch = _editBranchValue(newBranch, _value);\\n                // Push the branch into the list of new nodes.\\n                newNodes[totalNewNodes] = newBranch;\\n                totalNewNodes += 1;\\n            } else {\\n                // We've got some key remainder to work with.\\n                // We'll be inserting a leaf node into the trie.\\n                // First, move on to the next nibble.\\n                keyRemainder = Lib_BytesUtils.slice(keyRemainder, 1);\\n                // Push the branch into the list of new nodes.\\n                newNodes[totalNewNodes] = newBranch;\\n                totalNewNodes += 1;\\n                // Push a new leaf node for our k/v pair.\\n                newNodes[totalNewNodes] = _makeLeafNode(keyRemainder, _value);\\n                totalNewNodes += 1;\\n            }\\n        }\\n\\n        // Finally, join the old path with our newly created nodes.\\n        // Since we're overwriting the last node in the path, we use `_pathLength - 1`.\\n        return _joinNodeArrays(_path, _pathLength - 1, newNodes, totalNewNodes);\\n    }\\n\\n    /**\\n     * @notice Computes the trie root from a given path.\\n     * @param _nodes Path to some k/v pair.\\n     * @param _key Key for the k/v pair.\\n     * @return _updatedRoot Root hash for the updated trie.\\n     */\\n    function _getUpdatedTrieRoot(\\n        TrieNode[] memory _nodes,\\n        bytes memory _key\\n    )\\n        private\\n        pure\\n        returns (\\n            bytes32 _updatedRoot\\n        )\\n    {\\n        bytes memory key = Lib_BytesUtils.toNibbles(_key);\\n\\n        // Some variables to keep track of during iteration.\\n        TrieNode memory currentNode;\\n        NodeType currentNodeType;\\n        bytes memory previousNodeHash;\\n\\n        // Run through the path backwards to rebuild our root hash.\\n        for (uint256 i = _nodes.length; i > 0; i--) {\\n            // Pick out the current node.\\n            currentNode = _nodes[i - 1];\\n            currentNodeType = _getNodeType(currentNode);\\n\\n            if (currentNodeType == NodeType.LeafNode) {\\n                // Leaf nodes are already correctly encoded.\\n                // Shift the key over to account for the nodes key.\\n                bytes memory nodeKey = _getNodeKey(currentNode);\\n                key = Lib_BytesUtils.slice(key, 0, key.length - nodeKey.length);\\n            } else if (currentNodeType == NodeType.ExtensionNode) {\\n                // Shift the key over to account for the nodes key.\\n                bytes memory nodeKey = _getNodeKey(currentNode);\\n                key = Lib_BytesUtils.slice(key, 0, key.length - nodeKey.length);\\n\\n                // If this node is the last element in the path, it'll be correctly encoded\\n                // and we can skip this part.\\n                if (previousNodeHash.length > 0) {\\n                    // Re-encode the node based on the previous node.\\n                    currentNode = _makeExtensionNode(nodeKey, previousNodeHash);\\n                }\\n            } else if (currentNodeType == NodeType.BranchNode) {\\n                // If this node is the last element in the path, it'll be correctly encoded\\n                // and we can skip this part.\\n                if (previousNodeHash.length > 0) {\\n                    // Re-encode the node based on the previous node.\\n                    uint8 branchKey = uint8(key[key.length - 1]);\\n                    key = Lib_BytesUtils.slice(key, 0, key.length - 1);\\n                    currentNode = _editBranchIndex(currentNode, branchKey, previousNodeHash);\\n                }\\n            }\\n\\n            // Compute the node hash for the next iteration.\\n            previousNodeHash = _getNodeHash(currentNode.encoded);\\n        }\\n\\n        // Current node should be the root at this point.\\n        // Simply return the hash of its encoding.\\n        return keccak256(currentNode.encoded);\\n    }\\n\\n    /**\\n     * @notice Parses an RLP-encoded proof into something more useful.\\n     * @param _proof RLP-encoded proof to parse.\\n     * @return _parsed Proof parsed into easily accessible structs.\\n     */\\n    function _parseProof(\\n        bytes memory _proof\\n    )\\n        private\\n        pure\\n        returns (\\n            TrieNode[] memory _parsed\\n        )\\n    {\\n        Lib_RLPReader.RLPItem[] memory nodes = Lib_RLPReader.readList(_proof);\\n        TrieNode[] memory proof = new TrieNode[](nodes.length);\\n\\n        for (uint256 i = 0; i < nodes.length; i++) {\\n            bytes memory encoded = Lib_RLPReader.readBytes(nodes[i]);\\n            proof[i] = TrieNode({\\n                encoded: encoded,\\n                decoded: Lib_RLPReader.readList(encoded)\\n            });\\n        }\\n\\n        return proof;\\n    }\\n\\n    /**\\n     * @notice Picks out the ID for a node. Node ID is referred to as the\\n     * \\\"hash\\\" within the specification, but nodes < 32 bytes are not actually\\n     * hashed.\\n     * @param _node Node to pull an ID for.\\n     * @return _nodeID ID for the node, depending on the size of its contents.\\n     */\\n    function _getNodeID(\\n        Lib_RLPReader.RLPItem memory _node\\n    )\\n        private\\n        pure\\n        returns (\\n            bytes32 _nodeID\\n        )\\n    {\\n        bytes memory nodeID;\\n\\n        if (_node.length < 32) {\\n            // Nodes smaller than 32 bytes are RLP encoded.\\n            nodeID = Lib_RLPReader.readRawBytes(_node);\\n        } else {\\n            // Nodes 32 bytes or larger are hashed.\\n            nodeID = Lib_RLPReader.readBytes(_node);\\n        }\\n\\n        return Lib_BytesUtils.toBytes32(nodeID);\\n    }\\n\\n    /**\\n     * @notice Gets the path for a leaf or extension node.\\n     * @param _node Node to get a path for.\\n     * @return _path Node path, converted to an array of nibbles.\\n     */\\n    function _getNodePath(\\n        TrieNode memory _node\\n    )\\n        private\\n        pure\\n        returns (\\n            bytes memory _path\\n        )\\n    {\\n        return Lib_BytesUtils.toNibbles(Lib_RLPReader.readBytes(_node.decoded[0]));\\n    }\\n\\n    /**\\n     * @notice Gets the key for a leaf or extension node. Keys are essentially\\n     * just paths without any prefix.\\n     * @param _node Node to get a key for.\\n     * @return _key Node key, converted to an array of nibbles.\\n     */\\n    function _getNodeKey(\\n        TrieNode memory _node\\n    )\\n        private\\n        pure\\n        returns (\\n            bytes memory _key\\n        )\\n    {\\n        return _removeHexPrefix(_getNodePath(_node));\\n    }\\n\\n    /**\\n     * @notice Gets the path for a node.\\n     * @param _node Node to get a value for.\\n     * @return _value Node value, as hex bytes.\\n     */\\n    function _getNodeValue(\\n        TrieNode memory _node\\n    )\\n        private\\n        pure\\n        returns (\\n            bytes memory _value\\n        )\\n    {\\n        return Lib_RLPReader.readBytes(_node.decoded[_node.decoded.length - 1]);\\n    }\\n\\n    /**\\n     * @notice Computes the node hash for an encoded node. Nodes < 32 bytes\\n     * are not hashed, all others are keccak256 hashed.\\n     * @param _encoded Encoded node to hash.\\n     * @return _hash Hash of the encoded node. Simply the input if < 32 bytes.\\n     */\\n    function _getNodeHash(\\n        bytes memory _encoded\\n    )\\n        private\\n        pure\\n        returns (\\n            bytes memory _hash\\n        )\\n    {\\n        if (_encoded.length < 32) {\\n            return _encoded;\\n        } else {\\n            return abi.encodePacked(keccak256(_encoded));\\n        }\\n    }\\n\\n    /**\\n     * @notice Determines the type for a given node.\\n     * @param _node Node to determine a type for.\\n     * @return _type Type of the node; BranchNode/ExtensionNode/LeafNode.\\n     */\\n    function _getNodeType(\\n        TrieNode memory _node\\n    )\\n        private\\n        pure\\n        returns (\\n            NodeType _type\\n        )\\n    {\\n        if (_node.decoded.length == BRANCH_NODE_LENGTH) {\\n            return NodeType.BranchNode;\\n        } else if (_node.decoded.length == LEAF_OR_EXTENSION_NODE_LENGTH) {\\n            bytes memory path = _getNodePath(_node);\\n            uint8 prefix = uint8(path[0]);\\n\\n            if (prefix == PREFIX_LEAF_EVEN || prefix == PREFIX_LEAF_ODD) {\\n                return NodeType.LeafNode;\\n            } else if (prefix == PREFIX_EXTENSION_EVEN || prefix == PREFIX_EXTENSION_ODD) {\\n                return NodeType.ExtensionNode;\\n            }\\n        }\\n\\n        revert(\\\"Invalid node type\\\");\\n    }\\n\\n    /**\\n     * @notice Utility; determines the number of nibbles shared between two\\n     * nibble arrays.\\n     * @param _a First nibble array.\\n     * @param _b Second nibble array.\\n     * @return _shared Number of shared nibbles.\\n     */\\n    function _getSharedNibbleLength(\\n        bytes memory _a,\\n        bytes memory _b\\n    )\\n        private\\n        pure\\n        returns (\\n            uint256 _shared\\n        )\\n    {\\n        uint256 i = 0;\\n        while (_a.length > i && _b.length > i && _a[i] == _b[i]) {\\n            i++;\\n        }\\n        return i;\\n    }\\n\\n    /**\\n     * @notice Utility; converts an RLP-encoded node into our nice struct.\\n     * @param _raw RLP-encoded node to convert.\\n     * @return _node Node as a TrieNode struct.\\n     */\\n    function _makeNode(\\n        bytes[] memory _raw\\n    )\\n        private\\n        pure\\n        returns (\\n            TrieNode memory _node\\n        )\\n    {\\n        bytes memory encoded = Lib_RLPWriter.writeList(_raw);\\n\\n        return TrieNode({\\n            encoded: encoded,\\n            decoded: Lib_RLPReader.readList(encoded)\\n        });\\n    }\\n\\n    /**\\n     * @notice Utility; converts an RLP-decoded node into our nice struct.\\n     * @param _items RLP-decoded node to convert.\\n     * @return _node Node as a TrieNode struct.\\n     */\\n    function _makeNode(\\n        Lib_RLPReader.RLPItem[] memory _items\\n    )\\n        private\\n        pure\\n        returns (\\n            TrieNode memory _node\\n        )\\n    {\\n        bytes[] memory raw = new bytes[](_items.length);\\n        for (uint256 i = 0; i < _items.length; i++) {\\n            raw[i] = Lib_RLPReader.readRawBytes(_items[i]);\\n        }\\n        return _makeNode(raw);\\n    }\\n\\n    /**\\n     * @notice Creates a new extension node.\\n     * @param _key Key for the extension node, unprefixed.\\n     * @param _value Value for the extension node.\\n     * @return _node New extension node with the given k/v pair.\\n     */\\n    function _makeExtensionNode(\\n        bytes memory _key,\\n        bytes memory _value\\n    )\\n        private\\n        pure\\n        returns (\\n            TrieNode memory _node\\n        )\\n    {\\n        bytes[] memory raw = new bytes[](2);\\n        bytes memory key = _addHexPrefix(_key, false);\\n        raw[0] = Lib_RLPWriter.writeBytes(Lib_BytesUtils.fromNibbles(key));\\n        raw[1] = Lib_RLPWriter.writeBytes(_value);\\n        return _makeNode(raw);\\n    }\\n\\n    /**\\n     * @notice Creates a new leaf node.\\n     * @dev This function is essentially identical to `_makeExtensionNode`.\\n     * Although we could route both to a single method with a flag, it's\\n     * more gas efficient to keep them separate and duplicate the logic.\\n     * @param _key Key for the leaf node, unprefixed.\\n     * @param _value Value for the leaf node.\\n     * @return _node New leaf node with the given k/v pair.\\n     */\\n    function _makeLeafNode(\\n        bytes memory _key,\\n        bytes memory _value\\n    )\\n        private\\n        pure\\n        returns (\\n            TrieNode memory _node\\n        )\\n    {\\n        bytes[] memory raw = new bytes[](2);\\n        bytes memory key = _addHexPrefix(_key, true);\\n        raw[0] = Lib_RLPWriter.writeBytes(Lib_BytesUtils.fromNibbles(key));\\n        raw[1] = Lib_RLPWriter.writeBytes(_value);\\n        return _makeNode(raw);\\n    }\\n\\n    /**\\n     * @notice Creates an empty branch node.\\n     * @return _node Empty branch node as a TrieNode struct.\\n     */\\n    function _makeEmptyBranchNode()\\n        private\\n        pure\\n        returns (\\n            TrieNode memory _node\\n        )\\n    {\\n        bytes[] memory raw = new bytes[](BRANCH_NODE_LENGTH);\\n        for (uint256 i = 0; i < raw.length; i++) {\\n            raw[i] = RLP_NULL_BYTES;\\n        }\\n        return _makeNode(raw);\\n    }\\n\\n    /**\\n     * @notice Modifies the value slot for a given branch.\\n     * @param _branch Branch node to modify.\\n     * @param _value Value to insert into the branch.\\n     * @return _updatedNode Modified branch node.\\n     */\\n    function _editBranchValue(\\n        TrieNode memory _branch,\\n        bytes memory _value\\n    )\\n        private\\n        pure\\n        returns (\\n            TrieNode memory _updatedNode\\n        )\\n    {\\n        bytes memory encoded = Lib_RLPWriter.writeBytes(_value);\\n        _branch.decoded[_branch.decoded.length - 1] = Lib_RLPReader.toRLPItem(encoded);\\n        return _makeNode(_branch.decoded);\\n    }\\n\\n    /**\\n     * @notice Modifies a slot at an index for a given branch.\\n     * @param _branch Branch node to modify.\\n     * @param _index Slot index to modify.\\n     * @param _value Value to insert into the slot.\\n     * @return _updatedNode Modified branch node.\\n     */\\n    function _editBranchIndex(\\n        TrieNode memory _branch,\\n        uint8 _index,\\n        bytes memory _value\\n    )\\n        private\\n        pure\\n        returns (\\n            TrieNode memory _updatedNode\\n        )\\n    {\\n        bytes memory encoded = _value.length < 32 ? _value : Lib_RLPWriter.writeBytes(_value);\\n        _branch.decoded[_index] = Lib_RLPReader.toRLPItem(encoded);\\n        return _makeNode(_branch.decoded);\\n    }\\n\\n    /**\\n     * @notice Utility; adds a prefix to a key.\\n     * @param _key Key to prefix.\\n     * @param _isLeaf Whether or not the key belongs to a leaf.\\n     * @return _prefixedKey Prefixed key.\\n     */\\n    function _addHexPrefix(\\n        bytes memory _key,\\n        bool _isLeaf\\n    )\\n        private\\n        pure\\n        returns (\\n            bytes memory _prefixedKey\\n        )\\n    {\\n        uint8 prefix = _isLeaf ? uint8(0x02) : uint8(0x00);\\n        uint8 offset = uint8(_key.length % 2);\\n        bytes memory prefixed = new bytes(2 - offset);\\n        prefixed[0] = bytes1(prefix + offset);\\n        return Lib_BytesUtils.concat(prefixed, _key);\\n    }\\n\\n    /**\\n     * @notice Utility; removes a prefix from a path.\\n     * @param _path Path to remove the prefix from.\\n     * @return _unprefixedKey Unprefixed key.\\n     */\\n    function _removeHexPrefix(\\n        bytes memory _path\\n    )\\n        private\\n        pure\\n        returns (\\n            bytes memory _unprefixedKey\\n        )\\n    {\\n        if (uint8(_path[0]) % 2 == 0) {\\n            return Lib_BytesUtils.slice(_path, 2);\\n        } else {\\n            return Lib_BytesUtils.slice(_path, 1);\\n        }\\n    }\\n\\n    /**\\n     * @notice Utility; combines two node arrays. Array lengths are required\\n     * because the actual lengths may be longer than the filled lengths.\\n     * Array resizing is extremely costly and should be avoided.\\n     * @param _a First array to join.\\n     * @param _aLength Length of the first array.\\n     * @param _b Second array to join.\\n     * @param _bLength Length of the second array.\\n     * @return _joined Combined node array.\\n     */\\n    function _joinNodeArrays(\\n        TrieNode[] memory _a,\\n        uint256 _aLength,\\n        TrieNode[] memory _b,\\n        uint256 _bLength\\n    )\\n        private\\n        pure\\n        returns (\\n            TrieNode[] memory _joined\\n        )\\n    {\\n        TrieNode[] memory ret = new TrieNode[](_aLength + _bLength);\\n\\n        // Copy elements from the first array.\\n        for (uint256 i = 0; i < _aLength; i++) {\\n            ret[i] = _a[i];\\n        }\\n\\n        // Copy elements from the second array.\\n        for (uint256 i = 0; i < _bLength; i++) {\\n            ret[i + _aLength] = _b[i];\\n        }\\n\\n        return ret;\\n    }\\n}\\n\",\"keccak256\":\"0xe84d904dcf0c03d5ebd0792c3aee70bf32e94513f3d3ac3636b53937116efd49\",\"license\":\"MIT\"},\"contracts/optimistic-ethereum/libraries/trie/Lib_SecureMerkleTrie.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >0.5.0 <0.8.0;\\npragma experimental ABIEncoderV2;\\n\\n/* Library Imports */\\nimport { Lib_MerkleTrie } from \\\"./Lib_MerkleTrie.sol\\\";\\n\\n/**\\n * @title Lib_SecureMerkleTrie\\n */\\nlibrary Lib_SecureMerkleTrie {\\n\\n    /**********************\\n     * Internal Functions *\\n     **********************/\\n\\n    /**\\n     * @notice Verifies a proof that a given key/value pair is present in the\\n     * Merkle trie.\\n     * @param _key Key of the node to search for, as a hex string.\\n     * @param _value Value of the node to search for, as a hex string.\\n     * @param _proof Merkle trie inclusion proof for the desired node. Unlike\\n     * traditional Merkle trees, this proof is executed top-down and consists\\n     * of a list of RLP-encoded nodes that make a path down to the target node.\\n     * @param _root Known root of the Merkle trie. Used to verify that the\\n     * included proof is correctly constructed.\\n     * @return _verified `true` if the k/v pair exists in the trie, `false` otherwise.\\n     */\\n    function verifyInclusionProof(\\n        bytes memory _key,\\n        bytes memory _value,\\n        bytes memory _proof,\\n        bytes32 _root\\n    )\\n        internal\\n        pure\\n        returns (\\n            bool _verified\\n        )\\n    {\\n        bytes memory key = _getSecureKey(_key);\\n        return Lib_MerkleTrie.verifyInclusionProof(key, _value, _proof, _root);\\n    }\\n\\n    /**\\n     * @notice Verifies a proof that a given key is *not* present in\\n     * the Merkle trie.\\n     * @param _key Key of the node to search for, as a hex string.\\n     * @param _proof Merkle trie inclusion proof for the node *nearest* the\\n     * target node.\\n     * @param _root Known root of the Merkle trie. Used to verify that the\\n     * included proof is correctly constructed.\\n     * @return _verified `true` if the key is not present in the trie, `false` otherwise.\\n     */\\n    function verifyExclusionProof(\\n        bytes memory _key,\\n        bytes memory _proof,\\n        bytes32 _root\\n    )\\n        internal\\n        pure\\n        returns (\\n            bool _verified\\n        )\\n    {\\n        bytes memory key = _getSecureKey(_key);\\n        return Lib_MerkleTrie.verifyExclusionProof(key, _proof, _root);\\n    }\\n\\n    /**\\n     * @notice Updates a Merkle trie and returns a new root hash.\\n     * @param _key Key of the node to update, as a hex string.\\n     * @param _value Value of the node to update, as a hex string.\\n     * @param _proof Merkle trie inclusion proof for the node *nearest* the\\n     * target node. If the key exists, we can simply update the value.\\n     * Otherwise, we need to modify the trie to handle the new k/v pair.\\n     * @param _root Known root of the Merkle trie. Used to verify that the\\n     * included proof is correctly constructed.\\n     * @return _updatedRoot Root hash of the newly constructed trie.\\n     */\\n    function update(\\n        bytes memory _key,\\n        bytes memory _value,\\n        bytes memory _proof,\\n        bytes32 _root\\n    )\\n        internal\\n        pure\\n        returns (\\n            bytes32 _updatedRoot\\n        )\\n    {\\n        bytes memory key = _getSecureKey(_key);\\n        return Lib_MerkleTrie.update(key, _value, _proof, _root);\\n    }\\n\\n    /**\\n     * @notice Retrieves the value associated with a given key.\\n     * @param _key Key to search for, as hex bytes.\\n     * @param _proof Merkle trie inclusion proof for the key.\\n     * @param _root Known root of the Merkle trie.\\n     * @return _exists Whether or not the key exists.\\n     * @return _value Value of the key if it exists.\\n     */\\n    function get(\\n        bytes memory _key,\\n        bytes memory _proof,\\n        bytes32 _root\\n    )\\n        internal\\n        pure\\n        returns (\\n            bool _exists,\\n            bytes memory _value\\n        )\\n    {\\n        bytes memory key = _getSecureKey(_key);\\n        return Lib_MerkleTrie.get(key, _proof, _root);\\n    }\\n\\n    /**\\n     * Computes the root hash for a trie with a single node.\\n     * @param _key Key for the single node.\\n     * @param _value Value for the single node.\\n     * @return _updatedRoot Hash of the trie.\\n     */\\n    function getSingleNodeRootHash(\\n        bytes memory _key,\\n        bytes memory _value\\n    )\\n        internal\\n        pure\\n        returns (\\n            bytes32 _updatedRoot\\n        )\\n    {\\n        bytes memory key = _getSecureKey(_key);\\n        return Lib_MerkleTrie.getSingleNodeRootHash(key, _value);\\n    }\\n\\n\\n    /*********************\\n     * Private Functions *\\n     *********************/\\n\\n    /**\\n     * Computes the secure counterpart to a key.\\n     * @param _key Key to get a secure key from.\\n     * @return _secureKey Secure version of the key.\\n     */\\n    function _getSecureKey(\\n        bytes memory _key\\n    )\\n        private\\n        pure\\n        returns (\\n            bytes memory _secureKey\\n        )\\n    {\\n        return abi.encodePacked(keccak256(_key));\\n    }\\n}\",\"keccak256\":\"0x79355346f74bb1eb9eeb733cb5d9677d50115c4f390307cbf608fe071a1ada0c\",\"license\":\"MIT\"},\"contracts/optimistic-ethereum/libraries/utils/Lib_Bytes32Utils.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.7.0;\\n\\n/**\\n * @title Lib_Byte32Utils\\n */\\nlibrary Lib_Bytes32Utils {\\n\\n    /**********************\\n     * Internal Functions *\\n     **********************/\\n\\n    function toBool(\\n        bytes32 _in\\n    )\\n        internal\\n        pure\\n        returns (\\n            bool _out\\n        )\\n    {\\n        return _in != 0;\\n    }\\n\\n    function fromBool(\\n        bool _in\\n    )\\n        internal\\n        pure\\n        returns (\\n            bytes32 _out\\n        )\\n    {\\n        return bytes32(uint256(_in ? 1 : 0));\\n    }\\n\\n    function toAddress(\\n        bytes32 _in\\n    )\\n        internal\\n        pure\\n        returns (\\n            address _out\\n        )\\n    {\\n        return address(uint160(uint256(_in)));\\n    }\\n\\n    function fromAddress(\\n        address _in\\n    )\\n        internal\\n        pure\\n        returns (\\n            bytes32 _out\\n        )\\n    {\\n        return bytes32(uint256(_in));\\n    }\\n\\n    function removeLeadingZeros(\\n        bytes32 _in\\n    )\\n        internal\\n        pure\\n        returns (\\n            bytes memory _out\\n        )\\n    {\\n        bytes memory out;\\n\\n        assembly {\\n            // Figure out how many leading zero bytes to remove.\\n            let shift := 0\\n            for { let i := 0 } and(lt(i, 32), eq(byte(i, _in), 0)) { i := add(i, 1) } {\\n                shift := add(shift, 1)\\n            }\\n\\n            // Reserve some space for our output and fix the free memory pointer.\\n            out := mload(0x40)\\n            mstore(0x40, add(out, 0x40))\\n\\n            // Shift the value and store it into the output bytes.\\n            mstore(add(out, 0x20), shl(mul(shift, 8), _in))\\n\\n            // Store the new size (with leading zero bytes removed) in the output byte size.\\n            mstore(out, sub(32, shift))\\n        }\\n\\n        return out;\\n    }\\n}\\n\",\"keccak256\":\"0x06f97590a80a01daa3bf6aa795449aea91a78684c646b4a6caeece8ef919c80c\",\"license\":\"MIT\"},\"contracts/optimistic-ethereum/libraries/utils/Lib_BytesUtils.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.7.0;\\n\\n/**\\n * @title Lib_BytesUtils\\n */\\nlibrary Lib_BytesUtils {\\n\\n    /**********************\\n     * Internal Functions *\\n     **********************/\\n\\n    function concat(\\n        bytes memory _preBytes,\\n        bytes memory _postBytes\\n    )\\n        internal\\n        pure\\n        returns (bytes memory)\\n    {\\n        bytes memory tempBytes;\\n\\n        assembly {\\n            // Get a location of some free memory and store it in tempBytes as\\n            // Solidity does for memory variables.\\n            tempBytes := mload(0x40)\\n\\n            // Store the length of the first bytes array at the beginning of\\n            // the memory for tempBytes.\\n            let length := mload(_preBytes)\\n            mstore(tempBytes, length)\\n\\n            // Maintain a memory counter for the current write location in the\\n            // temp bytes array by adding the 32 bytes for the array length to\\n            // the starting location.\\n            let mc := add(tempBytes, 0x20)\\n            // Stop copying when the memory counter reaches the length of the\\n            // first bytes array.\\n            let end := add(mc, length)\\n\\n            for {\\n                // Initialize a copy counter to the start of the _preBytes data,\\n                // 32 bytes into its memory.\\n                let cc := add(_preBytes, 0x20)\\n            } lt(mc, end) {\\n                // Increase both counters by 32 bytes each iteration.\\n                mc := add(mc, 0x20)\\n                cc := add(cc, 0x20)\\n            } {\\n                // Write the _preBytes data into the tempBytes memory 32 bytes\\n                // at a time.\\n                mstore(mc, mload(cc))\\n            }\\n\\n            // Add the length of _postBytes to the current length of tempBytes\\n            // and store it as the new length in the first 32 bytes of the\\n            // tempBytes memory.\\n            length := mload(_postBytes)\\n            mstore(tempBytes, add(length, mload(tempBytes)))\\n\\n            // Move the memory counter back from a multiple of 0x20 to the\\n            // actual end of the _preBytes data.\\n            mc := end\\n            // Stop copying when the memory counter reaches the new combined\\n            // length of the arrays.\\n            end := add(mc, length)\\n\\n            for {\\n                let cc := add(_postBytes, 0x20)\\n            } lt(mc, end) {\\n                mc := add(mc, 0x20)\\n                cc := add(cc, 0x20)\\n            } {\\n                mstore(mc, mload(cc))\\n            }\\n\\n            // Update the free-memory pointer by padding our last write location\\n            // to 32 bytes: add 31 bytes to the end of tempBytes to move to the\\n            // next 32 byte block, then round down to the nearest multiple of\\n            // 32. If the sum of the length of the two arrays is zero then add\\n            // one before rounding down to leave a blank 32 bytes (the length block with 0).\\n            mstore(0x40, 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        return tempBytes;\\n    }\\n\\n    function slice(\\n        bytes memory _bytes,\\n        uint256 _start,\\n        uint256 _length\\n    )\\n        internal\\n        pure\\n        returns (bytes memory)\\n    {\\n        require(_length + 31 >= _length, \\\"slice_overflow\\\");\\n        require(_start + _length >= _start, \\\"slice_overflow\\\");\\n        require(_bytes.length >= _start + _length, \\\"slice_outOfBounds\\\");\\n\\n        bytes memory tempBytes;\\n\\n        assembly {\\n            switch iszero(_length)\\n            case 0 {\\n                // Get a location of some free memory and store it in tempBytes as\\n                // Solidity does for memory variables.\\n                tempBytes := mload(0x40)\\n\\n                // The first word of the slice result is potentially a partial\\n                // word read from the original array. To read it, we calculate\\n                // the length of that partial word and start copying that many\\n                // bytes into the array. The first word we copy will start with\\n                // data we don't care about, but the last `lengthmod` bytes will\\n                // land at the beginning of the contents of the new array. When\\n                // we're done copying, we overwrite the full first word with\\n                // the actual length of the slice.\\n                let lengthmod := and(_length, 31)\\n\\n                // The multiplication in the next line is necessary\\n                // because when slicing multiples of 32 bytes (lengthmod == 0)\\n                // the following copy loop was copying the origin's length\\n                // and then ending prematurely not copying everything it should.\\n                let mc := add(add(tempBytes, lengthmod), mul(0x20, iszero(lengthmod)))\\n                let end := add(mc, _length)\\n\\n                for {\\n                    // The multiplication in the next line has the same exact purpose\\n                    // as the one above.\\n                    let cc := add(add(add(_bytes, lengthmod), mul(0x20, iszero(lengthmod))), _start)\\n                } lt(mc, end) {\\n                    mc := add(mc, 0x20)\\n                    cc := add(cc, 0x20)\\n                } {\\n                    mstore(mc, mload(cc))\\n                }\\n\\n                mstore(tempBytes, _length)\\n\\n                //update free-memory pointer\\n                //allocating the array padded to 32 bytes like the compiler does now\\n                mstore(0x40, and(add(mc, 31), not(31)))\\n            }\\n            //if we want a zero-length slice let's just return a zero-length array\\n            default {\\n                tempBytes := mload(0x40)\\n\\n                //zero out the 32 bytes slice we are about to return\\n                //we need to do it because Solidity does not garbage collect\\n                mstore(tempBytes, 0)\\n\\n                mstore(0x40, add(tempBytes, 0x20))\\n            }\\n        }\\n\\n        return tempBytes;\\n    }\\n\\n    function slice(\\n        bytes memory _bytes,\\n        uint256 _start\\n    )\\n        internal\\n        pure\\n        returns (bytes memory)\\n    {\\n        if (_bytes.length - _start == 0) {\\n            return bytes('');\\n        }\\n\\n        return slice(_bytes, _start, _bytes.length - _start);\\n    }\\n\\n    function toBytes32PadLeft(\\n        bytes memory _bytes\\n    )\\n        internal\\n        pure\\n        returns (bytes32)\\n    {\\n        bytes32 ret;\\n        uint256 len = _bytes.length <= 32 ? _bytes.length : 32;\\n        assembly {\\n            ret := shr(mul(sub(32, len), 8), mload(add(_bytes, 32)))\\n        }\\n        return ret;\\n    }\\n\\n    function toBytes32(\\n        bytes memory _bytes\\n    )\\n        internal\\n        pure\\n        returns (bytes32)\\n    {\\n        if (_bytes.length < 32) {\\n            bytes32 ret;\\n            assembly {\\n                ret := mload(add(_bytes, 32))\\n            }\\n            return ret;\\n        }\\n\\n        return abi.decode(_bytes,(bytes32)); // will truncate if input length > 32 bytes\\n    }\\n\\n    function toUint256(\\n        bytes memory _bytes\\n    )\\n        internal\\n        pure\\n        returns (uint256)\\n    {\\n        return uint256(toBytes32(_bytes));\\n    }\\n\\n    function toUint24(bytes memory _bytes, uint256 _start) internal pure returns (uint24) {\\n        require(_start + 3 >= _start, \\\"toUint24_overflow\\\");\\n        require(_bytes.length >= _start + 3 , \\\"toUint24_outOfBounds\\\");\\n        uint24 tempUint;\\n\\n        assembly {\\n            tempUint := mload(add(add(_bytes, 0x3), _start))\\n        }\\n\\n        return tempUint;\\n    }\\n\\n    function toUint8(bytes memory _bytes, uint256 _start) internal pure returns (uint8) {\\n        require(_start + 1 >= _start, \\\"toUint8_overflow\\\");\\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 toAddress(bytes memory _bytes, uint256 _start) internal pure returns (address) {\\n        require(_start + 20 >= _start, \\\"toAddress_overflow\\\");\\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 toNibbles(\\n        bytes memory _bytes\\n    )\\n        internal\\n        pure\\n        returns (bytes memory)\\n    {\\n        bytes memory nibbles = new bytes(_bytes.length * 2);\\n\\n        for (uint256 i = 0; i < _bytes.length; i++) {\\n            nibbles[i * 2] = _bytes[i] >> 4;\\n            nibbles[i * 2 + 1] = bytes1(uint8(_bytes[i]) % 16);\\n        }\\n\\n        return nibbles;\\n    }\\n\\n    function fromNibbles(\\n        bytes memory _bytes\\n    )\\n        internal\\n        pure\\n        returns (bytes memory)\\n    {\\n        bytes memory ret = new bytes(_bytes.length / 2);\\n\\n        for (uint256 i = 0; i < ret.length; i++) {\\n            ret[i] = (_bytes[i * 2] << 4) | (_bytes[i * 2 + 1]);\\n        }\\n\\n        return ret;\\n    }\\n\\n    function equal(\\n        bytes memory _bytes,\\n        bytes memory _other\\n    )\\n        internal\\n        pure\\n        returns (bool)\\n    {\\n        return keccak256(_bytes) == keccak256(_other);\\n    }\\n}\\n\",\"keccak256\":\"0x849e4fedd81cd260e4c3b74b953f00636323574c60d363f36ab331e94aab9219\",\"license\":\"MIT\"},\"contracts/optimistic-ethereum/libraries/utils/Lib_ReentrancyGuard.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// +build ovm\\npragma solidity >0.5.0 <0.8.0;\\n\\n/**\\n * @dev Contract module that helps prevent reentrant calls to a function.\\n *\\n * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier\\n * available, which can be applied to functions to make sure there are no nested\\n * (reentrant) calls to them.\\n *\\n * Note that because there is a single `nonReentrant` guard, functions marked as\\n * `nonReentrant` may not call one another. This can be worked around by making\\n * those functions `private`, and then adding `external` `nonReentrant` entry\\n * points to them.\\n *\\n * TIP: If you would like to learn more about reentrancy and alternative ways\\n * to protect against it, check out our blog post\\n * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].\\n */\\nabstract contract Lib_ReentrancyGuard {\\n    // Booleans are more expensive than uint256 or any type that takes up a full\\n    // word because each write operation emits an extra SLOAD to first read the\\n    // slot's contents, replace the bits taken up by the boolean, and then write\\n    // back. This is the compiler's defense against contract upgrades and\\n    // pointer aliasing, and it cannot be disabled.\\n\\n    // The values being non-zero value makes deployment a bit more expensive,\\n    // but in exchange the refund on every call to nonReentrant will be lower in\\n    // amount. Since refunds are capped to a percentage of the total\\n    // transaction's gas, it is best to keep them low in cases like this one, to\\n    // increase the likelihood of the full refund coming into effect.\\n    uint256 private constant _NOT_ENTERED = 1;\\n    uint256 private constant _ENTERED = 2;\\n\\n    uint256 private _status;\\n\\n    constructor () internal {\\n        _status = _NOT_ENTERED;\\n    }\\n\\n    /**\\n     * @dev Prevents a contract from calling itself, directly or indirectly.\\n     * Calling a `nonReentrant` function from another `nonReentrant`\\n     * function is not supported. It is possible to prevent this from happening\\n     * by making the `nonReentrant` function external, and make it call a\\n     * `private` function that does the actual work.\\n     */\\n    modifier nonReentrant() {\\n        // On the first call to nonReentrant, _notEntered will be true\\n        require(_status != _ENTERED, \\\"ReentrancyGuard: reentrant call\\\");\\n\\n        // Any calls to nonReentrant after this point will fail\\n        _status = _ENTERED;\\n\\n        _;\\n\\n        // By storing the original value once again, a refund is triggered (see\\n        // https://eips.ethereum.org/EIPS/eip-2200)\\n        _status = _NOT_ENTERED;\\n    }\\n}\\n\",\"keccak256\":\"0x8cb909f4039d8d9770578c6c469e8f3cfcbb6088c209ce663742c023920af9c1\",\"license\":\"MIT\"},\"contracts/optimistic-ethereum/libraries/wrappers/Lib_SafeExecutionManagerWrapper.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.7.0;\\n\\n/**\\n * @title Lib_SafeExecutionManagerWrapper\\n */\\nlibrary Lib_SafeExecutionManagerWrapper {\\n\\n    /**********************\\n     * Internal Functions *\\n     **********************/\\n\\n    /**\\n     * Makes an ovmCALL and performs all the necessary safety checks.\\n     * @param _gasLimit Gas limit for the call.\\n     * @param _target Address to call.\\n     * @param _calldata Data to send to the call.\\n     * @return _success Whether or not the call reverted.\\n     * @return _returndata Data returned by the call.\\n     */\\n    function safeCALL(\\n        uint256 _gasLimit,\\n        address _target,\\n        bytes memory _calldata\\n    )\\n        internal\\n        returns (\\n            bool _success,\\n            bytes memory _returndata\\n        )\\n    {\\n        bytes memory returndata = _safeExecutionManagerInteraction(\\n            abi.encodeWithSignature(\\n                \\\"ovmCALL(uint256,address,bytes)\\\",\\n                _gasLimit,\\n                _target,\\n                _calldata\\n            )\\n        );\\n\\n        return abi.decode(returndata, (bool, bytes));\\n    }\\n\\n    /**\\n     * Makes an ovmCALL and performs all the necessary safety checks.\\n     * @param _gasLimit Gas limit for the call.\\n     * @param _target Address to call.\\n     * @param _calldata Data to send to the call.\\n     * @return _success Whether or not the call reverted.\\n     * @return _returndata Data returned by the call.\\n     */\\n    function safeDELEGATECALL(\\n        uint256 _gasLimit,\\n        address _target,\\n        bytes memory _calldata\\n    )\\n        internal\\n        returns (\\n            bool _success,\\n            bytes memory _returndata\\n        )\\n    {\\n        bytes memory returndata = _safeExecutionManagerInteraction(\\n            abi.encodeWithSignature(\\n                \\\"ovmDELEGATECALL(uint256,address,bytes)\\\",\\n                _gasLimit,\\n                _target,\\n                _calldata\\n            )\\n        );\\n\\n        return abi.decode(returndata, (bool, bytes));\\n    }\\n\\n    /**\\n     * Performs an ovmCREATE and the necessary safety checks.\\n     * @param _gasLimit Gas limit for the creation.\\n     * @param _bytecode Code for the new contract.\\n     * @return _contract Address of the created contract.\\n     */\\n    function safeCREATE(\\n        uint256 _gasLimit,\\n        bytes memory _bytecode\\n    )\\n        internal\\n        returns (\\n            address _contract\\n        )\\n    {\\n        bytes memory returndata = _safeExecutionManagerInteraction(\\n            _gasLimit,\\n            abi.encodeWithSignature(\\n                \\\"ovmCREATE(bytes)\\\",\\n                _bytecode\\n            )\\n        );\\n\\n        return abi.decode(returndata, (address));\\n    }\\n\\n    /**\\n     * Performs an ovmEXTCODESIZE and the necessary safety checks.\\n     * @param _contract Address of the contract to query the size of.\\n     * @return _EXTCODESIZE Size of the requested contract in bytes.\\n     */\\n    function safeEXTCODESIZE(\\n        address _contract\\n    )\\n        internal\\n        returns (\\n            uint256 _EXTCODESIZE\\n        )\\n    {\\n        bytes memory returndata = _safeExecutionManagerInteraction(\\n            abi.encodeWithSignature(\\n                \\\"ovmEXTCODESIZE(address)\\\",\\n                _contract\\n            )\\n        );\\n\\n        return abi.decode(returndata, (uint256));\\n    }\\n\\n    /**\\n     * Performs a safe ovmCHAINID call.\\n     * @return _CHAINID Result of calling ovmCHAINID.\\n     */\\n    function safeCHAINID()\\n        internal\\n        returns (\\n            uint256 _CHAINID\\n        )\\n    {\\n        bytes memory returndata = _safeExecutionManagerInteraction(\\n            abi.encodeWithSignature(\\n                \\\"ovmCHAINID()\\\"\\n            )\\n        );\\n\\n        return abi.decode(returndata, (uint256));\\n    }\\n\\n    /**\\n     * Performs a safe ovmCALLER call.\\n     * @return _CALLER Result of calling ovmCALLER.\\n     */\\n    function safeCALLER()\\n        internal\\n        returns (\\n            address _CALLER\\n        )\\n    {\\n        bytes memory returndata = _safeExecutionManagerInteraction(\\n            abi.encodeWithSignature(\\n                \\\"ovmCALLER()\\\"\\n            )\\n        );\\n\\n        return abi.decode(returndata, (address));\\n    }\\n\\n    /**\\n     * Performs a safe ovmADDRESS call.\\n     * @return _ADDRESS Result of calling ovmADDRESS.\\n     */\\n    function safeADDRESS()\\n        internal\\n        returns (\\n            address _ADDRESS\\n        )\\n    {\\n        bytes memory returndata = _safeExecutionManagerInteraction(\\n            abi.encodeWithSignature(\\n                \\\"ovmADDRESS()\\\"\\n            )\\n        );\\n\\n        return abi.decode(returndata, (address));\\n    }\\n\\n    /**\\n     * Performs a safe ovmGETNONCE call.\\n     * @return _nonce Result of calling ovmGETNONCE.\\n     */\\n    function safeGETNONCE()\\n        internal\\n        returns (\\n            uint256 _nonce\\n        )\\n    {\\n        bytes memory returndata = _safeExecutionManagerInteraction(\\n            abi.encodeWithSignature(\\n                \\\"ovmGETNONCE()\\\"\\n            )\\n        );\\n\\n        return abi.decode(returndata, (uint256));\\n    }\\n\\n    /**\\n     * Performs a safe ovmSETNONCE call.\\n     * @param _nonce New account nonce.\\n     */\\n    function safeSETNONCE(\\n        uint256 _nonce\\n    )\\n        internal\\n    {\\n        _safeExecutionManagerInteraction(\\n            abi.encodeWithSignature(\\n                \\\"ovmSETNONCE(uint256)\\\",\\n                _nonce\\n            )\\n        );\\n    }\\n\\n    /**\\n     * Performs a safe ovmCREATEEOA call.\\n     * @param _messageHash Message hash which was signed by EOA\\n     * @param _v v value of signature (0 or 1)\\n     * @param _r r value of signature\\n     * @param _s s value of signature\\n     */\\n    function safeCREATEEOA(\\n        bytes32 _messageHash,\\n        uint8 _v,\\n        bytes32 _r,\\n        bytes32 _s\\n    )\\n        internal\\n    {\\n        _safeExecutionManagerInteraction(\\n            abi.encodeWithSignature(\\n                \\\"ovmCREATEEOA(bytes32,uint8,bytes32,bytes32)\\\",\\n                _messageHash,\\n                _v,\\n                _r,\\n                _s\\n            )\\n        );\\n    }\\n\\n    /**\\n     * Performs a safe REVERT.\\n     * @param _reason String revert reason to pass along with the REVERT.\\n     */\\n    function safeREVERT(\\n        string memory _reason\\n    )\\n        internal\\n    {\\n        _safeExecutionManagerInteraction(\\n            abi.encodeWithSignature(\\n                \\\"ovmREVERT(bytes)\\\",\\n                bytes(_reason)\\n            )\\n        );\\n    }\\n\\n    /**\\n     * Performs a safe \\\"require\\\".\\n     * @param _condition Boolean condition that must be true or will revert.\\n     * @param _reason String revert reason to pass along with the REVERT.\\n     */\\n    function safeREQUIRE(\\n        bool _condition,\\n        string memory _reason\\n    )\\n        internal\\n    {\\n        if (!_condition) {\\n            safeREVERT(\\n                _reason\\n            );\\n        }\\n    }\\n\\n    /**\\n     * Performs a safe ovmSLOAD call.\\n     */\\n    function safeSLOAD(\\n        bytes32 _key\\n    )\\n        internal\\n        returns (\\n            bytes32\\n        )\\n    {\\n        bytes memory returndata = _safeExecutionManagerInteraction(\\n            abi.encodeWithSignature(\\n                \\\"ovmSLOAD(bytes32)\\\",\\n                _key\\n            )\\n        );\\n\\n        return abi.decode(returndata, (bytes32));\\n    }\\n\\n    /**\\n     * Performs a safe ovmSSTORE call.\\n     */\\n    function safeSSTORE(\\n        bytes32 _key,\\n        bytes32 _value\\n    )\\n        internal\\n    {\\n        _safeExecutionManagerInteraction(\\n            abi.encodeWithSignature(\\n                \\\"ovmSSTORE(bytes32,bytes32)\\\",\\n                _key,\\n                _value\\n            )\\n        );\\n    }\\n\\n    /*********************\\n     * Private Functions *\\n     *********************/\\n\\n    /**\\n     * Performs an ovm interaction and the necessary safety checks.\\n     * @param _gasLimit Gas limit for the interaction.\\n     * @param _calldata Data to send to the OVM_ExecutionManager (encoded with sighash).\\n     * @return _returndata Data sent back by the OVM_ExecutionManager.\\n     */\\n    function _safeExecutionManagerInteraction(\\n        uint256 _gasLimit,\\n        bytes memory _calldata\\n    )\\n        private\\n        returns (\\n            bytes memory _returndata\\n        )\\n    {\\n        address ovmExecutionManager = msg.sender;\\n        (\\n            bool success,\\n            bytes memory returndata\\n        ) = ovmExecutionManager.call{gas: _gasLimit}(_calldata);\\n\\n        if (success == false) {\\n            assembly {\\n                revert(add(returndata, 0x20), mload(returndata))\\n            }\\n        } else if (returndata.length == 1) {\\n            assembly {\\n                return(0, 1)\\n            }\\n        } else {\\n            return returndata;\\n        }\\n    }\\n\\n    function _safeExecutionManagerInteraction(\\n        bytes memory _calldata\\n    )\\n        private\\n        returns (\\n            bytes memory _returndata\\n        )\\n    {\\n        return _safeExecutionManagerInteraction(\\n            gasleft(),\\n            _calldata\\n        );\\n    }\\n}\\n\",\"keccak256\":\"0xdc30487ca1580f3498d4a1c4e26dc53158c00b44bd72da212a66267c22a139b0\",\"license\":\"MIT\"}},\"version\":1}",
  "bytecode": "[encoded data, 19448 characters]",
  "deployedBytecode": "[encoded data, 19342 characters]",
  "devdoc": {
    "details": "This contract lives on L1. It sends L1->L2 messages into L2, and relays L2->L1 messages from L2 to their target on L1.",
    "kind": "dev",
    "methods": {
      "initialize(address)": {
        "params": {
          "_libAddressManager": "Address of the Address Manager."
        }
      },
      "relayMessage(address,address,bytes,uint256,(bytes32,(uint256,bytes32,uint256,uint256,bytes),(uint256,bytes32[]),bytes,bytes))": {
        "params": {
          "_message": "Message to send to the target.",
          "_messageNonce": "Nonce for the provided message.",
          "_proof": "Inclusion proof for the given message.",
          "_sender": "Message sender address.",
          "_target": "Target contract address."
        }
      },
      "replayMessage(address,address,bytes,uint256,uint32)": {
        "params": {
          "_gasLimit": "Gas limit for the provided message.",
          "_message": "Message to send to the target.",
          "_messageNonce": "Nonce for the provided message.",
          "_sender": "Original sender address.",
          "_target": "Target contract address."
        }
      },
      "sendMessage(address,bytes,uint32)": {
        "params": {
          "_gasLimit": "Gas limit for the provided message.",
          "_message": "Message to send to the target.",
          "_target": "Target contract address."
        }
      }
    },
    "title": "OVM_L1CrossDomainMessenger",
    "version": 1
  },
  "userdoc": {
    "kind": "user",
    "methods": {
      "constructor": {
        "notice": "Pass a default zero address to the address resolver. This will be updated when initialized."
      },
      "relayMessage(address,address,bytes,uint256,(bytes32,(uint256,bytes32,uint256,uint256,bytes),(uint256,bytes32[]),bytes,bytes))": {
        "notice": "Relays a cross domain message to a contract."
      },
      "replayMessage(address,address,bytes,uint256,uint32)": {
        "notice": "Replays a cross domain message to the target messenger."
      },
      "sendMessage(address,bytes,uint32)": {
        "notice": "Sends a cross domain message to the target messenger."
      }
    },
    "version": 1
  },
  "storageLayout": {
    "storage": [
      {
        "astId": 16313,
        "contract": "contracts/optimistic-ethereum/OVM/bridge/OVM_L1CrossDomainMessenger.sol:OVM_L1CrossDomainMessenger",
        "label": "_status",
        "offset": 0,
        "slot": "0",
        "type": "t_uint256"
      },
      {
        "astId": 679,
        "contract": "contracts/optimistic-ethereum/OVM/bridge/OVM_L1CrossDomainMessenger.sol:OVM_L1CrossDomainMessenger",
        "label": "relayedMessages",
        "offset": 0,
        "slot": "1",
        "type": "t_mapping(t_bytes32,t_bool)"
      },
      {
        "astId": 683,
        "contract": "contracts/optimistic-ethereum/OVM/bridge/OVM_L1CrossDomainMessenger.sol:OVM_L1CrossDomainMessenger",
        "label": "successfulMessages",
        "offset": 0,
        "slot": "2",
        "type": "t_mapping(t_bytes32,t_bool)"
      },
      {
        "astId": 687,
        "contract": "contracts/optimistic-ethereum/OVM/bridge/OVM_L1CrossDomainMessenger.sol:OVM_L1CrossDomainMessenger",
        "label": "sentMessages",
        "offset": 0,
        "slot": "3",
        "type": "t_mapping(t_bytes32,t_bool)"
      },
      {
        "astId": 689,
        "contract": "contracts/optimistic-ethereum/OVM/bridge/OVM_L1CrossDomainMessenger.sol:OVM_L1CrossDomainMessenger",
        "label": "messageNonce",
        "offset": 0,
        "slot": "4",
        "type": "t_uint256"
      },
      {
        "astId": 692,
        "contract": "contracts/optimistic-ethereum/OVM/bridge/OVM_L1CrossDomainMessenger.sol:OVM_L1CrossDomainMessenger",
        "label": "xDomainMessageSender",
        "offset": 0,
        "slot": "5",
        "type": "t_address"
      },
      {
        "astId": 11707,
        "contract": "contracts/optimistic-ethereum/OVM/bridge/OVM_L1CrossDomainMessenger.sol:OVM_L1CrossDomainMessenger",
        "label": "libAddressManager",
        "offset": 0,
        "slot": "6",
        "type": "t_contract(Lib_AddressManager)11700"
      }
    ],
    "types": {
      "t_address": {
        "encoding": "inplace",
        "label": "address",
        "numberOfBytes": "20"
      },
      "t_bool": {
        "encoding": "inplace",
        "label": "bool",
        "numberOfBytes": "1"
      },
      "t_bytes32": {
        "encoding": "inplace",
        "label": "bytes32",
        "numberOfBytes": "32"
      },
      "t_contract(Lib_AddressManager)11700": {
        "encoding": "inplace",
        "label": "contract Lib_AddressManager",
        "numberOfBytes": "20"
      },
      "t_mapping(t_bytes32,t_bool)": {
        "encoding": "mapping",
        "key": "t_bytes32",
        "label": "mapping(bytes32 => bool)",
        "numberOfBytes": "32",
        "value": "t_bool"
      },
      "t_uint256": {
        "encoding": "inplace",
        "label": "uint256",
        "numberOfBytes": "32"
      }
    }
  }
}