creation_sourcecode: {{
    "language": "Solidity",
    "sources": {
      "contracts/BL/rollup/MessageQueue.sol": {
        "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.9;\n\n/* Library Imports */\nimport { AddressAliasHelper } from \"../../standards/AddressAliasHelper.sol\";\nimport { Lib_NVMCodec } from \"../../libraries/codec/Lib_NVMCodec.sol\";\nimport { Lib_AddressResolver } from \"../../libraries/resolver/Lib_AddressResolver.sol\";\n\n/* Interface Imports */\nimport { IMessageQueue } from \"./IMessageQueue.sol\";\nimport { Ownable } from \"@openzeppelin/contracts/access/Ownable.sol\";\n\n/**\n * @title MessageQueue\n * @dev TODO\n *\n */\ncontract MessageQueue is IMessageQueue, Lib_AddressResolver, Ownable {\n    /*************\n     * Constants *\n     *************/\n\n    // SL tx gas-related\n    uint256 public constant MIN_ROLLUP_TX_GAS = 100000;\n    uint256 public constant MAX_ROLLUP_TX_SIZE = 50000;\n    uint256 public constant SL_GAS_DISCOUNT_DIVISOR = 32;\n\n    /*************\n     * Variables *\n     *************/\n\n    uint256 public maxTransactionGasLimit;\n    bool public limitedEnqueueEnabled;\n    mapping(address => bool) public enqueuers;\n\n    /***************\n     * Queue State *\n     ***************/\n    Lib_NVMCodec.QueueElement[] queueElements;\n\n    /***************\n     * Constructor *\n     ***************/\n\n    constructor(address _libAddressManager, uint256 _maxTransactionGasLimit)\n        Lib_AddressResolver(_libAddressManager)\n    {\n        maxTransactionGasLimit = _maxTransactionGasLimit;\n    }\n\n    modifier onlyEnqueuer() {\n        if (limitedEnqueueEnabled) {\n            require(enqueuers[msg.sender], \"Account is not an enabled enqueuer\");\n        }\n        _;\n    }\n\n    /********************\n     * Public Functions *\n     ********************/\n\n    /**\n     * Gets the queue element at a particular index.\n     * @param _index Index of the queue element to access.\n     * @return _element Queue element at the given index.\n     */\n    function getQueueElement(uint256 _index)\n        public\n        view\n        returns (Lib_NVMCodec.QueueElement memory _element)\n    {\n        return queueElements[_index];\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() public view returns (uint40) {\n        return uint40(queueElements.length);\n    }\n\n    /**\n     * Adds a transaction to the queue.\n     * @param _target Target SL contract to send the transaction to.\n     * @param _gasLimit Gas limit for the enqueued SL transaction.\n     * @param _data Transaction data.\n     */\n    function enqueue(\n        address _target,\n        uint256 _gasLimit,\n        bytes memory _data\n    ) external onlyEnqueuer {\n        require(\n            _data.length <= MAX_ROLLUP_TX_SIZE,\n            \"Transaction data size exceeds maximum for rollup transaction.\"\n        );\n\n        require(\n            _gasLimit <= maxTransactionGasLimit,\n            \"Transaction gas limit exceeds maximum for rollup transaction.\"\n        );\n\n        require(_gasLimit >= MIN_ROLLUP_TX_GAS, \"Transaction gas limit too low to enqueue.\");\n\n        // Apply an aliasing unless msg.sender == tx.origin. This prevents an attack in which a\n        // contract on BL has the same address as a contract on SL but doesn't have the same code.\n        // We can safely ignore this for EOAs because they're guaranteed to have the same \"code\"\n        // (i.e. no code at all). This also makes it possible for users to interact with contracts\n        // on SL even when the Sequencer is down.\n        address sender;\n        if (msg.sender == tx.origin) {\n            sender = msg.sender;\n        } else {\n            sender = AddressAliasHelper.applyBLToSLAlias(msg.sender);\n        }\n\n        bytes32 transactionHash = keccak256(abi.encode(sender, _target, _gasLimit, _data));\n\n        queueElements.push(\n            Lib_NVMCodec.QueueElement({\n                transactionHash: transactionHash,\n                timestamp: uint40(block.timestamp),\n                blockNumber: uint40(block.number)\n            })\n        );\n        uint256 queueIndex = queueElements.length - 1;\n        emit TransactionEnqueued(sender, _target, _gasLimit, _data, queueIndex, block.timestamp);\n    }\n\n    function toggleLimitedEnqueue() external onlyOwner returns (bool) {\n        limitedEnqueueEnabled = !limitedEnqueueEnabled;\n        return limitedEnqueueEnabled;\n    }\n\n    function addEnqueuer(address _address) external onlyOwner {\n        enqueuers[_address] = true;\n    }\n\n    function removeEnqueuer(address _address) external onlyOwner {\n        enqueuers[_address] = false;\n    }\n\n    function isEnqueuer(address _address) public view returns (bool result) {\n        result = enqueuers[_address];\n    }\n}\n"
      },
      "contracts/standards/AddressAliasHelper.sol": {
        "content": "// SPDX-License-Identifier: Apache-2.0\n\n/*\n * Copyright 2019-2021, Offchain Labs, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *    http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npragma solidity ^0.8.7;\n\nlibrary AddressAliasHelper {\n    uint160 constant offset = uint160(0x1111000000000000000000000000000000001111);\n\n    /// @notice Utility function that converts the address in the BL that submitted a tx to\n    /// the inbox to the msg.sender viewed in the SL\n    /// @param blAddress the address in the BL that triggered the tx to SL\n    /// @return slAddress SL address as viewed in msg.sender\n    function applyBLToSLAlias(address blAddress) internal pure returns (address slAddress) {\n        unchecked {\n            slAddress = address(uint160(blAddress) + offset);\n        }\n    }\n\n    /// @notice Utility function that converts the msg.sender viewed in the SL to the\n    /// address in the BL that submitted a tx to the inbox\n    /// @param slAddress SL address as viewed in msg.sender\n    /// @return blAddress the address in the BL that triggered the tx to SL\n    function undoBLToSLAlias(address slAddress) internal pure returns (address blAddress) {\n        unchecked {\n            blAddress = address(uint160(slAddress) - offset);\n        }\n    }\n}\n"
      },
      "contracts/libraries/codec/Lib_NVMCodec.sol": {
        "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.9;\n\n/* Library Imports */\nimport { Lib_RLPReader } from \"../rlp/Lib_RLPReader.sol\";\nimport { Lib_RLPWriter } from \"../rlp/Lib_RLPWriter.sol\";\nimport { Lib_BytesUtils } from \"../utils/Lib_BytesUtils.sol\";\nimport { Lib_Bytes32Utils } from \"../utils/Lib_Bytes32Utils.sol\";\n\n/**\n * @title Lib_NVMCodec\n */\nlibrary Lib_NVMCodec {\n    /*********\n     * Enums *\n     *********/\n\n    enum QueueOrigin {\n        SEQUENCER_QUEUE,\n        BLTOSL_QUEUE\n    }\n\n    /***********\n     * Structs *\n     ***********/\n\n    struct EVMAccount {\n        uint256 nonce;\n        uint256 balance;\n        bytes32 storageRoot;\n        bytes32 codeHash;\n    }\n\n    struct ChainBatchHeader {\n        uint256 batchIndex;\n        bytes32 batchRoot;\n        uint256 batchSize;\n        uint256 prevTotalElements;\n        bytes extraData;\n    }\n\n    struct ChainInclusionProof {\n        uint256 index;\n        bytes32[] siblings;\n    }\n\n    struct Transaction {\n        uint256 blTimestamp;\n        uint256 blockNumber;\n        uint256 slTimestamp;\n        QueueOrigin blQueueOrigin;\n        bytes data;\n    }\n\n    struct TransactionChainElement {\n        bool isSequenced;\n        uint256 queueIndex; // QUEUED TX ONLY\n        uint256 timestamp; // SEQUENCER TX ONLY\n        uint256 blockNumber; // SEQUENCER TX ONLY\n        bytes txData; // SEQUENCER TX ONLY\n    }\n\n    struct QueueElement {\n        bytes32 transactionHash;\n        uint40 timestamp;\n        uint40 blockNumber;\n    }\n\n    struct Receipt {\n        uint256 index;\n        bytes32 stateRoot;\n        bytes32 operatorHash;\n        bytes operatorSignature;\n    }\n\n    /**********************\n     * Internal Functions *\n     **********************/\n\n    /**\n     * Encodes a standard NVM transaction.\n     * @param _transaction NVM transaction to encode.\n     * @return Encoded transaction bytes.\n     */\n    function encodeTransaction(Transaction memory _transaction)\n        internal\n        pure\n        returns (bytes memory)\n    {\n        return\n            abi.encodePacked(\n                _transaction.blTimestamp,\n                _transaction.blockNumber,\n                _transaction.slTimestamp,\n                _transaction.blQueueOrigin,\n                _transaction.data\n            );\n    }\n\n    /**\n     * Hashes a standard NVM transaction.\n     * @param _transaction NVM transaction to encode.\n     * @return Hashed transaction\n     */\n    function hashTransaction(Transaction memory _transaction) internal pure returns (bytes32) {\n        return keccak256(encodeTransaction(_transaction));\n    }\n\n    /**\n     * @notice Decodes an RLP-encoded account state into a useful struct.\n     * @param _encoded RLP-encoded account state.\n     * @return Account state struct.\n     */\n    function decodeEVMAccount(bytes memory _encoded) internal pure returns (EVMAccount memory) {\n        Lib_RLPReader.RLPItem[] memory accountState = Lib_RLPReader.readList(_encoded);\n\n        return\n            EVMAccount({\n                nonce: Lib_RLPReader.readUint256(accountState[0]),\n                balance: Lib_RLPReader.readUint256(accountState[1]),\n                storageRoot: Lib_RLPReader.readBytes32(accountState[2]),\n                codeHash: Lib_RLPReader.readBytes32(accountState[3])\n            });\n    }\n\n    /**\n     * Calculates a hash for a given batch header.\n     * @param _batchHeader Header to hash.\n     * @return Hash of the header.\n     */\n    function hashBatchHeader(Lib_NVMCodec.ChainBatchHeader memory _batchHeader)\n        internal\n        pure\n        returns (bytes32)\n    {\n        return\n            keccak256(\n                abi.encode(\n                    _batchHeader.batchRoot,\n                    _batchHeader.batchSize,\n                    _batchHeader.prevTotalElements,\n                    _batchHeader.extraData\n                )\n            );\n    }\n}\n"
      },
      "contracts/libraries/resolver/Lib_AddressResolver.sol": {
        "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.9;\n\n/* Library Imports */\nimport { Lib_AddressManager } from \"./Lib_AddressManager.sol\";\n\n/**\n * @title Lib_AddressResolver\n */\nabstract contract Lib_AddressResolver {\n    /*************\n     * Variables *\n     *************/\n\n    Lib_AddressManager public libAddressManager;\n\n    /***************\n     * Constructor *\n     ***************/\n\n    /**\n     * @param _libAddressManager Address of the Lib_AddressManager.\n     */\n    constructor(address _libAddressManager) {\n        libAddressManager = Lib_AddressManager(_libAddressManager);\n    }\n\n    /********************\n     * Public Functions *\n     ********************/\n\n    /**\n     * Resolves the address associated with a given name.\n     * @param _name Name to resolve an address for.\n     * @return Address associated with the given name.\n     */\n    function resolve(string memory _name) public view returns (address) {\n        return libAddressManager.getAddress(_name);\n    }\n}\n"
      },
      "contracts/BL/rollup/IMessageQueue.sol": {
        "content": "// SPDX-License-Identifier: MIT\npragma solidity >0.5.0 <0.9.0;\n\n/* Library Imports */\nimport { Lib_NVMCodec } from \"../../libraries/codec/Lib_NVMCodec.sol\";\n\n/**\n * @title IMessageQueue\n */\ninterface IMessageQueue {\n    /**********\n     * Events *\n     **********/\n\n    event TransactionEnqueued(\n        address indexed _blTxOrigin,\n        address indexed _target,\n        uint256 _gasLimit,\n        bytes _data,\n        uint256 indexed _queueIndex,\n        uint256 _timestamp\n    );\n\n    /********************\n     * Public Functions *\n     ********************/\n\n    /**\n     * Gets the queue element at a particular index.\n     * @param _index Index of the queue element to access.\n     * @return _element Queue element at the given index.\n     */\n    function getQueueElement(uint256 _index)\n        external\n        view\n        returns (Lib_NVMCodec.QueueElement memory _element);\n\n    /**\n     * Retrieves the length of the queue, including\n     * both pending and canonical transactions.\n     * @return Length of the queue.\n     */\n    function getQueueLength() external view returns (uint40);\n\n    /**\n     * Adds a transaction to the queue.\n     * @param _target Target contract to send the transaction to.\n     * @param _gasLimit Gas limit for the given transaction.\n     * @param _data Transaction data.\n     */\n    function enqueue(\n        address _target,\n        uint256 _gasLimit,\n        bytes memory _data\n    ) external;\n}\n"
      },
      "@openzeppelin/contracts/access/Ownable.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (access/Ownable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../utils/Context.sol\";\n\n/**\n * @dev Contract module which provides a basic access control mechanism, where\n * there is an account (an owner) that can be granted exclusive access to\n * specific functions.\n *\n * By default, the owner account will be the one that deploys the contract. This\n * can later be changed with {transferOwnership}.\n *\n * This module is used through inheritance. It will make available the modifier\n * `onlyOwner`, which can be applied to your functions to restrict their use to\n * the owner.\n */\nabstract contract Ownable is Context {\n    address private _owner;\n\n    event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n    /**\n     * @dev Initializes the contract setting the deployer as the initial owner.\n     */\n    constructor() {\n        _transferOwnership(_msgSender());\n    }\n\n    /**\n     * @dev Throws if called by any account other than the owner.\n     */\n    modifier onlyOwner() {\n        _checkOwner();\n        _;\n    }\n\n    /**\n     * @dev Returns the address of the current owner.\n     */\n    function owner() public view virtual returns (address) {\n        return _owner;\n    }\n\n    /**\n     * @dev Throws if the sender is not the owner.\n     */\n    function _checkOwner() internal view virtual {\n        require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n    }\n\n    /**\n     * @dev Leaves the contract without owner. It will not be possible to call\n     * `onlyOwner` functions anymore. Can only be called by the current owner.\n     *\n     * NOTE: Renouncing ownership will leave the contract without an owner,\n     * thereby removing any functionality that is only available to the owner.\n     */\n    function renounceOwnership() public virtual onlyOwner {\n        _transferOwnership(address(0));\n    }\n\n    /**\n     * @dev Transfers ownership of the contract to a new account (`newOwner`).\n     * Can only be called by the current owner.\n     */\n    function transferOwnership(address newOwner) public virtual onlyOwner {\n        require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n        _transferOwnership(newOwner);\n    }\n\n    /**\n     * @dev Transfers ownership of the contract to a new account (`newOwner`).\n     * Internal function without access restriction.\n     */\n    function _transferOwnership(address newOwner) internal virtual {\n        address oldOwner = _owner;\n        _owner = newOwner;\n        emit OwnershipTransferred(oldOwner, newOwner);\n    }\n}\n"
      },
      "contracts/libraries/rlp/Lib_RLPWriter.sol": {
        "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.9;\n\n/**\n * @title Lib_RLPWriter\n * @author Bakaoh (with modifications)\n */\nlibrary Lib_RLPWriter {\n    /**********************\n     * Internal Functions *\n     **********************/\n\n    /**\n     * RLP encodes a byte string.\n     * @param _in The byte string to encode.\n     * @return The RLP encoded string in bytes.\n     */\n    function writeBytes(bytes memory _in) internal pure returns (bytes memory) {\n        bytes memory encoded;\n\n        if (_in.length == 1 && uint8(_in[0]) < 128) {\n            encoded = _in;\n        } else {\n            encoded = abi.encodePacked(_writeLength(_in.length, 128), _in);\n        }\n\n        return encoded;\n    }\n\n    /**\n     * RLP encodes a list of RLP encoded byte byte strings.\n     * @param _in The list of RLP encoded byte strings.\n     * @return The RLP encoded list of items in bytes.\n     */\n    function writeList(bytes[] memory _in) internal pure returns (bytes memory) {\n        bytes memory list = _flatten(_in);\n        return abi.encodePacked(_writeLength(list.length, 192), list);\n    }\n\n    /**\n     * RLP encodes a string.\n     * @param _in The string to encode.\n     * @return The RLP encoded string in bytes.\n     */\n    function writeString(string memory _in) internal pure returns (bytes memory) {\n        return writeBytes(bytes(_in));\n    }\n\n    /**\n     * RLP encodes an address.\n     * @param _in The address to encode.\n     * @return The RLP encoded address in bytes.\n     */\n    function writeAddress(address _in) internal pure returns (bytes memory) {\n        return writeBytes(abi.encodePacked(_in));\n    }\n\n    /**\n     * RLP encodes a uint.\n     * @param _in The uint256 to encode.\n     * @return The RLP encoded uint256 in bytes.\n     */\n    function writeUint(uint256 _in) internal pure returns (bytes memory) {\n        return writeBytes(_toBinary(_in));\n    }\n\n    /**\n     * RLP encodes a bool.\n     * @param _in The bool to encode.\n     * @return The RLP encoded bool in bytes.\n     */\n    function writeBool(bool _in) internal pure returns (bytes memory) {\n        bytes memory encoded = new bytes(1);\n        encoded[0] = (_in ? bytes1(0x01) : bytes1(0x80));\n        return encoded;\n    }\n\n    /*********************\n     * Private Functions *\n     *********************/\n\n    /**\n     * Encode the first byte, followed by the `len` in binary form if `length` is more than 55.\n     * @param _len The length of the string or the payload.\n     * @param _offset 128 if item is string, 192 if item is list.\n     * @return RLP encoded bytes.\n     */\n    function _writeLength(uint256 _len, uint256 _offset) private pure returns (bytes memory) {\n        bytes memory encoded;\n\n        if (_len < 56) {\n            encoded = new bytes(1);\n            encoded[0] = bytes1(uint8(_len) + uint8(_offset));\n        } else {\n            uint256 lenLen;\n            uint256 i = 1;\n            while (_len / i != 0) {\n                lenLen++;\n                i *= 256;\n            }\n\n            encoded = new bytes(lenLen + 1);\n            encoded[0] = bytes1(uint8(lenLen) + uint8(_offset) + 55);\n            for (i = 1; i <= lenLen; i++) {\n                encoded[i] = bytes1(uint8((_len / (256**(lenLen - i))) % 256));\n            }\n        }\n\n        return encoded;\n    }\n\n    /**\n     * Encode integer in big endian binary form with no leading zeroes.\n     * @notice TODO: This should be optimized with assembly to save gas costs.\n     * @param _x The integer to encode.\n     * @return RLP encoded bytes.\n     */\n    function _toBinary(uint256 _x) private pure returns (bytes memory) {\n        bytes memory b = abi.encodePacked(_x);\n\n        uint256 i = 0;\n        for (; i < 32; i++) {\n            if (b[i] != 0) {\n                break;\n            }\n        }\n\n        bytes memory res = new bytes(32 - i);\n        for (uint256 j = 0; j < res.length; j++) {\n            res[j] = b[i++];\n        }\n\n        return res;\n    }\n\n    /**\n     * Copies a piece of memory to another location.\n     * @notice From: https://github.com/Arachnid/solidity-stringutils/blob/master/src/strings.sol.\n     * @param _dest Destination location.\n     * @param _src Source location.\n     * @param _len Length of memory to copy.\n     */\n    function _memcpy(\n        uint256 _dest,\n        uint256 _src,\n        uint256 _len\n    ) private pure {\n        uint256 dest = _dest;\n        uint256 src = _src;\n        uint256 len = _len;\n\n        for (; len >= 32; len -= 32) {\n            assembly {\n                mstore(dest, mload(src))\n            }\n            dest += 32;\n            src += 32;\n        }\n\n        uint256 mask;\n        unchecked {\n            mask = 256**(32 - len) - 1;\n        }\n        assembly {\n            let srcpart := and(mload(src), not(mask))\n            let destpart := and(mload(dest), mask)\n            mstore(dest, or(destpart, srcpart))\n        }\n    }\n\n    /**\n     * Flattens a list of byte strings into one byte string.\n     * @notice From: https://github.com/sammayo/solidity-rlp-encoder/blob/master/RLPEncode.sol.\n     * @param _list List of byte strings to flatten.\n     * @return The flattened byte string.\n     */\n    function _flatten(bytes[] memory _list) private pure returns (bytes memory) {\n        if (_list.length == 0) {\n            return new bytes(0);\n        }\n\n        uint256 len;\n        uint256 i = 0;\n        for (; i < _list.length; i++) {\n            len += _list[i].length;\n        }\n\n        bytes memory flattened = new bytes(len);\n        uint256 flattenedPtr;\n        assembly {\n            flattenedPtr := add(flattened, 0x20)\n        }\n\n        for (i = 0; i < _list.length; i++) {\n            bytes memory item = _list[i];\n\n            uint256 listPtr;\n            assembly {\n                listPtr := add(item, 0x20)\n            }\n\n            _memcpy(flattenedPtr, listPtr, item.length);\n            flattenedPtr += _list[i].length;\n        }\n\n        return flattened;\n    }\n}\n"
      },
      "contracts/libraries/rlp/Lib_RLPReader.sol": {
        "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.9;\n\n/**\n * @title Lib_RLPReader\n * @dev Adapted from \"RLPReader\" by Hamdi Allam (hamdi.allam97@gmail.com).\n */\nlibrary Lib_RLPReader {\n    /*************\n     * Constants *\n     *************/\n\n    uint256 internal constant MAX_LIST_LENGTH = 32;\n\n    /*********\n     * Enums *\n     *********/\n\n    enum RLPItemType {\n        DATA_ITEM,\n        LIST_ITEM\n    }\n\n    /***********\n     * Structs *\n     ***********/\n\n    struct RLPItem {\n        uint256 length;\n        uint256 ptr;\n    }\n\n    /**********************\n     * Internal Functions *\n     **********************/\n\n    /**\n     * Converts bytes to a reference to memory position and length.\n     * @param _in Input bytes to convert.\n     * @return Output memory reference.\n     */\n    function toRLPItem(bytes memory _in) internal pure returns (RLPItem memory) {\n        uint256 ptr;\n        assembly {\n            ptr := add(_in, 32)\n        }\n\n        return RLPItem({ length: _in.length, ptr: ptr });\n    }\n\n    /**\n     * Reads an RLP list value into a list of RLP items.\n     * @param _in RLP list value.\n     * @return Decoded RLP list items.\n     */\n    function readList(RLPItem memory _in) internal pure returns (RLPItem[] memory) {\n        (uint256 listOffset, , RLPItemType itemType) = _decodeLength(_in);\n\n        require(itemType == RLPItemType.LIST_ITEM, \"Invalid RLP list value.\");\n\n        // Solidity in-memory arrays can't be increased in size, but *can* be decreased in size by\n        // writing to the length. Since we can't know the number of RLP items without looping over\n        // the entire input, we'd have to loop twice to accurately size this array. It's easier to\n        // simply set a reasonable maximum list length and decrease the size before we finish.\n        RLPItem[] memory out = new RLPItem[](MAX_LIST_LENGTH);\n\n        uint256 itemCount = 0;\n        uint256 offset = listOffset;\n        while (offset < _in.length) {\n            require(itemCount < MAX_LIST_LENGTH, \"Provided RLP list exceeds max list length.\");\n\n            (uint256 itemOffset, uint256 itemLength, ) = _decodeLength(\n                RLPItem({ length: _in.length - offset, ptr: _in.ptr + offset })\n            );\n\n            out[itemCount] = RLPItem({ length: itemLength + itemOffset, ptr: _in.ptr + offset });\n\n            itemCount += 1;\n            offset += itemOffset + itemLength;\n        }\n\n        // Decrease the array size to match the actual item count.\n        assembly {\n            mstore(out, itemCount)\n        }\n\n        return out;\n    }\n\n    /**\n     * Reads an RLP list value into a list of RLP items.\n     * @param _in RLP list value.\n     * @return Decoded RLP list items.\n     */\n    function readList(bytes memory _in) internal pure returns (RLPItem[] memory) {\n        return readList(toRLPItem(_in));\n    }\n\n    /**\n     * Reads an RLP bytes value into bytes.\n     * @param _in RLP bytes value.\n     * @return Decoded bytes.\n     */\n    function readBytes(RLPItem memory _in) internal pure returns (bytes memory) {\n        (uint256 itemOffset, uint256 itemLength, RLPItemType itemType) = _decodeLength(_in);\n\n        require(itemType == RLPItemType.DATA_ITEM, \"Invalid RLP bytes value.\");\n\n        return _copy(_in.ptr, itemOffset, itemLength);\n    }\n\n    /**\n     * Reads an RLP bytes value into bytes.\n     * @param _in RLP bytes value.\n     * @return Decoded bytes.\n     */\n    function readBytes(bytes memory _in) internal pure returns (bytes memory) {\n        return readBytes(toRLPItem(_in));\n    }\n\n    /**\n     * Reads an RLP string value into a string.\n     * @param _in RLP string value.\n     * @return Decoded string.\n     */\n    function readString(RLPItem memory _in) internal pure returns (string memory) {\n        return string(readBytes(_in));\n    }\n\n    /**\n     * Reads an RLP string value into a string.\n     * @param _in RLP string value.\n     * @return Decoded string.\n     */\n    function readString(bytes memory _in) internal pure returns (string memory) {\n        return readString(toRLPItem(_in));\n    }\n\n    /**\n     * Reads an RLP bytes32 value into a bytes32.\n     * @param _in RLP bytes32 value.\n     * @return Decoded bytes32.\n     */\n    function readBytes32(RLPItem memory _in) internal pure returns (bytes32) {\n        require(_in.length <= 33, \"Invalid RLP bytes32 value.\");\n\n        (uint256 itemOffset, uint256 itemLength, RLPItemType itemType) = _decodeLength(_in);\n\n        require(itemType == RLPItemType.DATA_ITEM, \"Invalid RLP bytes32 value.\");\n\n        uint256 ptr = _in.ptr + itemOffset;\n        bytes32 out;\n        assembly {\n            out := mload(ptr)\n\n            // Shift the bytes over to match the item size.\n            if lt(itemLength, 32) {\n                out := div(out, exp(256, sub(32, itemLength)))\n            }\n        }\n\n        return out;\n    }\n\n    /**\n     * Reads an RLP bytes32 value into a bytes32.\n     * @param _in RLP bytes32 value.\n     * @return Decoded bytes32.\n     */\n    function readBytes32(bytes memory _in) internal pure returns (bytes32) {\n        return readBytes32(toRLPItem(_in));\n    }\n\n    /**\n     * Reads an RLP uint256 value into a uint256.\n     * @param _in RLP uint256 value.\n     * @return Decoded uint256.\n     */\n    function readUint256(RLPItem memory _in) internal pure returns (uint256) {\n        return uint256(readBytes32(_in));\n    }\n\n    /**\n     * Reads an RLP uint256 value into a uint256.\n     * @param _in RLP uint256 value.\n     * @return Decoded uint256.\n     */\n    function readUint256(bytes memory _in) internal pure returns (uint256) {\n        return readUint256(toRLPItem(_in));\n    }\n\n    /**\n     * Reads an RLP bool value into a bool.\n     * @param _in RLP bool value.\n     * @return Decoded bool.\n     */\n    function readBool(RLPItem memory _in) internal pure returns (bool) {\n        require(_in.length == 1, \"Invalid RLP boolean value.\");\n\n        uint256 ptr = _in.ptr;\n        uint256 out;\n        assembly {\n            out := byte(0, mload(ptr))\n        }\n\n        require(out == 0 || out == 1, \"Lib_RLPReader: Invalid RLP boolean value, must be 0 or 1\");\n\n        return out != 0;\n    }\n\n    /**\n     * Reads an RLP bool value into a bool.\n     * @param _in RLP bool value.\n     * @return Decoded bool.\n     */\n    function readBool(bytes memory _in) internal pure returns (bool) {\n        return readBool(toRLPItem(_in));\n    }\n\n    /**\n     * Reads an RLP address value into a address.\n     * @param _in RLP address value.\n     * @return Decoded address.\n     */\n    function readAddress(RLPItem memory _in) internal pure returns (address) {\n        if (_in.length == 1) {\n            return address(0);\n        }\n\n        require(_in.length == 21, \"Invalid RLP address value.\");\n\n        return address(uint160(readUint256(_in)));\n    }\n\n    /**\n     * Reads an RLP address value into a address.\n     * @param _in RLP address value.\n     * @return Decoded address.\n     */\n    function readAddress(bytes memory _in) internal pure returns (address) {\n        return readAddress(toRLPItem(_in));\n    }\n\n    /**\n     * Reads the raw bytes of an RLP item.\n     * @param _in RLP item to read.\n     * @return Raw RLP bytes.\n     */\n    function readRawBytes(RLPItem memory _in) internal pure returns (bytes memory) {\n        return _copy(_in);\n    }\n\n    /*********************\n     * Private Functions *\n     *********************/\n\n    /**\n     * Decodes the length of an RLP item.\n     * @param _in RLP item to decode.\n     * @return Offset of the encoded data.\n     * @return Length of the encoded data.\n     * @return RLP item type (LIST_ITEM or DATA_ITEM).\n     */\n    function _decodeLength(RLPItem memory _in)\n        private\n        pure\n        returns (\n            uint256,\n            uint256,\n            RLPItemType\n        )\n    {\n        require(_in.length > 0, \"RLP item cannot be null.\");\n\n        uint256 ptr = _in.ptr;\n        uint256 prefix;\n        assembly {\n            prefix := byte(0, mload(ptr))\n        }\n\n        if (prefix <= 0x7f) {\n            // Single byte.\n\n            return (0, 1, RLPItemType.DATA_ITEM);\n        } else if (prefix <= 0xb7) {\n            // Short string.\n\n            // slither-disable-next-line variable-scope\n            uint256 strLen = prefix - 0x80;\n\n            require(_in.length > strLen, \"Invalid RLP short string.\");\n\n            return (1, strLen, RLPItemType.DATA_ITEM);\n        } else if (prefix <= 0xbf) {\n            // Long string.\n            uint256 lenOfStrLen = prefix - 0xb7;\n\n            require(_in.length > lenOfStrLen, \"Invalid RLP long string length.\");\n\n            uint256 strLen;\n            assembly {\n                // Pick out the string length.\n                strLen := div(mload(add(ptr, 1)), exp(256, sub(32, lenOfStrLen)))\n            }\n\n            require(_in.length > lenOfStrLen + strLen, \"Invalid RLP long string.\");\n\n            return (1 + lenOfStrLen, strLen, RLPItemType.DATA_ITEM);\n        } else if (prefix <= 0xf7) {\n            // Short list.\n            // slither-disable-next-line variable-scope\n            uint256 listLen = prefix - 0xc0;\n\n            require(_in.length > listLen, \"Invalid RLP short list.\");\n\n            return (1, listLen, RLPItemType.LIST_ITEM);\n        } else {\n            // Long list.\n            uint256 lenOfListLen = prefix - 0xf7;\n\n            require(_in.length > lenOfListLen, \"Invalid RLP long list length.\");\n\n            uint256 listLen;\n            assembly {\n                // Pick out the list length.\n                listLen := div(mload(add(ptr, 1)), exp(256, sub(32, lenOfListLen)))\n            }\n\n            require(_in.length > lenOfListLen + listLen, \"Invalid RLP long list.\");\n\n            return (1 + lenOfListLen, listLen, RLPItemType.LIST_ITEM);\n        }\n    }\n\n    /**\n     * Copies the bytes from a memory location.\n     * @param _src Pointer to the location to read from.\n     * @param _offset Offset to start reading from.\n     * @param _length Number of bytes to read.\n     * @return Copied bytes.\n     */\n    function _copy(\n        uint256 _src,\n        uint256 _offset,\n        uint256 _length\n    ) private pure returns (bytes memory) {\n        bytes memory out = new bytes(_length);\n        if (out.length == 0) {\n            return out;\n        }\n\n        uint256 src = _src + _offset;\n        uint256 dest;\n        assembly {\n            dest := add(out, 32)\n        }\n\n        // Copy over as many complete words as we can.\n        for (uint256 i = 0; i < _length / 32; i++) {\n            assembly {\n                mstore(dest, mload(src))\n            }\n\n            src += 32;\n            dest += 32;\n        }\n\n        // Pick out the remaining bytes.\n        uint256 mask;\n        unchecked {\n            mask = 256**(32 - (_length % 32)) - 1;\n        }\n\n        assembly {\n            mstore(dest, or(and(mload(src), not(mask)), and(mload(dest), mask)))\n        }\n        return out;\n    }\n\n    /**\n     * Copies an RLP item into bytes.\n     * @param _in RLP item to copy.\n     * @return Copied bytes.\n     */\n    function _copy(RLPItem memory _in) private pure returns (bytes memory) {\n        return _copy(_in.ptr, 0, _in.length);\n    }\n}\n"
      },
      "contracts/libraries/utils/Lib_Bytes32Utils.sol": {
        "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.9;\n\n/**\n * @title Lib_Byte32Utils\n */\nlibrary Lib_Bytes32Utils {\n    /**********************\n     * Internal Functions *\n     **********************/\n\n    /**\n     * Converts a bytes32 value to a boolean. Anything non-zero will be converted to \"true.\"\n     * @param _in Input bytes32 value.\n     * @return Bytes32 as a boolean.\n     */\n    function toBool(bytes32 _in) internal pure returns (bool) {\n        return _in != 0;\n    }\n\n    /**\n     * Converts a boolean to a bytes32 value.\n     * @param _in Input boolean value.\n     * @return Boolean as a bytes32.\n     */\n    function fromBool(bool _in) internal pure returns (bytes32) {\n        return bytes32(uint256(_in ? 1 : 0));\n    }\n\n    /**\n     * Converts a bytes32 value to an address. Takes the *last* 20 bytes.\n     * @param _in Input bytes32 value.\n     * @return Bytes32 as an address.\n     */\n    function toAddress(bytes32 _in) internal pure returns (address) {\n        return address(uint160(uint256(_in)));\n    }\n\n    /**\n     * Converts an address to a bytes32.\n     * @param _in Input address value.\n     * @return Address as a bytes32.\n     */\n    function fromAddress(address _in) internal pure returns (bytes32) {\n        return bytes32(uint256(uint160(_in)));\n    }\n}\n"
      },
      "contracts/libraries/utils/Lib_BytesUtils.sol": {
        "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.9;\n\n/**\n * @title Lib_BytesUtils\n */\nlibrary Lib_BytesUtils {\n    /**********************\n     * Internal Functions *\n     **********************/\n\n    function slice(\n        bytes memory _bytes,\n        uint256 _start,\n        uint256 _length\n    ) internal pure returns (bytes memory) {\n        require(_length + 31 >= _length, \"slice_overflow\");\n        require(_start + _length >= _start, \"slice_overflow\");\n        require(_bytes.length >= _start + _length, \"slice_outOfBounds\");\n\n        bytes memory tempBytes;\n\n        assembly {\n            switch iszero(_length)\n            case 0 {\n                // Get a location of some free memory and store it in tempBytes as\n                // Solidity does for memory variables.\n                tempBytes := mload(0x40)\n\n                // The first word of the slice result is potentially a partial\n                // word read from the original array. To read it, we calculate\n                // the length of that partial word and start copying that many\n                // bytes into the array. The first word we copy will start with\n                // data we don't care about, but the last `lengthmod` bytes will\n                // land at the beginning of the contents of the new array. When\n                // we're done copying, we overwrite the full first word with\n                // the actual length of the slice.\n                let lengthmod := and(_length, 31)\n\n                // The multiplication in the next line is necessary\n                // because when slicing multiples of 32 bytes (lengthmod == 0)\n                // the following copy loop was copying the origin's length\n                // and then ending prematurely not copying everything it should.\n                let mc := add(add(tempBytes, lengthmod), mul(0x20, iszero(lengthmod)))\n                let end := add(mc, _length)\n\n                for {\n                    // The multiplication in the next line has the same exact purpose\n                    // as the one above.\n                    let cc := add(add(add(_bytes, lengthmod), mul(0x20, iszero(lengthmod))), _start)\n                } lt(mc, end) {\n                    mc := add(mc, 0x20)\n                    cc := add(cc, 0x20)\n                } {\n                    mstore(mc, mload(cc))\n                }\n\n                mstore(tempBytes, _length)\n\n                //update free-memory pointer\n                //allocating the array padded to 32 bytes like the compiler does now\n                mstore(0x40, and(add(mc, 31), not(31)))\n            }\n            //if we want a zero-length slice let's just return a zero-length array\n            default {\n                tempBytes := mload(0x40)\n\n                //zero out the 32 bytes slice we are about to return\n                //we need to do it because Solidity does not garbage collect\n                mstore(tempBytes, 0)\n\n                mstore(0x40, add(tempBytes, 0x20))\n            }\n        }\n\n        return tempBytes;\n    }\n\n    function slice(bytes memory _bytes, uint256 _start) internal pure returns (bytes memory) {\n        if (_start >= _bytes.length) {\n            return bytes(\"\");\n        }\n\n        return slice(_bytes, _start, _bytes.length - _start);\n    }\n\n    function toBytes32(bytes memory _bytes) internal pure returns (bytes32) {\n        if (_bytes.length < 32) {\n            bytes32 ret;\n            assembly {\n                ret := mload(add(_bytes, 32))\n            }\n            return ret;\n        }\n\n        return abi.decode(_bytes, (bytes32)); // will truncate if input length > 32 bytes\n    }\n\n    function toUint256(bytes memory _bytes) internal pure returns (uint256) {\n        return uint256(toBytes32(_bytes));\n    }\n\n    function toNibbles(bytes memory _bytes) internal pure returns (bytes memory) {\n        bytes memory nibbles = new bytes(_bytes.length * 2);\n\n        for (uint256 i = 0; i < _bytes.length; i++) {\n            nibbles[i * 2] = _bytes[i] >> 4;\n            nibbles[i * 2 + 1] = bytes1(uint8(_bytes[i]) % 16);\n        }\n\n        return nibbles;\n    }\n\n    function fromNibbles(bytes memory _bytes) internal pure returns (bytes memory) {\n        bytes memory ret = new bytes(_bytes.length / 2);\n\n        for (uint256 i = 0; i < ret.length; i++) {\n            ret[i] = (_bytes[i * 2] << 4) | (_bytes[i * 2 + 1]);\n        }\n\n        return ret;\n    }\n\n    function equal(bytes memory _bytes, bytes memory _other) internal pure returns (bool) {\n        return keccak256(_bytes) == keccak256(_other);\n    }\n}\n"
      },
      "contracts/libraries/resolver/Lib_AddressManager.sol": {
        "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.9;\n\n/* External Imports */\nimport { Ownable } from \"@openzeppelin/contracts/access/Ownable.sol\";\n\n/**\n * @title Lib_AddressManager\n */\ncontract Lib_AddressManager is Ownable {\n    /**********\n     * Events *\n     **********/\n\n    event AddressSet(string indexed _name, address _newAddress, address _oldAddress);\n\n    /*************\n     * Variables *\n     *************/\n\n    mapping(bytes32 => address) private addresses;\n\n    /********************\n     * Public Functions *\n     ********************/\n\n    /**\n     * Changes the address associated with a particular name.\n     * @param _name String name to associate an address with.\n     * @param _address Address to associate with the name.\n     */\n    function setAddress(string memory _name, address _address) external onlyOwner {\n        bytes32 nameHash = _getNameHash(_name);\n        address oldAddress = addresses[nameHash];\n        addresses[nameHash] = _address;\n\n        emit AddressSet(_name, _address, oldAddress);\n    }\n\n    /**\n     * Retrieves the address associated with a given name.\n     * @param _name Name to retrieve an address for.\n     * @return Address associated with the given name.\n     */\n    function getAddress(string memory _name) external view returns (address) {\n        return addresses[_getNameHash(_name)];\n    }\n\n    /**********************\n     * Internal Functions *\n     **********************/\n\n    /**\n     * Computes the hash of a name.\n     * @param _name Name to compute a hash for.\n     * @return Hash of the given name.\n     */\n    function _getNameHash(string memory _name) internal pure returns (bytes32) {\n        return keccak256(abi.encodePacked(_name));\n    }\n}\n"
      },
      "@openzeppelin/contracts/utils/Context.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract Context {\n    function _msgSender() internal view virtual returns (address) {\n        return msg.sender;\n    }\n\n    function _msgData() internal view virtual returns (bytes calldata) {\n        return msg.data;\n    }\n}\n"
      }
    },
    "settings": {
      "optimizer": {
        "enabled": true,
        "runs": 10000
      },
      "outputSelection": {
        "*": {
          "*": [
            "evm.bytecode",
            "evm.deployedBytecode",
            "devdoc",
            "userdoc",
            "metadata",
            "abi"
          ]
        }
      },
      "metadata": {
        "useLiteralContent": true
      },
      "libraries": {}
    }
  }}