creation_sourcecode: {{
    "language": "Solidity",
    "sources": {
      "src/dispute/weth/DelayedWETH.sol": {
        "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { OwnableUpgradeable } from \"@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol\";\nimport { ISemver } from \"src/universal/ISemver.sol\";\n\nimport { IDelayedWETH } from \"src/dispute/interfaces/IDelayedWETH.sol\";\nimport { IWETH } from \"src/dispute/interfaces/IWETH.sol\";\nimport { WETH98 } from \"src/dispute/weth/WETH98.sol\";\n\nimport { SuperchainConfig } from \"src/L1/SuperchainConfig.sol\";\n\n/// @title DelayedWETH\n/// @notice DelayedWETH is an extension to WETH9 that allows for delayed withdrawals. Accounts must\n///         trigger an unlock function before they can withdraw WETH. Accounts must trigger unlock\n///         by specifying a sub-account and an amount of WETH to unlock. Accounts can trigger the\n///         unlock function at any time, but must wait a delay period before they can withdraw\n///         after the unlock function is triggered. DelayedWETH is designed to be used by the\n///         DisputeGame contracts where unlock will only be triggered after a dispute is resolved.\n///         DelayedWETH is meant to sit behind a proxy contract and has an owner address that can\n///         pull WETH from any account and can recover ETH from the contract itself. Variable and\n///         function naming vaguely follows the vibe of WETH9. Not the prettiest contract in the\n///         world, but it gets the job done.\ncontract DelayedWETH is OwnableUpgradeable, WETH98, IDelayedWETH, ISemver {\n    /// @notice Semantic version.\n    /// @custom:semver 0.2.0\n    string public constant version = \"0.2.0\";\n\n    /// @inheritdoc IDelayedWETH\n    mapping(address => mapping(address => WithdrawalRequest)) public withdrawals;\n\n    /// @notice Withdrawal delay in seconds.\n    uint256 internal immutable DELAY_SECONDS;\n\n    /// @notice Address of the SuperchainConfig contract.\n    SuperchainConfig public config;\n\n    /// @param _delay The delay for withdrawals in seconds.\n    constructor(uint256 _delay) {\n        DELAY_SECONDS = _delay;\n        initialize({ _owner: address(0), _config: SuperchainConfig(address(0)) });\n    }\n\n    /// @notice Initializes the contract.\n    /// @param _owner The address of the owner.\n    /// @param _config Address of the SuperchainConfig contract.\n    function initialize(address _owner, SuperchainConfig _config) public initializer {\n        __Ownable_init();\n        _transferOwnership(_owner);\n        config = _config;\n    }\n\n    /// @inheritdoc IDelayedWETH\n    function delay() external view returns (uint256) {\n        return DELAY_SECONDS;\n    }\n\n    /// @inheritdoc IDelayedWETH\n    function unlock(address _guy, uint256 _wad) external {\n        // Note that the unlock function can be called by any address, but the actual unlocking\n        // capability still only gives the msg.sender the ability to withdraw from the account.\n        // As long as the unlock and withdraw functions are called with the proper recipient\n        // addresses, this will be safe. Could be made safer by having external accounts execute\n        // withdrawals themselves but that would have added extra complexity and made DelayedWETH\n        // a leaky abstraction, so we chose this instead.\n        require(!config.paused(), \"DelayedWETH: contract is paused\");\n        WithdrawalRequest storage wd = withdrawals[msg.sender][_guy];\n        wd.timestamp = block.timestamp;\n        wd.amount += _wad;\n    }\n\n    /// @inheritdoc IWETH\n    function withdraw(uint256 _wad) public override(WETH98, IWETH) {\n        withdraw(msg.sender, _wad);\n    }\n\n    /// @inheritdoc IDelayedWETH\n    function withdraw(address _guy, uint256 _wad) public {\n        require(!config.paused(), \"DelayedWETH: contract is paused\");\n        WithdrawalRequest storage wd = withdrawals[msg.sender][_guy];\n        require(wd.amount >= _wad, \"DelayedWETH: insufficient unlocked withdrawal\");\n        require(wd.timestamp > 0, \"DelayedWETH: withdrawal not unlocked\");\n        require(wd.timestamp + DELAY_SECONDS <= block.timestamp, \"DelayedWETH: withdrawal delay not met\");\n        wd.amount -= _wad;\n        super.withdraw(_wad);\n    }\n\n    /// @inheritdoc IDelayedWETH\n    function recover(uint256 _wad) external {\n        require(msg.sender == owner(), \"DelayedWETH: not owner\");\n        require(address(this).balance >= _wad, \"DelayedWETH: insufficient balance\");\n        payable(msg.sender).transfer(_wad);\n    }\n\n    /// @inheritdoc IDelayedWETH\n    function hold(address _guy, uint256 _wad) external {\n        require(msg.sender == owner(), \"DelayedWETH: not owner\");\n        allowance[msg.sender][_guy] = _wad;\n        emit Approval(msg.sender, _guy, _wad);\n    }\n}\n"
      },
      "lib/openzeppelin-contracts-upgradeable/contracts/access/OwnableUpgradeable.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (access/Ownable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../utils/ContextUpgradeable.sol\";\nimport \"../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Contract module which provides a basic access control mechanism, where\n * there is an account (an owner) that can be granted exclusive access to\n * specific functions.\n *\n * By default, the owner account will be the one that deploys the contract. This\n * can later be changed with {transferOwnership}.\n *\n * This module is used through inheritance. It will make available the modifier\n * `onlyOwner`, which can be applied to your functions to restrict their use to\n * the owner.\n */\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\n    address private _owner;\n\n    event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n    /**\n     * @dev Initializes the contract setting the deployer as the initial owner.\n     */\n    function __Ownable_init() internal onlyInitializing {\n        __Ownable_init_unchained();\n    }\n\n    function __Ownable_init_unchained() internal onlyInitializing {\n        _transferOwnership(_msgSender());\n    }\n\n    /**\n     * @dev Throws if called by any account other than the owner.\n     */\n    modifier onlyOwner() {\n        _checkOwner();\n        _;\n    }\n\n    /**\n     * @dev Returns the address of the current owner.\n     */\n    function owner() public view virtual returns (address) {\n        return _owner;\n    }\n\n    /**\n     * @dev Throws if the sender is not the owner.\n     */\n    function _checkOwner() internal view virtual {\n        require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n    }\n\n    /**\n     * @dev Leaves the contract without owner. It will not be possible to call\n     * `onlyOwner` functions anymore. Can only be called by the current owner.\n     *\n     * NOTE: Renouncing ownership will leave the contract without an owner,\n     * thereby removing any functionality that is only available to the owner.\n     */\n    function renounceOwnership() public virtual onlyOwner {\n        _transferOwnership(address(0));\n    }\n\n    /**\n     * @dev Transfers ownership of the contract to a new account (`newOwner`).\n     * Can only be called by the current owner.\n     */\n    function transferOwnership(address newOwner) public virtual onlyOwner {\n        require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n        _transferOwnership(newOwner);\n    }\n\n    /**\n     * @dev Transfers ownership of the contract to a new account (`newOwner`).\n     * Internal function without access restriction.\n     */\n    function _transferOwnership(address newOwner) internal virtual {\n        address oldOwner = _owner;\n        _owner = newOwner;\n        emit OwnershipTransferred(oldOwner, newOwner);\n    }\n\n    /**\n     * @dev This empty reserved space is put in place to allow future versions to add new\n     * variables without shifting down storage in the inheritance chain.\n     * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n     */\n    uint256[49] private __gap;\n}\n"
      },
      "src/universal/ISemver.sol": {
        "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\n/// @title ISemver\n/// @notice ISemver is a simple contract for ensuring that contracts are\n///         versioned using semantic versioning.\ninterface ISemver {\n    /// @notice Getter for the semantic version of the contract. This is not\n    ///         meant to be used onchain but instead meant to be used by offchain\n    ///         tooling.\n    /// @return Semver contract version as a string.\n    function version() external view returns (string memory);\n}\n"
      },
      "src/dispute/interfaces/IDelayedWETH.sol": {
        "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.15;\n\nimport { IWETH } from \"src/dispute/interfaces/IWETH.sol\";\n\n/// @title IDelayedWETH\n/// @notice Interface for the DelayedWETH contract.\ninterface IDelayedWETH is IWETH {\n    /// @notice Represents a withdrawal request.\n    struct WithdrawalRequest {\n        uint256 amount;\n        uint256 timestamp;\n    }\n\n    /// @notice Emitted when an unwrap is started.\n    /// @param src The address that started the unwrap.\n    /// @param wad The amount of WETH that was unwrapped.\n    event Unwrap(address indexed src, uint256 wad);\n\n    /// @notice Returns the withdrawal delay in seconds.\n    /// @return The withdrawal delay in seconds.\n    function delay() external view returns (uint256);\n\n    /// @notice Returns a withdrawal request for the given address.\n    /// @param _owner The address to query the withdrawal request of.\n    /// @param _guy Sub-account to query the withdrawal request of.\n    /// @return The withdrawal request for the given address-subaccount pair.\n    function withdrawals(address _owner, address _guy) external view returns (uint256, uint256);\n\n    /// @notice Unlocks withdrawals for the sender's account, after a time delay.\n    /// @param _guy Sub-account to unlock.\n    /// @param _wad The amount of WETH to unlock.\n    function unlock(address _guy, uint256 _wad) external;\n\n    /// @notice Extension to withdrawal, must provide a sub-account to withdraw from.\n    /// @param _guy Sub-account to withdraw from.\n    /// @param _wad The amount of WETH to withdraw.\n    function withdraw(address _guy, uint256 _wad) external;\n\n    /// @notice Allows the owner to recover from error cases by pulling ETH out of the contract.\n    /// @param _wad The amount of WETH to recover.\n    function recover(uint256 _wad) external;\n\n    /// @notice Allows the owner to recover from error cases by pulling ETH from a specific owner.\n    /// @param _guy The address to recover the WETH from.\n    /// @param _wad The amount of WETH to recover.\n    function hold(address _guy, uint256 _wad) external;\n}\n"
      },
      "src/dispute/interfaces/IWETH.sol": {
        "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.15;\n\n/// @title IWETH\n/// @notice Interface for WETH9.\ninterface IWETH {\n    /// @notice Emitted when an approval is made.\n    /// @param src The address that approved the transfer.\n    /// @param guy The address that was approved to transfer.\n    /// @param wad The amount that was approved to transfer.\n    event Approval(address indexed src, address indexed guy, uint256 wad);\n\n    /// @notice Emitted when a transfer is made.\n    /// @param src The address that transferred the WETH.\n    /// @param dst The address that received the WETH.\n    /// @param wad The amount of WETH that was transferred.\n    event Transfer(address indexed src, address indexed dst, uint256 wad);\n\n    /// @notice Emitted when a deposit is made.\n    /// @param dst The address that deposited the WETH.\n    /// @param wad The amount of WETH that was deposited.\n    event Deposit(address indexed dst, uint256 wad);\n\n    /// @notice Emitted when a withdrawal is made.\n    /// @param src The address that withdrew the WETH.\n    /// @param wad The amount of WETH that was withdrawn.\n    event Withdrawal(address indexed src, uint256 wad);\n\n    /// @notice Returns the name of the token.\n    /// @return The name of the token.\n    function name() external pure returns (string memory);\n\n    /// @notice Returns the symbol of the token.\n    /// @return The symbol of the token.\n    function symbol() external pure returns (string memory);\n\n    /// @notice Returns the number of decimals the token uses.\n    /// @return The number of decimals the token uses.\n    function decimals() external pure returns (uint8);\n\n    /// @notice Returns the balance of the given address.\n    /// @param owner The address to query the balance of.\n    /// @return The balance of the given address.\n    function balanceOf(address owner) external view returns (uint256);\n\n    /// @notice Returns the amount of WETH that the spender can transfer on behalf of the owner.\n    /// @param owner The address that owns the WETH.\n    /// @param spender The address that is approved to transfer the WETH.\n    /// @return The amount of WETH that the spender can transfer on behalf of the owner.\n    function allowance(address owner, address spender) external view returns (uint256);\n\n    /// @notice Allows WETH to be deposited by sending ether to the contract.\n    function deposit() external payable;\n\n    /// @notice Withdraws an amount of ETH.\n    /// @param wad The amount of ETH to withdraw.\n    function withdraw(uint256 wad) external;\n\n    /// @notice Returns the total supply of WETH.\n    /// @return The total supply of WETH.\n    function totalSupply() external view returns (uint256);\n\n    /// @notice Approves the given address to transfer the WETH on behalf of the caller.\n    /// @param guy The address that is approved to transfer the WETH.\n    /// @param wad The amount that is approved to transfer.\n    /// @return True if the approval was successful.\n    function approve(address guy, uint256 wad) external returns (bool);\n\n    /// @notice Transfers the given amount of WETH to the given address.\n    /// @param dst The address to transfer the WETH to.\n    /// @param wad The amount of WETH to transfer.\n    /// @return True if the transfer was successful.\n    function transfer(address dst, uint256 wad) external returns (bool);\n\n    /// @notice Transfers the given amount of WETH from the given address to the given address.\n    /// @param src The address to transfer the WETH from.\n    /// @param dst The address to transfer the WETH to.\n    /// @param wad The amount of WETH to transfer.\n    /// @return True if the transfer was successful.\n    function transferFrom(address src, address dst, uint256 wad) external returns (bool);\n}\n"
      },
      "src/dispute/weth/WETH98.sol": {
        "content": "// Copyright (C) 2015, 2016, 2017 Dapphub\n\n// This program is free software: you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation, either version 3 of the License, or\n// (at your option) any later version.\n\n// This program is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n// GNU General Public License for more details.\n\n// You should have received a copy of the GNU General Public License\n// along with this program.  If not, see <http://www.gnu.org/licenses/>.\n\n// Based on WETH9 by Dapphub.\n// Modified by OP Labs.\n\npragma solidity 0.8.15;\n\nimport { IWETH } from \"src/dispute/interfaces/IWETH.sol\";\n\n/// @title WETH98\n/// @notice WETH98 is a version of WETH9 upgraded for Solidity 0.8.x.\ncontract WETH98 is IWETH {\n    string public constant name = \"Wrapped Ether\";\n    string public constant symbol = \"WETH\";\n    uint8 public constant decimals = 18;\n\n    mapping(address => uint256) public balanceOf;\n    mapping(address => mapping(address => uint256)) public allowance;\n\n    /// @notice Pipes to deposit.\n    receive() external payable {\n        deposit();\n    }\n\n    /// @inheritdoc IWETH\n    function deposit() public payable {\n        balanceOf[msg.sender] += msg.value;\n        emit Deposit(msg.sender, msg.value);\n    }\n\n    /// @inheritdoc IWETH\n    function withdraw(uint256 wad) public virtual {\n        require(balanceOf[msg.sender] >= wad);\n        balanceOf[msg.sender] -= wad;\n        payable(msg.sender).transfer(wad);\n        emit Withdrawal(msg.sender, wad);\n    }\n\n    /// @inheritdoc IWETH\n    function totalSupply() external view returns (uint256) {\n        return address(this).balance;\n    }\n\n    /// @inheritdoc IWETH\n    function approve(address guy, uint256 wad) external returns (bool) {\n        allowance[msg.sender][guy] = wad;\n        emit Approval(msg.sender, guy, wad);\n        return true;\n    }\n\n    /// @inheritdoc IWETH\n    function transfer(address dst, uint256 wad) external returns (bool) {\n        return transferFrom(msg.sender, dst, wad);\n    }\n\n    /// @inheritdoc IWETH\n    function transferFrom(address src, address dst, uint256 wad) public returns (bool) {\n        require(balanceOf[src] >= wad);\n\n        if (src != msg.sender && allowance[src][msg.sender] != type(uint256).max) {\n            require(allowance[src][msg.sender] >= wad);\n            allowance[src][msg.sender] -= wad;\n        }\n\n        balanceOf[src] -= wad;\n        balanceOf[dst] += wad;\n\n        emit Transfer(src, dst, wad);\n\n        return true;\n    }\n}\n"
      },
      "src/L1/SuperchainConfig.sol": {
        "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { Initializable } from \"@openzeppelin/contracts/proxy/utils/Initializable.sol\";\nimport { ISemver } from \"src/universal/ISemver.sol\";\nimport { Storage } from \"src/libraries/Storage.sol\";\n\n/// @custom:audit none This contracts is not yet audited.\n/// @title SuperchainConfig\n/// @notice The SuperchainConfig contract is used to manage configuration of global superchain values.\ncontract SuperchainConfig is Initializable, ISemver {\n    /// @notice Enum representing different types of updates.\n    /// @custom:value GUARDIAN            Represents an update to the guardian.\n    enum UpdateType {\n        GUARDIAN\n    }\n\n    /// @notice Whether or not the Superchain is paused.\n    bytes32 public constant PAUSED_SLOT = bytes32(uint256(keccak256(\"superchainConfig.paused\")) - 1);\n\n    /// @notice The address of the guardian, which can pause withdrawals from the System.\n    ///         It can only be modified by an upgrade.\n    bytes32 public constant GUARDIAN_SLOT = bytes32(uint256(keccak256(\"superchainConfig.guardian\")) - 1);\n\n    /// @notice Emitted when the pause is triggered.\n    /// @param identifier A string helping to identify provenance of the pause transaction.\n    event Paused(string identifier);\n\n    /// @notice Emitted when the pause is lifted.\n    event Unpaused();\n\n    /// @notice Emitted when configuration is updated.\n    /// @param updateType Type of update.\n    /// @param data       Encoded update data.\n    event ConfigUpdate(UpdateType indexed updateType, bytes data);\n\n    /// @notice Semantic version.\n    /// @custom:semver 1.1.0\n    string public constant version = \"1.1.0\";\n\n    /// @notice Constructs the SuperchainConfig contract.\n    constructor() {\n        initialize({ _guardian: address(0), _paused: false });\n    }\n\n    /// @notice Initializer.\n    /// @param _guardian    Address of the guardian, can pause the OptimismPortal.\n    /// @param _paused      Initial paused status.\n    function initialize(address _guardian, bool _paused) public initializer {\n        _setGuardian(_guardian);\n        if (_paused) {\n            _pause(\"Initializer paused\");\n        }\n    }\n\n    /// @notice Getter for the guardian address.\n    function guardian() public view returns (address guardian_) {\n        guardian_ = Storage.getAddress(GUARDIAN_SLOT);\n    }\n\n    /// @notice Getter for the current paused status.\n    function paused() public view returns (bool paused_) {\n        paused_ = Storage.getBool(PAUSED_SLOT);\n    }\n\n    /// @notice Pauses withdrawals.\n    /// @param _identifier (Optional) A string to identify provenance of the pause transaction.\n    function pause(string memory _identifier) external {\n        require(msg.sender == guardian(), \"SuperchainConfig: only guardian can pause\");\n        _pause(_identifier);\n    }\n\n    /// @notice Pauses withdrawals.\n    /// @param _identifier (Optional) A string to identify provenance of the pause transaction.\n    function _pause(string memory _identifier) internal {\n        Storage.setBool(PAUSED_SLOT, true);\n        emit Paused(_identifier);\n    }\n\n    /// @notice Unpauses withdrawals.\n    function unpause() external {\n        require(msg.sender == guardian(), \"SuperchainConfig: only guardian can unpause\");\n        Storage.setBool(PAUSED_SLOT, false);\n        emit Unpaused();\n    }\n\n    /// @notice Sets the guardian address. This is only callable during initialization, so an upgrade\n    ///         will be required to change the guardian.\n    /// @param _guardian The new guardian address.\n    function _setGuardian(address _guardian) internal {\n        Storage.setAddress(GUARDIAN_SLOT, _guardian);\n        emit ConfigUpdate(UpdateType.GUARDIAN, abi.encode(_guardian));\n    }\n}\n"
      },
      "lib/openzeppelin-contracts-upgradeable/contracts/utils/ContextUpgradeable.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n\npragma solidity ^0.8.0;\nimport \"../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n    function __Context_init() internal onlyInitializing {\n    }\n\n    function __Context_init_unchained() internal onlyInitializing {\n    }\n    function _msgSender() internal view virtual returns (address) {\n        return msg.sender;\n    }\n\n    function _msgData() internal view virtual returns (bytes calldata) {\n        return msg.data;\n    }\n\n    /**\n     * @dev This empty reserved space is put in place to allow future versions to add new\n     * variables without shifting down storage in the inheritance chain.\n     * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n     */\n    uint256[50] private __gap;\n}\n"
      },
      "lib/openzeppelin-contracts-upgradeable/contracts/proxy/utils/Initializable.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (proxy/utils/Initializable.sol)\n\npragma solidity ^0.8.2;\n\nimport \"../../utils/AddressUpgradeable.sol\";\n\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * contract MyToken is ERC20Upgradeable {\n *     function initialize() initializer public {\n *         __ERC20_init(\"MyToken\", \"MTK\");\n *     }\n * }\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n *     function initializeV2() reinitializer(2) public {\n *         __ERC20Permit_init(\"MyToken\");\n *     }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n *     _disableInitializers();\n * }\n * ```\n * ====\n */\nabstract contract Initializable {\n    /**\n     * @dev Indicates that the contract has been initialized.\n     * @custom:oz-retyped-from bool\n     */\n    uint8 private _initialized;\n\n    /**\n     * @dev Indicates that the contract is in the process of being initialized.\n     */\n    bool private _initializing;\n\n    /**\n     * @dev Triggered when the contract has been initialized or reinitialized.\n     */\n    event Initialized(uint8 version);\n\n    /**\n     * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n     * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\n     */\n    modifier initializer() {\n        bool isTopLevelCall = !_initializing;\n        require(\n            (isTopLevelCall && _initialized < 1) || (!AddressUpgradeable.isContract(address(this)) && _initialized == 1),\n            \"Initializable: contract is already initialized\"\n        );\n        _initialized = 1;\n        if (isTopLevelCall) {\n            _initializing = true;\n        }\n        _;\n        if (isTopLevelCall) {\n            _initializing = false;\n            emit Initialized(1);\n        }\n    }\n\n    /**\n     * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n     * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n     * used to initialize parent contracts.\n     *\n     * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\n     * initialization step. This is essential to configure modules that are added through upgrades and that require\n     * initialization.\n     *\n     * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n     * a contract, executing them in the right order is up to the developer or operator.\n     */\n    modifier reinitializer(uint8 version) {\n        require(!_initializing && _initialized < version, \"Initializable: contract is already initialized\");\n        _initialized = version;\n        _initializing = true;\n        _;\n        _initializing = false;\n        emit Initialized(version);\n    }\n\n    /**\n     * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n     * {initializer} and {reinitializer} modifiers, directly or indirectly.\n     */\n    modifier onlyInitializing() {\n        require(_initializing, \"Initializable: contract is not initializing\");\n        _;\n    }\n\n    /**\n     * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n     * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n     * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n     * through proxies.\n     */\n    function _disableInitializers() internal virtual {\n        require(!_initializing, \"Initializable: contract is initializing\");\n        if (_initialized < type(uint8).max) {\n            _initialized = type(uint8).max;\n            emit Initialized(type(uint8).max);\n        }\n    }\n}\n"
      },
      "lib/openzeppelin-contracts/contracts/proxy/utils/Initializable.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (proxy/utils/Initializable.sol)\n\npragma solidity ^0.8.2;\n\nimport \"../../utils/Address.sol\";\n\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * contract MyToken is ERC20Upgradeable {\n *     function initialize() initializer public {\n *         __ERC20_init(\"MyToken\", \"MTK\");\n *     }\n * }\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n *     function initializeV2() reinitializer(2) public {\n *         __ERC20Permit_init(\"MyToken\");\n *     }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n *     _disableInitializers();\n * }\n * ```\n * ====\n */\nabstract contract Initializable {\n    /**\n     * @dev Indicates that the contract has been initialized.\n     * @custom:oz-retyped-from bool\n     */\n    uint8 private _initialized;\n\n    /**\n     * @dev Indicates that the contract is in the process of being initialized.\n     */\n    bool private _initializing;\n\n    /**\n     * @dev Triggered when the contract has been initialized or reinitialized.\n     */\n    event Initialized(uint8 version);\n\n    /**\n     * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n     * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\n     */\n    modifier initializer() {\n        bool isTopLevelCall = !_initializing;\n        require(\n            (isTopLevelCall && _initialized < 1) || (!Address.isContract(address(this)) && _initialized == 1),\n            \"Initializable: contract is already initialized\"\n        );\n        _initialized = 1;\n        if (isTopLevelCall) {\n            _initializing = true;\n        }\n        _;\n        if (isTopLevelCall) {\n            _initializing = false;\n            emit Initialized(1);\n        }\n    }\n\n    /**\n     * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n     * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n     * used to initialize parent contracts.\n     *\n     * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\n     * initialization step. This is essential to configure modules that are added through upgrades and that require\n     * initialization.\n     *\n     * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n     * a contract, executing them in the right order is up to the developer or operator.\n     */\n    modifier reinitializer(uint8 version) {\n        require(!_initializing && _initialized < version, \"Initializable: contract is already initialized\");\n        _initialized = version;\n        _initializing = true;\n        _;\n        _initializing = false;\n        emit Initialized(version);\n    }\n\n    /**\n     * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n     * {initializer} and {reinitializer} modifiers, directly or indirectly.\n     */\n    modifier onlyInitializing() {\n        require(_initializing, \"Initializable: contract is not initializing\");\n        _;\n    }\n\n    /**\n     * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n     * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n     * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n     * through proxies.\n     */\n    function _disableInitializers() internal virtual {\n        require(!_initializing, \"Initializable: contract is initializing\");\n        if (_initialized < type(uint8).max) {\n            _initialized = type(uint8).max;\n            emit Initialized(type(uint8).max);\n        }\n    }\n}\n"
      },
      "src/libraries/Storage.sol": {
        "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\n/// @title Storage\n/// @notice Storage handles reading and writing to arbitary storage locations\nlibrary Storage {\n    /// @notice Returns an address stored in an arbitrary storage slot.\n    ///         These storage slots decouple the storage layout from\n    ///         solc's automation.\n    /// @param _slot The storage slot to retrieve the address from.\n    function getAddress(bytes32 _slot) internal view returns (address addr_) {\n        assembly {\n            addr_ := sload(_slot)\n        }\n    }\n\n    /// @notice Stores an address in an arbitrary storage slot, `_slot`.\n    /// @param _slot The storage slot to store the address in.\n    /// @param _address The protocol version to store\n    /// @dev WARNING! This function must be used cautiously, as it allows for overwriting addresses\n    ///      in arbitrary storage slots.\n    function setAddress(bytes32 _slot, address _address) internal {\n        assembly {\n            sstore(_slot, _address)\n        }\n    }\n\n    /// @notice Returns a uint256 stored in an arbitrary storage slot.\n    ///         These storage slots decouple the storage layout from\n    ///         solc's automation.\n    /// @param _slot The storage slot to retrieve the address from.\n    function getUint(bytes32 _slot) internal view returns (uint256 value_) {\n        assembly {\n            value_ := sload(_slot)\n        }\n    }\n\n    /// @notice Stores a value in an arbitrary storage slot, `_slot`.\n    /// @param _slot The storage slot to store the address in.\n    /// @param _value The protocol version to store\n    /// @dev WARNING! This function must be used cautiously, as it allows for overwriting values\n    ///      in arbitrary storage slots.\n    function setUint(bytes32 _slot, uint256 _value) internal {\n        assembly {\n            sstore(_slot, _value)\n        }\n    }\n\n    /// @notice Returns a bytes32 stored in an arbitrary storage slot.\n    ///         These storage slots decouple the storage layout from\n    ///         solc's automation.\n    /// @param _slot The storage slot to retrieve the address from.\n    function getBytes32(bytes32 _slot) internal view returns (bytes32 value_) {\n        assembly {\n            value_ := sload(_slot)\n        }\n    }\n\n    /// @notice Stores a bytes32 value in an arbitrary storage slot, `_slot`.\n    /// @param _slot The storage slot to store the address in.\n    /// @param _value The bytes32 value to store.\n    /// @dev WARNING! This function must be used cautiously, as it allows for overwriting values\n    ///      in arbitrary storage slots.\n    function setBytes32(bytes32 _slot, bytes32 _value) internal {\n        assembly {\n            sstore(_slot, _value)\n        }\n    }\n\n    /// @notice Stores a bool value in an arbitrary storage slot, `_slot`.\n    /// @param _slot The storage slot to store the bool in.\n    /// @param _value The bool value to store\n    /// @dev WARNING! This function must be used cautiously, as it allows for overwriting values\n    ///      in arbitrary storage slots.\n    function setBool(bytes32 _slot, bool _value) internal {\n        assembly {\n            sstore(_slot, _value)\n        }\n    }\n\n    /// @notice Returns a bool stored in an arbitrary storage slot.\n    /// @param _slot The storage slot to retrieve the bool from.\n    function getBool(bytes32 _slot) internal view returns (bool value_) {\n        assembly {\n            value_ := sload(_slot)\n        }\n    }\n}\n"
      },
      "lib/openzeppelin-contracts-upgradeable/contracts/utils/AddressUpgradeable.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Address.sol)\n\npragma solidity ^0.8.1;\n\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\n    /**\n     * @dev Returns true if `account` is a contract.\n     *\n     * [IMPORTANT]\n     * ====\n     * It is unsafe to assume that an address for which this function returns\n     * false is an externally-owned account (EOA) and not a contract.\n     *\n     * Among others, `isContract` will return false for the following\n     * types of addresses:\n     *\n     *  - an externally-owned account\n     *  - a contract in construction\n     *  - an address where a contract will be created\n     *  - an address where a contract lived, but was destroyed\n     * ====\n     *\n     * [IMPORTANT]\n     * ====\n     * You shouldn't rely on `isContract` to protect against flash loan attacks!\n     *\n     * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n     * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n     * constructor.\n     * ====\n     */\n    function isContract(address account) internal view returns (bool) {\n        // This method relies on extcodesize/address.code.length, which returns 0\n        // for contracts in construction, since the code is only stored at the end\n        // of the constructor execution.\n\n        return account.code.length > 0;\n    }\n\n    /**\n     * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n     * `recipient`, forwarding all available gas and reverting on errors.\n     *\n     * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n     * of certain opcodes, possibly making contracts go over the 2300 gas limit\n     * imposed by `transfer`, making them unable to receive funds via\n     * `transfer`. {sendValue} removes this limitation.\n     *\n     * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n     *\n     * IMPORTANT: because control is transferred to `recipient`, care must be\n     * taken to not create reentrancy vulnerabilities. Consider using\n     * {ReentrancyGuard} or the\n     * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n     */\n    function sendValue(address payable recipient, uint256 amount) internal {\n        require(address(this).balance >= amount, \"Address: insufficient balance\");\n\n        (bool success, ) = recipient.call{value: amount}(\"\");\n        require(success, \"Address: unable to send value, recipient may have reverted\");\n    }\n\n    /**\n     * @dev Performs a Solidity function call using a low level `call`. A\n     * plain `call` is an unsafe replacement for a function call: use this\n     * function instead.\n     *\n     * If `target` reverts with a revert reason, it is bubbled up by this\n     * function (like regular Solidity function calls).\n     *\n     * Returns the raw returned data. To convert to the expected return value,\n     * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n     *\n     * Requirements:\n     *\n     * - `target` must be a contract.\n     * - calling `target` with `data` must not revert.\n     *\n     * _Available since v3.1._\n     */\n    function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n        return functionCall(target, data, \"Address: low-level call failed\");\n    }\n\n    /**\n     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n     * `errorMessage` as a fallback revert reason when `target` reverts.\n     *\n     * _Available since v3.1._\n     */\n    function functionCall(\n        address target,\n        bytes memory data,\n        string memory errorMessage\n    ) internal returns (bytes memory) {\n        return functionCallWithValue(target, data, 0, errorMessage);\n    }\n\n    /**\n     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n     * but also transferring `value` wei to `target`.\n     *\n     * Requirements:\n     *\n     * - the calling contract must have an ETH balance of at least `value`.\n     * - the called Solidity function must be `payable`.\n     *\n     * _Available since v3.1._\n     */\n    function functionCallWithValue(\n        address target,\n        bytes memory data,\n        uint256 value\n    ) internal returns (bytes memory) {\n        return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n    }\n\n    /**\n     * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n     * with `errorMessage` as a fallback revert reason when `target` reverts.\n     *\n     * _Available since v3.1._\n     */\n    function functionCallWithValue(\n        address target,\n        bytes memory data,\n        uint256 value,\n        string memory errorMessage\n    ) internal returns (bytes memory) {\n        require(address(this).balance >= value, \"Address: insufficient balance for call\");\n        require(isContract(target), \"Address: call to non-contract\");\n\n        (bool success, bytes memory returndata) = target.call{value: value}(data);\n        return verifyCallResult(success, returndata, errorMessage);\n    }\n\n    /**\n     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n     * but performing a static call.\n     *\n     * _Available since v3.3._\n     */\n    function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n        return functionStaticCall(target, data, \"Address: low-level static call failed\");\n    }\n\n    /**\n     * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n     * but performing a static call.\n     *\n     * _Available since v3.3._\n     */\n    function functionStaticCall(\n        address target,\n        bytes memory data,\n        string memory errorMessage\n    ) internal view returns (bytes memory) {\n        require(isContract(target), \"Address: static call to non-contract\");\n\n        (bool success, bytes memory returndata) = target.staticcall(data);\n        return verifyCallResult(success, returndata, errorMessage);\n    }\n\n    /**\n     * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n     * revert reason using the provided one.\n     *\n     * _Available since v4.3._\n     */\n    function verifyCallResult(\n        bool success,\n        bytes memory returndata,\n        string memory errorMessage\n    ) internal pure returns (bytes memory) {\n        if (success) {\n            return returndata;\n        } else {\n            // Look for revert reason and bubble it up if present\n            if (returndata.length > 0) {\n                // The easiest way to bubble the revert reason is using memory via assembly\n                /// @solidity memory-safe-assembly\n                assembly {\n                    let returndata_size := mload(returndata)\n                    revert(add(32, returndata), returndata_size)\n                }\n            } else {\n                revert(errorMessage);\n            }\n        }\n    }\n}\n"
      },
      "lib/openzeppelin-contracts/contracts/utils/Address.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Address.sol)\n\npragma solidity ^0.8.1;\n\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary Address {\n    /**\n     * @dev Returns true if `account` is a contract.\n     *\n     * [IMPORTANT]\n     * ====\n     * It is unsafe to assume that an address for which this function returns\n     * false is an externally-owned account (EOA) and not a contract.\n     *\n     * Among others, `isContract` will return false for the following\n     * types of addresses:\n     *\n     *  - an externally-owned account\n     *  - a contract in construction\n     *  - an address where a contract will be created\n     *  - an address where a contract lived, but was destroyed\n     * ====\n     *\n     * [IMPORTANT]\n     * ====\n     * You shouldn't rely on `isContract` to protect against flash loan attacks!\n     *\n     * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n     * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n     * constructor.\n     * ====\n     */\n    function isContract(address account) internal view returns (bool) {\n        // This method relies on extcodesize/address.code.length, which returns 0\n        // for contracts in construction, since the code is only stored at the end\n        // of the constructor execution.\n\n        return account.code.length > 0;\n    }\n\n    /**\n     * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n     * `recipient`, forwarding all available gas and reverting on errors.\n     *\n     * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n     * of certain opcodes, possibly making contracts go over the 2300 gas limit\n     * imposed by `transfer`, making them unable to receive funds via\n     * `transfer`. {sendValue} removes this limitation.\n     *\n     * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n     *\n     * IMPORTANT: because control is transferred to `recipient`, care must be\n     * taken to not create reentrancy vulnerabilities. Consider using\n     * {ReentrancyGuard} or the\n     * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n     */\n    function sendValue(address payable recipient, uint256 amount) internal {\n        require(address(this).balance >= amount, \"Address: insufficient balance\");\n\n        (bool success, ) = recipient.call{value: amount}(\"\");\n        require(success, \"Address: unable to send value, recipient may have reverted\");\n    }\n\n    /**\n     * @dev Performs a Solidity function call using a low level `call`. A\n     * plain `call` is an unsafe replacement for a function call: use this\n     * function instead.\n     *\n     * If `target` reverts with a revert reason, it is bubbled up by this\n     * function (like regular Solidity function calls).\n     *\n     * Returns the raw returned data. To convert to the expected return value,\n     * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n     *\n     * Requirements:\n     *\n     * - `target` must be a contract.\n     * - calling `target` with `data` must not revert.\n     *\n     * _Available since v3.1._\n     */\n    function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n        return functionCall(target, data, \"Address: low-level call failed\");\n    }\n\n    /**\n     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n     * `errorMessage` as a fallback revert reason when `target` reverts.\n     *\n     * _Available since v3.1._\n     */\n    function functionCall(\n        address target,\n        bytes memory data,\n        string memory errorMessage\n    ) internal returns (bytes memory) {\n        return functionCallWithValue(target, data, 0, errorMessage);\n    }\n\n    /**\n     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n     * but also transferring `value` wei to `target`.\n     *\n     * Requirements:\n     *\n     * - the calling contract must have an ETH balance of at least `value`.\n     * - the called Solidity function must be `payable`.\n     *\n     * _Available since v3.1._\n     */\n    function functionCallWithValue(\n        address target,\n        bytes memory data,\n        uint256 value\n    ) internal returns (bytes memory) {\n        return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n    }\n\n    /**\n     * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n     * with `errorMessage` as a fallback revert reason when `target` reverts.\n     *\n     * _Available since v3.1._\n     */\n    function functionCallWithValue(\n        address target,\n        bytes memory data,\n        uint256 value,\n        string memory errorMessage\n    ) internal returns (bytes memory) {\n        require(address(this).balance >= value, \"Address: insufficient balance for call\");\n        require(isContract(target), \"Address: call to non-contract\");\n\n        (bool success, bytes memory returndata) = target.call{value: value}(data);\n        return verifyCallResult(success, returndata, errorMessage);\n    }\n\n    /**\n     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n     * but performing a static call.\n     *\n     * _Available since v3.3._\n     */\n    function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n        return functionStaticCall(target, data, \"Address: low-level static call failed\");\n    }\n\n    /**\n     * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n     * but performing a static call.\n     *\n     * _Available since v3.3._\n     */\n    function functionStaticCall(\n        address target,\n        bytes memory data,\n        string memory errorMessage\n    ) internal view returns (bytes memory) {\n        require(isContract(target), \"Address: static call to non-contract\");\n\n        (bool success, bytes memory returndata) = target.staticcall(data);\n        return verifyCallResult(success, returndata, errorMessage);\n    }\n\n    /**\n     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n     * but performing a delegate call.\n     *\n     * _Available since v3.4._\n     */\n    function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\n        return functionDelegateCall(target, data, \"Address: low-level delegate call failed\");\n    }\n\n    /**\n     * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n     * but performing a delegate call.\n     *\n     * _Available since v3.4._\n     */\n    function functionDelegateCall(\n        address target,\n        bytes memory data,\n        string memory errorMessage\n    ) internal returns (bytes memory) {\n        require(isContract(target), \"Address: delegate call to non-contract\");\n\n        (bool success, bytes memory returndata) = target.delegatecall(data);\n        return verifyCallResult(success, returndata, errorMessage);\n    }\n\n    /**\n     * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n     * revert reason using the provided one.\n     *\n     * _Available since v4.3._\n     */\n    function verifyCallResult(\n        bool success,\n        bytes memory returndata,\n        string memory errorMessage\n    ) internal pure returns (bytes memory) {\n        if (success) {\n            return returndata;\n        } else {\n            // Look for revert reason and bubble it up if present\n            if (returndata.length > 0) {\n                // The easiest way to bubble the revert reason is using memory via assembly\n                /// @solidity memory-safe-assembly\n                assembly {\n                    let returndata_size := mload(returndata)\n                    revert(add(32, returndata), returndata_size)\n                }\n            } else {\n                revert(errorMessage);\n            }\n        }\n    }\n}\n"
      }
    },
    "settings": {
      "remappings": [
        "@openzeppelin/contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/contracts/",
        "@openzeppelin/contracts/=lib/openzeppelin-contracts/contracts/",
        "@rari-capital/solmate/=lib/solmate/",
        "@cwia/=lib/clones-with-immutable-args/src/",
        "@lib-keccak/=lib/lib-keccak/contracts/lib/",
        "forge-std/=lib/forge-std/src/",
        "ds-test/=lib/forge-std/lib/ds-test/src/",
        "safe-contracts/=lib/safe-contracts/contracts/",
        "kontrol-cheatcodes/=lib/kontrol-cheatcodes/src/",
        "solady/=lib/solady/src/",
        "@solady-test/=lib/lib-keccak/lib/solady/test/",
        "@solady/=lib/lib-keccak/lib/solady/src/",
        "clones-with-immutable-args/=lib/clones-with-immutable-args/src/",
        "lib-keccak/=lib/lib-keccak/contracts/",
        "openzeppelin-contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/",
        "openzeppelin-contracts/=lib/openzeppelin-contracts/",
        "solmate/=lib/solmate/src/"
      ],
      "optimizer": {
        "enabled": true,
        "runs": 999999
      },
      "metadata": {
        "useLiteralContent": false,
        "bytecodeHash": "none"
      },
      "outputSelection": {
        "*": {
          "*": [
            "evm.bytecode",
            "evm.deployedBytecode",
            "devdoc",
            "userdoc",
            "metadata",
            "abi"
          ]
        }
      },
      "evmVersion": "london",
      "viaIR": false,
      "libraries": {}
    }
  }}