creation_sourcecode: {{
    "language": "Solidity",
    "sources": {
      "solidity/contracts/ConnextVestingWallet.sol": {
        "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.20;\n\nimport {Ownable} from '@openzeppelin/contracts/access/Ownable.sol';\nimport {Ownable2Step} from '@openzeppelin/contracts/access/Ownable2Step.sol';\nimport {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol';\n\nimport {IConnextVestingWallet} from 'interfaces/IConnextVestingWallet.sol';\nimport {IVestingEscrowSimple} from 'interfaces/IVestingEscrowSimple.sol';\n\n/**\n * @title   ConnextVestingWallet\n * NOTE:    The NEXT tokens will be subject to a twenty-four (24) months unlock schedule as follows:\n *          1/13 (~7.69% of the token grant) unlocks at the 1 year mark from NEXT token launch,\n *          and 1/13 unlocks every month thereafter for 12 months. All tokens are unlocked after 24 months.\n *          https://forum.connext.network/t/rfc-partnership-token-agreements/938\n */\ncontract ConnextVestingWallet is Ownable2Step, IConnextVestingWallet {\n  /// @inheritdoc IConnextVestingWallet\n  uint64 public constant ONE_YEAR = 365 days;\n\n  /// @inheritdoc IConnextVestingWallet\n  uint64 public constant ONE_MONTH = ONE_YEAR / 12;\n\n  /// @inheritdoc IConnextVestingWallet\n  uint64 public constant SEPT_05_2023 = 1_693_872_000;\n\n  /// @inheritdoc IConnextVestingWallet\n  uint64 public constant NEXT_TOKEN_LAUNCH = SEPT_05_2023; // Equals to Sept 5th 2023\n\n  /// @inheritdoc IConnextVestingWallet\n  IERC20 public constant NEXT_TOKEN = IERC20(0xFE67A4450907459c3e1FFf623aA927dD4e28c67a); // Mainnet NEXT token address\n\n  /// @inheritdoc IConnextVestingWallet\n  uint64 public constant UNLOCK_DURATION = ONE_YEAR + ONE_MONTH; // 13 months duration\n\n  /// @inheritdoc IConnextVestingWallet\n  uint64 public constant UNLOCK_CLIFF_DURATION = ONE_MONTH; // 1 month cliff\n\n  /// @inheritdoc IConnextVestingWallet\n  uint64 public constant UNLOCK_OFFSET = ONE_YEAR - ONE_MONTH; // 11 months offset\n\n  /// @inheritdoc IConnextVestingWallet\n  uint64 public constant UNLOCK_START = NEXT_TOKEN_LAUNCH + UNLOCK_OFFSET; // Sept 5th 2024 - 1 month\n\n  /// @inheritdoc IConnextVestingWallet\n  uint64 public constant UNLOCK_CLIFF = UNLOCK_START + UNLOCK_CLIFF_DURATION; // Sept 5th 2024\n\n  /// @inheritdoc IConnextVestingWallet\n  uint64 public constant UNLOCK_END = UNLOCK_START + UNLOCK_DURATION; // Sept 5th 2025\n\n  /// @inheritdoc IConnextVestingWallet\n  uint256 public immutable TOTAL_AMOUNT; // Set into constructor\n\n  /// @inheritdoc IConnextVestingWallet\n  uint256 public released;\n\n  /**\n   * @param _owner The address of the beneficiary\n   * @param _totalAmount The total amount of tokens to be unlocked\n   */\n  constructor(address _owner, uint256 _totalAmount) Ownable(_owner) {\n    TOTAL_AMOUNT = _totalAmount;\n  }\n\n  /**\n   * NOTE:  The equivalent unlock schedule has a 13 months duration, with a 1 month cliff,\n   *        offsetted to start from `Sept 5th 2024 - 1 month`: At Sept 5th 2024 the cliff\n   *        is triggered unlocking 1/13 of the tokens, and then 1/13 of the tokens will\n   *        be linearly unlocked every month after that.\n   */\n\n  /// @inheritdoc IConnextVestingWallet\n  function vestedAmount(uint64 _timestamp) public view returns (uint256 _amount) {\n    if (_timestamp < UNLOCK_CLIFF) {\n      return 0;\n    } else if (_timestamp >= UNLOCK_END) {\n      return TOTAL_AMOUNT;\n    } else {\n      return (TOTAL_AMOUNT * (_timestamp - UNLOCK_START)) / UNLOCK_DURATION;\n    }\n  }\n\n  /// @inheritdoc IConnextVestingWallet\n  function release() public {\n    uint256 _amount = releasable();\n    released += _amount;\n    NEXT_TOKEN.transfer(owner(), _amount);\n    emit ERC20Released(address(NEXT_TOKEN), _amount);\n  }\n\n  /// @inheritdoc IConnextVestingWallet\n  function releasable() public view returns (uint256 _amount) {\n    _amount = vestedAmount(uint64(block.timestamp)) - released;\n    uint256 _balance = NEXT_TOKEN.balanceOf(address(this));\n    _amount = _balance < _amount ? _balance : _amount;\n  }\n\n  /**\n   * @inheritdoc IConnextVestingWallet\n   * @dev This contract allows to withdraw any token, with the exception of unlocked NEXT tokens\n   */\n  function sendDust(IERC20 _token, uint256 _amount, address _to) external onlyOwner {\n    if (_to == address(0)) revert ZeroAddress();\n\n    if (_token == NEXT_TOKEN && (released != TOTAL_AMOUNT || block.timestamp < UNLOCK_END)) {\n      revert NotAllowed();\n    }\n\n    if (_token == IERC20(0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE)) {\n      payable(_to).transfer(_amount); // Sending ETH\n    } else {\n      _token.transfer(_to, _amount); // Sending ERC20s\n    }\n  }\n\n  /**\n   * @inheritdoc IConnextVestingWallet\n   * @dev This func is needed because only the recipients can claim\n   */\n  function claim(IVestingEscrowSimple _vestingEscrow) external {\n    _vestingEscrow.claim(address(this));\n  }\n}\n"
      },
      "node_modules/@openzeppelin/contracts/access/Ownable.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.0.0) (access/Ownable.sol)\n\npragma solidity ^0.8.20;\n\nimport {Context} from \"../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 * The initial owner is set to the address provided by the deployer. This can\n * 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    /**\n     * @dev The caller account is not authorized to perform an operation.\n     */\n    error OwnableUnauthorizedAccount(address account);\n\n    /**\n     * @dev The owner is not a valid owner account. (eg. `address(0)`)\n     */\n    error OwnableInvalidOwner(address owner);\n\n    event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n    /**\n     * @dev Initializes the contract setting the address provided by the deployer as the initial owner.\n     */\n    constructor(address initialOwner) {\n        if (initialOwner == address(0)) {\n            revert OwnableInvalidOwner(address(0));\n        }\n        _transferOwnership(initialOwner);\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        if (owner() != _msgSender()) {\n            revert OwnableUnauthorizedAccount(_msgSender());\n        }\n    }\n\n    /**\n     * @dev Leaves the contract without owner. It will not be possible to call\n     * `onlyOwner` functions. Can only be called by the current owner.\n     *\n     * NOTE: Renouncing ownership will leave the contract without an owner,\n     * thereby disabling 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        if (newOwner == address(0)) {\n            revert OwnableInvalidOwner(address(0));\n        }\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"
      },
      "node_modules/@openzeppelin/contracts/access/Ownable2Step.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.0.0) (access/Ownable2Step.sol)\n\npragma solidity ^0.8.20;\n\nimport {Ownable} from \"./Ownable.sol\";\n\n/**\n * @dev Contract module which provides access control mechanism, where\n * there is an account (an owner) that can be granted exclusive access to\n * specific functions.\n *\n * The initial owner is specified at deployment time in the constructor for `Ownable`. This\n * can later be changed with {transferOwnership} and {acceptOwnership}.\n *\n * This module is used through inheritance. It will make available all functions\n * from parent (Ownable).\n */\nabstract contract Ownable2Step is Ownable {\n    address private _pendingOwner;\n\n    event OwnershipTransferStarted(address indexed previousOwner, address indexed newOwner);\n\n    /**\n     * @dev Returns the address of the pending owner.\n     */\n    function pendingOwner() public view virtual returns (address) {\n        return _pendingOwner;\n    }\n\n    /**\n     * @dev Starts the ownership transfer of the contract to a new account. Replaces the pending transfer if there is one.\n     * Can only be called by the current owner.\n     */\n    function transferOwnership(address newOwner) public virtual override onlyOwner {\n        _pendingOwner = newOwner;\n        emit OwnershipTransferStarted(owner(), newOwner);\n    }\n\n    /**\n     * @dev Transfers ownership of the contract to a new account (`newOwner`) and deletes any pending owner.\n     * Internal function without access restriction.\n     */\n    function _transferOwnership(address newOwner) internal virtual override {\n        delete _pendingOwner;\n        super._transferOwnership(newOwner);\n    }\n\n    /**\n     * @dev The new owner accepts the ownership transfer.\n     */\n    function acceptOwnership() public virtual {\n        address sender = _msgSender();\n        if (pendingOwner() != sender) {\n            revert OwnableUnauthorizedAccount(sender);\n        }\n        _transferOwnership(sender);\n    }\n}\n"
      },
      "node_modules/@openzeppelin/contracts/token/ERC20/IERC20.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.0.0) (token/ERC20/IERC20.sol)\n\npragma solidity ^0.8.20;\n\n/**\n * @dev Interface of the ERC20 standard as defined in the EIP.\n */\ninterface IERC20 {\n    /**\n     * @dev Emitted when `value` tokens are moved from one account (`from`) to\n     * another (`to`).\n     *\n     * Note that `value` may be zero.\n     */\n    event Transfer(address indexed from, address indexed to, uint256 value);\n\n    /**\n     * @dev Emitted when the allowance of a `spender` for an `owner` is set by\n     * a call to {approve}. `value` is the new allowance.\n     */\n    event Approval(address indexed owner, address indexed spender, uint256 value);\n\n    /**\n     * @dev Returns the value of tokens in existence.\n     */\n    function totalSupply() external view returns (uint256);\n\n    /**\n     * @dev Returns the value of tokens owned by `account`.\n     */\n    function balanceOf(address account) external view returns (uint256);\n\n    /**\n     * @dev Moves a `value` amount of tokens from the caller's account to `to`.\n     *\n     * Returns a boolean value indicating whether the operation succeeded.\n     *\n     * Emits a {Transfer} event.\n     */\n    function transfer(address to, uint256 value) external returns (bool);\n\n    /**\n     * @dev Returns the remaining number of tokens that `spender` will be\n     * allowed to spend on behalf of `owner` through {transferFrom}. This is\n     * zero by default.\n     *\n     * This value changes when {approve} or {transferFrom} are called.\n     */\n    function allowance(address owner, address spender) external view returns (uint256);\n\n    /**\n     * @dev Sets a `value` amount of tokens as the allowance of `spender` over the\n     * caller's tokens.\n     *\n     * Returns a boolean value indicating whether the operation succeeded.\n     *\n     * IMPORTANT: Beware that changing an allowance with this method brings the risk\n     * that someone may use both the old and the new allowance by unfortunate\n     * transaction ordering. One possible solution to mitigate this race\n     * condition is to first reduce the spender's allowance to 0 and set the\n     * desired value afterwards:\n     * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\n     *\n     * Emits an {Approval} event.\n     */\n    function approve(address spender, uint256 value) external returns (bool);\n\n    /**\n     * @dev Moves a `value` amount of tokens from `from` to `to` using the\n     * allowance mechanism. `value` is then deducted from the caller's\n     * allowance.\n     *\n     * Returns a boolean value indicating whether the operation succeeded.\n     *\n     * Emits a {Transfer} event.\n     */\n    function transferFrom(address from, address to, uint256 value) external returns (bool);\n}\n"
      },
      "solidity/interfaces/IConnextVestingWallet.sol": {
        "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.20;\n\nimport {IVestingEscrowSimple} from './IVestingEscrowSimple.sol';\nimport {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol';\n\ninterface IConnextVestingWallet {\n  /*///////////////////////////////////////////////////////////////\n                             EVENTS\n  //////////////////////////////////////////////////////////////*/\n\n  /**\n   * @notice Emits when the owner releases tokens\n   * @param _token  The address of the released ERC20 token\n   * @param _amount The amount of tokens released\n   */\n  event ERC20Released(address indexed _token, uint256 _amount);\n\n  /*///////////////////////////////////////////////////////////////\n                             ERRRORS\n  //////////////////////////////////////////////////////////////*/\n\n  /**\n   * @notice Permission denied\n   */\n  error NotAllowed();\n\n  /**\n   * @notice Zero address not allowed\n   */\n  error ZeroAddress();\n\n  /*///////////////////////////////////////////////////////////////\n                            CONSTANTS\n  //////////////////////////////////////////////////////////////*/\n\n  /**\n   * @notice NEXT token address\n   * @return _nextToken The address of the NEXT token\n   */\n  function NEXT_TOKEN() external view returns (IERC20 _nextToken);\n\n  /**\n   * @notice Token launch date\n   * @return _timestamp The timestamp of the token launch\n   */\n  function NEXT_TOKEN_LAUNCH() external view returns (uint64 _timestamp);\n\n  /**\n   * @notice 1 month in seconds (on average)\n   * @return _timedelta The timedelta of one month\n   */\n  function ONE_MONTH() external view returns (uint64 _timedelta);\n\n  /**\n   * @notice 1 year in seconds\n   * @return _timedelta The timedelta of one year\n   */\n  function ONE_YEAR() external view returns (uint64 _timedelta);\n\n  /**\n   * @notice Sept 5th 2023 in seconds\n   * @return _timestamp The timestamp of Sept 5th 2023\n   */\n  function SEPT_05_2023() external view returns (uint64 _timestamp);\n\n  /**\n   * @notice Vesting cliff duration\n   * @return _timedelta The timedelta of the cliff duration\n   */\n  function UNLOCK_CLIFF_DURATION() external view returns (uint64 _timedelta);\n\n  /**\n   * @notice Vesting duration including cliff duration\n   * @return _timedelta The timedelta of the vesting duration\n   */\n  function UNLOCK_DURATION() external view returns (uint64 _timedelta);\n\n  /**\n   * @notice Vesting warmup time\n   * @return _timedelta The timedelta of the warmup time\n   */\n  function UNLOCK_OFFSET() external view returns (uint64 _timedelta);\n\n  /**\n   * @notice Vesting start date\n   * @return _timestamp The timestamp of the start date\n   */\n  function UNLOCK_START() external view returns (uint64 _timestamp);\n\n  /**\n   * @notice Vesting cliff date\n   * @return _timestamp The timestamp of the cliff date\n   */\n  function UNLOCK_CLIFF() external view returns (uint64 _timestamp);\n\n  /**\n   * @notice Vesting end date\n   * @return _timestamp The timestamp of the end date\n   */\n  function UNLOCK_END() external view returns (uint64 _timestamp);\n\n  /*///////////////////////////////////////////////////////////////\n                             STORAGE\n  //////////////////////////////////////////////////////////////*/\n\n  /**\n   * @notice Total amount of tokens to be vested\n   * @return _amount The total amount of tokens\n   */\n  function TOTAL_AMOUNT() external view returns (uint256 _amount);\n\n  /**\n   * @notice The amount of NEXT tokens that are already released\n   * @return _released The amount of tokens released\n   */\n  function released() external view returns (uint256 _released);\n\n  /*///////////////////////////////////////////////////////////////\n                            UNLOCK LOGIC\n  //////////////////////////////////////////////////////////////*/\n\n  /**\n   * @notice Claim tokens from Yearn Vesting Escrow contract\n   * @param _vestingEscrow  The address of the Yearn Vesting Escrow contract\n   */\n  function claim(IVestingEscrowSimple _vestingEscrow) external;\n\n  /**\n   * @notice Collect dust from the contract\n   * @param _token  The address of the token to withdraw\n   * @param _amount The amount of tokens to withdraw\n   * @param _to     The address to send the tokens to\n   */\n  function sendDust(IERC20 _token, uint256 _amount, address _to) external;\n\n  /**\n   * @notice Release releasable NEXT tokens to the owner\n   */\n  function release() external;\n\n  /**\n   * @notice Calculate the amount of NEXT tokens vested at a given timestamp\n   * @param _timestamp  The timestamp to calculate the vested amount\n   * @return _amount The amount of tokens vested\n   */\n  function vestedAmount(uint64 _timestamp) external view returns (uint256 _amount);\n\n  /**\n   * @notice Calculate the amount of NEXT tokens ready to release\n   * @return _amount The amount of tokens ready to release\n   */\n  function releasable() external view returns (uint256 _amount);\n}\n"
      },
      "solidity/interfaces/IVestingEscrowSimple.sol": {
        "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.20;\n\ninterface IVestingEscrowSimple {\n  /**\n   * @notice Initialize the contract.\n   * @dev This function is seperate from `constructor` because of the factory pattern\n   * used in `VestingEscrowFactory.deploy_vesting_contract`. It may be called once per deployment.\n   * @param _owner Owner address\n   * @param _token Address of the ERC20 token being distributed\n   * @param _recipient Address to vest tokens for\n   * @param _amount Amount of tokens being vested for `recipient`\n   * @param _startTime Epoch time at which token distribution starts\n   * @param _endTime Time until everything should be vested\n   * @param _cliffLength Duration (in seconds) after which the first portion vests\n   * @param _openClaim Switch if anyone can claim for `recipient`\n   * @return _success Whether or not the initialization was successful\n   */\n  function initialize(\n    address _owner,\n    address _token,\n    address _recipient,\n    uint256 _amount,\n    uint256 _startTime,\n    uint256 _endTime,\n    uint256 _cliffLength,\n    bool _openClaim\n  ) external returns (bool _success);\n\n  /**\n   * @notice Get the number of unclaimed, vested tokens for recipient.\n   * @return _unclaimed The amount of unclaimed tokens.\n   */\n  function unclaimed() external view returns (uint256 _unclaimed);\n\n  /**\n   * @notice Get the number of locked tokens for recipient.\n   * @return _locked The amount of locked tokens.\n   */\n  function locked() external view returns (uint256 _locked);\n\n  /**\n   * @notice Claim tokens which have vested for the caller.\n   * @return _claimed The amount of tokens claimed.\n   */\n  function claim() external returns (uint256 _claimed);\n\n  /**\n   * @notice Claim tokens which have vested for a specified beneficiary.\n   * @param _beneficiary The address to transfer claimed tokens to.\n   * @return _claimed The amount of tokens claimed.\n   */\n  function claim(address _beneficiary) external returns (uint256 _claimed);\n\n  /**\n   * @notice Claim a specified amount of tokens which have vested for a specified beneficiary.\n   * @param _beneficiary The address to transfer claimed tokens to.\n   * @param _amount The amount of tokens to claim.\n   * @return _claimed The amount of tokens claimed.\n   */\n  function claim(address _beneficiary, uint256 _amount) external returns (uint256 _claimed);\n\n  /**\n   * @notice Disable further flow of tokens and renounce ownership.\n   */\n  function revoke() external;\n\n  /**\n   * @notice Disable further flow of tokens from a specific timestamp and renounce ownership.\n   * @param _timestamp The timestamp to disable further token flow.\n   */\n  function revoke(uint256 _timestamp) external;\n\n  /**\n   * @notice Disable further flow of tokens from a specific timestamp, transfer unvested tokens to a beneficiary, and renounce ownership.\n   * @param _timestamp The timestamp to disable further token flow.\n   * @param _beneficiary The address to transfer unvested tokens to.\n   */\n  function revoke(uint256 _timestamp, address _beneficiary) external;\n\n  /**\n   * @notice Renounce owner control of the escrow, effectively making it ownerless.\n   */\n  function disown() external;\n\n  /**\n   * @notice Disallow or allow anyone to claim tokens for `recipient`.\n   * @param _openClaim True to allow anyone to claim, false to restrict to recipient only.\n   */\n  function set_open_claim(bool _openClaim) external;\n\n  /**\n   * @notice Transfer any ERC20 tokens sent to the contract address to a beneficiary.\n   * @param _token The address of the ERC20 token to transfer.\n   */\n  function collect_dust(address _token) external;\n\n  /**\n   * @notice Transfer any ERC20 tokens sent to the contract address to a specified beneficiary.\n   * @param _token The address of the ERC20 token to transfer.\n   * @param _beneficiary The address to transfer the tokens to.\n   */\n  function collect_dust(address _token, address _beneficiary) external;\n\n  /**\n   * @notice Returns the address of the recipient.\n   * @return _recipient The address of the recipient.\n   */\n  function recipient() external view returns (address _recipient);\n\n  /**\n   * @notice Returns the address of the token being vested.\n   * @return _token The ERC20 token address.\n   */\n  function token() external view returns (address _token);\n\n  /**\n   * @notice Returns the start time of the vesting period.\n   * @return _startTime The start time as a UNIX timestamp.\n   */\n  function start_time() external view returns (uint256 _startTime);\n\n  /**\n   * @notice Returns the end time of the vesting period.\n   * @return _endTime The end time as a UNIX timestamp.\n   */\n  function end_time() external view returns (uint256 _endTime);\n\n  /**\n   * @notice Returns the cliff length in seconds.\n   * @return _cliffLength The cliff length in seconds.\n   */\n  function cliff_length() external view returns (uint256 _cliffLength);\n\n  /**\n   * @notice Returns the total amount of tokens locked in the contract.\n   * @return _totalLocked The total amount of locked tokens.\n   */\n  function total_locked() external view returns (uint256 _totalLocked);\n\n  /**\n   * @notice Returns the total amount of tokens claimed by the recipient.\n   * @return _totalClaimed The total amount of claimed tokens.\n   */\n  function total_claimed() external view returns (uint256 _totalClaimed);\n\n  /**\n   * @notice Returns the timestamp at which the token flow was disabled, if ever.\n   * @return _disabledAt The disable timestamp, or the end time if never disabled.\n   */\n  function disabled_at() external view returns (uint256 _disabledAt);\n\n  /**\n   * @notice Indicates whether anyone can claim tokens on behalf of the recipient.\n   * @return _openClaim True if open claiming is enabled, false otherwise.\n   */\n  function open_claim() external view returns (bool _openClaim);\n\n  /**\n   * @notice Indicates whether the contract has been initialized.\n   * @return _initialized True if the contract has been initialized, false otherwise.\n   */\n  function initialized() external view returns (bool _initialized);\n\n  /**\n   * @notice Returns the address of the owner.\n   * @return _owner The address of the owner.\n   */\n  function owner() external view returns (address _owner);\n}\n"
      },
      "node_modules/@openzeppelin/contracts/utils/Context.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.0.1) (utils/Context.sol)\n\npragma solidity ^0.8.20;\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    function _contextSuffixLength() internal view virtual returns (uint256) {\n        return 0;\n    }\n}\n"
      }
    },
    "settings": {
      "remappings": [
        "ds-test/=node_modules/ds-test/src/",
        "forge-std/=node_modules/forge-std/src/",
        "isolmate/=node_modules/isolmate/src/",
        "contracts/=solidity/contracts/",
        "interfaces/=solidity/interfaces/",
        "scripts/=solidity/scripts/",
        "test/=solidity/test/",
        "@openzeppelin/=node_modules/@openzeppelin/"
      ],
      "optimizer": {
        "enabled": true,
        "runs": 10000
      },
      "metadata": {
        "useLiteralContent": false,
        "bytecodeHash": "ipfs",
        "appendCBOR": true
      },
      "outputSelection": {
        "*": {
          "*": [
            "evm.bytecode",
            "evm.deployedBytecode",
            "devdoc",
            "userdoc",
            "metadata",
            "abi"
          ]
        }
      },
      "evmVersion": "shanghai",
      "viaIR": false,
      "libraries": {}
    }
  }}