creation_sourcecode: {{
    "language": "Solidity",
    "sources": {
      "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.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 {ContextUpgradeable} from \"../utils/ContextUpgradeable.sol\";\nimport {Initializable} from \"../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 * 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 OwnableUpgradeable is Initializable, ContextUpgradeable {\n    /// @custom:storage-location erc7201:openzeppelin.storage.Ownable\n    struct OwnableStorage {\n        address _owner;\n    }\n\n    // keccak256(abi.encode(uint256(keccak256(\"openzeppelin.storage.Ownable\")) - 1)) & ~bytes32(uint256(0xff))\n    bytes32 private constant OwnableStorageLocation = 0x9016d09d72d40fdae2fd8ceac6b6234c7706214fd39c1cd1e609a0528c199300;\n\n    function _getOwnableStorage() private pure returns (OwnableStorage storage $) {\n        assembly {\n            $.slot := OwnableStorageLocation\n        }\n    }\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    function __Ownable_init(address initialOwner) internal onlyInitializing {\n        __Ownable_init_unchained(initialOwner);\n    }\n\n    function __Ownable_init_unchained(address initialOwner) internal onlyInitializing {\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        OwnableStorage storage $ = _getOwnableStorage();\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        OwnableStorage storage $ = _getOwnableStorage();\n        address oldOwner = $._owner;\n        $._owner = newOwner;\n        emit OwnershipTransferred(oldOwner, newOwner);\n    }\n}\n"
      },
      "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.0.0) (proxy/utils/Initializable.sol)\n\npragma solidity ^0.8.20;\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 * ```solidity\n * contract MyToken is ERC20Upgradeable {\n *     function initialize() initializer public {\n *         __ERC20_init(\"MyToken\", \"MTK\");\n *     }\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 Storage of the initializable contract.\n     *\n     * It's implemented on a custom ERC-7201 namespace to reduce the risk of storage collisions\n     * when using with upgradeable contracts.\n     *\n     * @custom:storage-location erc7201:openzeppelin.storage.Initializable\n     */\n    struct InitializableStorage {\n        /**\n         * @dev Indicates that the contract has been initialized.\n         */\n        uint64 _initialized;\n        /**\n         * @dev Indicates that the contract is in the process of being initialized.\n         */\n        bool _initializing;\n    }\n\n    // keccak256(abi.encode(uint256(keccak256(\"openzeppelin.storage.Initializable\")) - 1)) & ~bytes32(uint256(0xff))\n    bytes32 private constant INITIALIZABLE_STORAGE = 0xf0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a00;\n\n    /**\n     * @dev The contract is already initialized.\n     */\n    error InvalidInitialization();\n\n    /**\n     * @dev The contract is not initializing.\n     */\n    error NotInitializing();\n\n    /**\n     * @dev Triggered when the contract has been initialized or reinitialized.\n     */\n    event Initialized(uint64 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.\n     *\n     * Similar to `reinitializer(1)`, except that in the context of a constructor an `initializer` may be invoked any\n     * number of times. This behavior in the constructor can be useful during testing and is not expected to be used in\n     * production.\n     *\n     * Emits an {Initialized} event.\n     */\n    modifier initializer() {\n        // solhint-disable-next-line var-name-mixedcase\n        InitializableStorage storage $ = _getInitializableStorage();\n\n        // Cache values to avoid duplicated sloads\n        bool isTopLevelCall = !$._initializing;\n        uint64 initialized = $._initialized;\n\n        // Allowed calls:\n        // - initialSetup: the contract is not in the initializing state and no previous version was\n        //                 initialized\n        // - construction: the contract is initialized at version 1 (no reininitialization) and the\n        //                 current contract is just being deployed\n        bool initialSetup = initialized == 0 && isTopLevelCall;\n        bool construction = initialized == 1 && address(this).code.length == 0;\n\n        if (!initialSetup && !construction) {\n            revert InvalidInitialization();\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     * A reinitializer may be used after the original initialization step. This is essential to configure modules that\n     * are added through upgrades and that require initialization.\n     *\n     * When `version` is 1, this modifier is similar to `initializer`, except that functions marked with `reinitializer`\n     * cannot be nested. If one is invoked in the context of another, execution will revert.\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     * WARNING: Setting the version to 2**64 - 1 will prevent any future reinitialization.\n     *\n     * Emits an {Initialized} event.\n     */\n    modifier reinitializer(uint64 version) {\n        // solhint-disable-next-line var-name-mixedcase\n        InitializableStorage storage $ = _getInitializableStorage();\n\n        if ($._initializing || $._initialized >= version) {\n            revert InvalidInitialization();\n        }\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        _checkInitializing();\n        _;\n    }\n\n    /**\n     * @dev Reverts if the contract is not in an initializing state. See {onlyInitializing}.\n     */\n    function _checkInitializing() internal view virtual {\n        if (!_isInitializing()) {\n            revert NotInitializing();\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     * Emits an {Initialized} event the first time it is successfully executed.\n     */\n    function _disableInitializers() internal virtual {\n        // solhint-disable-next-line var-name-mixedcase\n        InitializableStorage storage $ = _getInitializableStorage();\n\n        if ($._initializing) {\n            revert InvalidInitialization();\n        }\n        if ($._initialized != type(uint64).max) {\n            $._initialized = type(uint64).max;\n            emit Initialized(type(uint64).max);\n        }\n    }\n\n    /**\n     * @dev Returns the highest version that has been initialized. See {reinitializer}.\n     */\n    function _getInitializedVersion() internal view returns (uint64) {\n        return _getInitializableStorage()._initialized;\n    }\n\n    /**\n     * @dev Returns `true` if the contract is currently initializing. See {onlyInitializing}.\n     */\n    function _isInitializing() internal view returns (bool) {\n        return _getInitializableStorage()._initializing;\n    }\n\n    /**\n     * @dev Returns a pointer to the storage namespace.\n     */\n    // solhint-disable-next-line var-name-mixedcase\n    function _getInitializableStorage() private pure returns (InitializableStorage storage $) {\n        assembly {\n            $.slot := INITIALIZABLE_STORAGE\n        }\n    }\n}\n"
      },
      "@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.0.1) (utils/Context.sol)\n\npragma solidity ^0.8.20;\nimport {Initializable} from \"../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    function _contextSuffixLength() internal view virtual returns (uint256) {\n        return 0;\n    }\n}\n"
      },
      "@openzeppelin/contracts-upgradeable/utils/PausableUpgradeable.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.0.0) (utils/Pausable.sol)\n\npragma solidity ^0.8.20;\n\nimport {ContextUpgradeable} from \"../utils/ContextUpgradeable.sol\";\nimport {Initializable} from \"../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Contract module which allows children to implement an emergency stop\n * mechanism that can be triggered by an authorized account.\n *\n * This module is used through inheritance. It will make available the\n * modifiers `whenNotPaused` and `whenPaused`, which can be applied to\n * the functions of your contract. Note that they will not be pausable by\n * simply including this module, only once the modifiers are put in place.\n */\nabstract contract PausableUpgradeable is Initializable, ContextUpgradeable {\n    /// @custom:storage-location erc7201:openzeppelin.storage.Pausable\n    struct PausableStorage {\n        bool _paused;\n    }\n\n    // keccak256(abi.encode(uint256(keccak256(\"openzeppelin.storage.Pausable\")) - 1)) & ~bytes32(uint256(0xff))\n    bytes32 private constant PausableStorageLocation = 0xcd5ed15c6e187e77e9aee88184c21f4f2182ab5827cb3b7e07fbedcd63f03300;\n\n    function _getPausableStorage() private pure returns (PausableStorage storage $) {\n        assembly {\n            $.slot := PausableStorageLocation\n        }\n    }\n\n    /**\n     * @dev Emitted when the pause is triggered by `account`.\n     */\n    event Paused(address account);\n\n    /**\n     * @dev Emitted when the pause is lifted by `account`.\n     */\n    event Unpaused(address account);\n\n    /**\n     * @dev The operation failed because the contract is paused.\n     */\n    error EnforcedPause();\n\n    /**\n     * @dev The operation failed because the contract is not paused.\n     */\n    error ExpectedPause();\n\n    /**\n     * @dev Initializes the contract in unpaused state.\n     */\n    function __Pausable_init() internal onlyInitializing {\n        __Pausable_init_unchained();\n    }\n\n    function __Pausable_init_unchained() internal onlyInitializing {\n        PausableStorage storage $ = _getPausableStorage();\n        $._paused = false;\n    }\n\n    /**\n     * @dev Modifier to make a function callable only when the contract is not paused.\n     *\n     * Requirements:\n     *\n     * - The contract must not be paused.\n     */\n    modifier whenNotPaused() {\n        _requireNotPaused();\n        _;\n    }\n\n    /**\n     * @dev Modifier to make a function callable only when the contract is paused.\n     *\n     * Requirements:\n     *\n     * - The contract must be paused.\n     */\n    modifier whenPaused() {\n        _requirePaused();\n        _;\n    }\n\n    /**\n     * @dev Returns true if the contract is paused, and false otherwise.\n     */\n    function paused() public view virtual returns (bool) {\n        PausableStorage storage $ = _getPausableStorage();\n        return $._paused;\n    }\n\n    /**\n     * @dev Throws if the contract is paused.\n     */\n    function _requireNotPaused() internal view virtual {\n        if (paused()) {\n            revert EnforcedPause();\n        }\n    }\n\n    /**\n     * @dev Throws if the contract is not paused.\n     */\n    function _requirePaused() internal view virtual {\n        if (!paused()) {\n            revert ExpectedPause();\n        }\n    }\n\n    /**\n     * @dev Triggers stopped state.\n     *\n     * Requirements:\n     *\n     * - The contract must not be paused.\n     */\n    function _pause() internal virtual whenNotPaused {\n        PausableStorage storage $ = _getPausableStorage();\n        $._paused = true;\n        emit Paused(_msgSender());\n    }\n\n    /**\n     * @dev Returns to normal state.\n     *\n     * Requirements:\n     *\n     * - The contract must be paused.\n     */\n    function _unpause() internal virtual whenPaused {\n        PausableStorage storage $ = _getPausableStorage();\n        $._paused = false;\n        emit Unpaused(_msgSender());\n    }\n}\n"
      },
      "@openzeppelin/contracts-upgradeable/utils/ReentrancyGuardUpgradeable.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.0.0) (utils/ReentrancyGuard.sol)\n\npragma solidity ^0.8.20;\nimport {Initializable} from \"../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Contract module that helps prevent reentrant calls to a function.\n *\n * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier\n * available, which can be applied to functions to make sure there are no nested\n * (reentrant) calls to them.\n *\n * Note that because there is a single `nonReentrant` guard, functions marked as\n * `nonReentrant` may not call one another. This can be worked around by making\n * those functions `private`, and then adding `external` `nonReentrant` entry\n * points to them.\n *\n * TIP: If you would like to learn more about reentrancy and alternative ways\n * to protect against it, check out our blog post\n * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].\n */\nabstract contract ReentrancyGuardUpgradeable is Initializable {\n    // Booleans are more expensive than uint256 or any type that takes up a full\n    // word because each write operation emits an extra SLOAD to first read the\n    // slot's contents, replace the bits taken up by the boolean, and then write\n    // back. This is the compiler's defense against contract upgrades and\n    // pointer aliasing, and it cannot be disabled.\n\n    // The values being non-zero value makes deployment a bit more expensive,\n    // but in exchange the refund on every call to nonReentrant will be lower in\n    // amount. Since refunds are capped to a percentage of the total\n    // transaction's gas, it is best to keep them low in cases like this one, to\n    // increase the likelihood of the full refund coming into effect.\n    uint256 private constant NOT_ENTERED = 1;\n    uint256 private constant ENTERED = 2;\n\n    /// @custom:storage-location erc7201:openzeppelin.storage.ReentrancyGuard\n    struct ReentrancyGuardStorage {\n        uint256 _status;\n    }\n\n    // keccak256(abi.encode(uint256(keccak256(\"openzeppelin.storage.ReentrancyGuard\")) - 1)) & ~bytes32(uint256(0xff))\n    bytes32 private constant ReentrancyGuardStorageLocation = 0x9b779b17422d0df92223018b32b4d1fa46e071723d6817e2486d003becc55f00;\n\n    function _getReentrancyGuardStorage() private pure returns (ReentrancyGuardStorage storage $) {\n        assembly {\n            $.slot := ReentrancyGuardStorageLocation\n        }\n    }\n\n    /**\n     * @dev Unauthorized reentrant call.\n     */\n    error ReentrancyGuardReentrantCall();\n\n    function __ReentrancyGuard_init() internal onlyInitializing {\n        __ReentrancyGuard_init_unchained();\n    }\n\n    function __ReentrancyGuard_init_unchained() internal onlyInitializing {\n        ReentrancyGuardStorage storage $ = _getReentrancyGuardStorage();\n        $._status = NOT_ENTERED;\n    }\n\n    /**\n     * @dev Prevents a contract from calling itself, directly or indirectly.\n     * Calling a `nonReentrant` function from another `nonReentrant`\n     * function is not supported. It is possible to prevent this from happening\n     * by making the `nonReentrant` function external, and making it call a\n     * `private` function that does the actual work.\n     */\n    modifier nonReentrant() {\n        _nonReentrantBefore();\n        _;\n        _nonReentrantAfter();\n    }\n\n    function _nonReentrantBefore() private {\n        ReentrancyGuardStorage storage $ = _getReentrancyGuardStorage();\n        // On the first call to nonReentrant, _status will be NOT_ENTERED\n        if ($._status == ENTERED) {\n            revert ReentrancyGuardReentrantCall();\n        }\n\n        // Any calls to nonReentrant after this point will fail\n        $._status = ENTERED;\n    }\n\n    function _nonReentrantAfter() private {\n        ReentrancyGuardStorage storage $ = _getReentrancyGuardStorage();\n        // By storing the original value once again, a refund is triggered (see\n        // https://eips.ethereum.org/EIPS/eip-2200)\n        $._status = NOT_ENTERED;\n    }\n\n    /**\n     * @dev Returns true if the reentrancy guard is currently set to \"entered\", which indicates there is a\n     * `nonReentrant` function in the call stack.\n     */\n    function _reentrancyGuardEntered() internal view returns (bool) {\n        ReentrancyGuardStorage storage $ = _getReentrancyGuardStorage();\n        return $._status == ENTERED;\n    }\n}\n"
      },
      "@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"
      },
      "@uniswap/v3-periphery/contracts/libraries/TransferHelper.sol": {
        "content": "// SPDX-License-Identifier: GPL-2.0-or-later\npragma solidity >=0.6.0;\n\nimport '@openzeppelin/contracts/token/ERC20/IERC20.sol';\n\nlibrary TransferHelper {\n    /// @notice Transfers tokens from the targeted address to the given destination\n    /// @notice Errors with 'STF' if transfer fails\n    /// @param token The contract address of the token to be transferred\n    /// @param from The originating address from which the tokens will be transferred\n    /// @param to The destination address of the transfer\n    /// @param value The amount to be transferred\n    function safeTransferFrom(\n        address token,\n        address from,\n        address to,\n        uint256 value\n    ) internal {\n        (bool success, bytes memory data) =\n            token.call(abi.encodeWithSelector(IERC20.transferFrom.selector, from, to, value));\n        require(success && (data.length == 0 || abi.decode(data, (bool))), 'STF');\n    }\n\n    /// @notice Transfers tokens from msg.sender to a recipient\n    /// @dev Errors with ST if transfer fails\n    /// @param token The contract address of the token which will be transferred\n    /// @param to The recipient of the transfer\n    /// @param value The value of the transfer\n    function safeTransfer(\n        address token,\n        address to,\n        uint256 value\n    ) internal {\n        (bool success, bytes memory data) = token.call(abi.encodeWithSelector(IERC20.transfer.selector, to, value));\n        require(success && (data.length == 0 || abi.decode(data, (bool))), 'ST');\n    }\n\n    /// @notice Approves the stipulated contract to spend the given allowance in the given token\n    /// @dev Errors with 'SA' if transfer fails\n    /// @param token The contract address of the token to be approved\n    /// @param to The target of the approval\n    /// @param value The amount of the given token the target will be allowed to spend\n    function safeApprove(\n        address token,\n        address to,\n        uint256 value\n    ) internal {\n        (bool success, bytes memory data) = token.call(abi.encodeWithSelector(IERC20.approve.selector, to, value));\n        require(success && (data.length == 0 || abi.decode(data, (bool))), 'SA');\n    }\n\n    /// @notice Transfers ETH to the recipient address\n    /// @dev Fails with `STE`\n    /// @param to The destination of the transfer\n    /// @param value The value to be transferred\n    function safeTransferETH(address to, uint256 value) internal {\n        (bool success, ) = to.call{value: value}(new bytes(0));\n        require(success, 'STE');\n    }\n}\n"
      },
      "contracts/interface/IWETH.sol": {
        "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.20;\npragma abicoder v2;\n\ninterface IWETH {\n    function totalSupply() external view returns (uint256);\n\n    function balanceOf(address account) external view returns (uint256);\n\n    function transfer(\n        address recipient,\n        uint256 amount\n    ) external returns (bool);\n\n    function allowance(\n        address owner,\n        address spender\n    ) external view returns (uint256);\n\n    function approve(address spender, uint256 amount) external returns (bool);\n\n    function transferFrom(\n        address src,\n        address dst,\n        uint256 wad\n    ) external returns (bool);\n\n    function deposit() external payable;\n\n    function withdraw(uint256 wad) external;\n}\n"
      },
      "contracts/libraries/BytesLib.sol": {
        "content": "// SPDX-License-Identifier: MIT\n\n/// @title Library for Bytes Manipulation\npragma solidity ^0.8.0;\n\nlibrary BytesLib {\n    error SliceOutOfBounds();\n\n    /// @dev The length of the bytes encoded address\n    uint256 internal constant ADDR_SIZE = 20;\n\n    /// @notice Decode the `_arg`-th element in `_bytes` as a dynamic array\n    /// @dev The decoding of `length` and `offset` is universal,\n    /// whereas the type declaration of `res` instructs the compiler how to read it.\n    /// @param _bytes The input bytes string to slice\n    /// @param _arg The index of the argument to extract\n    /// @return length Length of the array\n    /// @return offset Pointer to the data part of the array\n    function toLengthOffset(\n        bytes calldata _bytes,\n        uint256 _arg\n    ) internal pure returns (uint256 length, uint256 offset) {\n        uint256 relativeOffset;\n        assembly {\n            // The offset of the `_arg`-th element is `32 * arg`, which stores the offset of the length pointer.\n            // shl(5, x) is equivalent to mul(32, x)\n            let lengthPtr := add(\n                _bytes.offset,\n                calldataload(add(_bytes.offset, shl(5, _arg)))\n            )\n            length := calldataload(lengthPtr)\n            offset := add(lengthPtr, 0x20)\n            relativeOffset := sub(offset, _bytes.offset)\n        }\n        if (_bytes.length < length + relativeOffset) revert SliceOutOfBounds();\n    }\n\n    /// @notice Decode the `_arg`-th element in `_bytes` as `bytes`\n    /// @param _bytes The input bytes string to extract a bytes string from\n    /// @param _arg The index of the argument to extract\n    function toBytes(\n        bytes calldata _bytes,\n        uint256 _arg\n    ) internal pure returns (bytes calldata res) {\n        (uint256 length, uint256 offset) = toLengthOffset(_bytes, _arg);\n        assembly {\n            res.length := length\n            res.offset := offset\n        }\n    }\n    /// @notice Decode the `_arg`-th element in `_bytes` as `address[]`\n    /// @param _bytes The input bytes string to extract an address array from\n    /// @param _arg The index of the argument to extract\n    function toAddressArray(\n        bytes calldata _bytes,\n        uint256 _arg\n    ) internal pure returns (address[] calldata res) {\n        (uint256 length, uint256 offset) = toLengthOffset(_bytes, _arg);\n        assembly {\n            res.length := length\n            res.offset := offset\n        }\n    }\n\n    // @notice Returns the address starting at byte 0\n    /// @dev length and overflow checks must be carried out before calling\n    /// @param _bytes The input bytes string to slice\n    /// @return _address The address starting at byte 0\n    function toAddress(\n        bytes calldata _bytes\n    ) internal pure returns (address _address) {\n        if (_bytes.length < ADDR_SIZE) revert SliceOutOfBounds();\n        assembly {\n            _address := shr(96, calldataload(_bytes.offset))\n        }\n    }\n}\n"
      },
      "contracts/libraries/constants/Common.sol": {
        "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.20;\n\nlibrary ZookeyConstants {\n    /// @dev WNATIVE_TOKEN address is network-specific and needs to be changed before deployment.\n    /// It can not be moved to immutable as immutables are not supported in assembly\n    // ETH:     0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2\n    // ARB:     0x82aF49447D8a07e3bd95BD0d56f35241523fBab1\n    // OP:      0x4200000000000000000000000000000000000006\n    // POLYGON [WMATIC]: 0x0d500B1d8E8eF31E21C99d1Db9A6444d3ADf1270\n    // ZK:      0x5AEa5775959fBC2557Cc8789bC1bf90A239D9a91\n    // Scroll   0x5300000000000000000000000000000000000004\n    // BASE     0x4200000000000000000000000000000000000006\n    address internal constant WNATIVE_TOKEN =\n        0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2;\n\n    // ETH 0x0000000000000000000000000000000000000000\n    // ARB 0x0000000000000000000000000000000000000000\n    // OP 0x0000000000000000000000000000000000000000\n    // BASE 0x0000000000000000000000000000000000000000\n    // POLYGON 0x0000000000000000000000000000000000001010\n    // ZK 0x0000000000000000000000000000000000000000\n    // SCROLL 0x0000000000000000000000000000000000000000\n    address internal constant NATIVE_TOKEN =\n        0x0000000000000000000000000000000000000000;\n}\n"
      },
      "contracts/libraries/errors/ZookeyReceiveErrors.sol": {
        "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.20;\n\nlibrary ZookeyReceiveErrors {\n    string internal constant ADDRESS_0 = \"address 0\";\n    string internal constant ONLY_ADMIN = \"only admin\";\n    string internal constant FROM_TOKEN_AMOUNT = \"from token amount err\";\n    string internal constant SWAP_RESULT_FAIL = \"swap failed\";\n    string internal constant BRIDGE_AMOUNT_ERR = \"bridge amount err\";\n    string internal constant BRIDGE_BALANCE_ERR = \"bridge balance err\";\n    string internal constant BRIDGE_RESULT_ERR = \"bridge failed\";\n    string internal constant WRAP_AMOUNT_ZERO = \"wrap amount must be > 0\";\n    string internal constant TRANSFER_ETH_FAILD = \"ETH transfer failed\";\n    string internal constant BRIDGE_DATA_LENGTH_ERR = \"bridge data err\";\n}\n"
      },
      "contracts/ZookeyReceive.sol": {
        "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.20;\n\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/utils/PausableUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/utils/ReentrancyGuardUpgradeable.sol\";\nimport \"@uniswap/v3-periphery/contracts/libraries/TransferHelper.sol\";\n\nimport {ZookeyConstants} from \"./libraries/constants/Common.sol\";\nimport {ZookeyReceiveErrors} from \"./libraries/errors/ZookeyReceiveErrors.sol\";\nimport {BytesLib} from \"./libraries/BytesLib.sol\";\nimport \"./interface/IWETH.sol\";\n\ncontract ZookeyReceive is\n    OwnableUpgradeable,\n    PausableUpgradeable,\n    ReentrancyGuardUpgradeable\n{\n    using BytesLib for bytes;\n\n    address public routerAddr;\n\n    address public bridgeAddr;\n\n    address public admin;\n\n    struct DispatchData {\n        bytes commands;\n        bytes[] inputs;\n    }\n\n    struct BridgeRequest {\n        bytes1 command;\n        bytes input;\n    }\n\n    modifier onlyAdmin() {\n        require(msg.sender == admin, ZookeyReceiveErrors.ONLY_ADMIN);\n        _;\n    }\n\n    modifier onlyNotZero(address addr) {\n        require(addr != address(0), ZookeyReceiveErrors.ADDRESS_0);\n        _;\n    }\n\n    function pause() public onlyOwner {\n        _pause();\n    }\n\n    function unpause() public onlyOwner {\n        _unpause();\n    }\n\n    /**\n     * @dev sets initials supply and the owner\n     */\n    function initialize(\n        address _owner,\n        address _routerAddr,\n        address _bridgeAddr\n    ) public initializer {\n        __Pausable_init();\n        __Ownable_init(_owner);\n        __ReentrancyGuard_init();\n        admin = _owner;\n        routerAddr = _routerAddr;\n        bridgeAddr = _bridgeAddr;\n    }\n\n    function setAdmin(\n        address newAdmin\n    ) external onlyOwner onlyNotZero(newAdmin) {\n        admin = newAdmin;\n    }\n\n    function setDexRouter(\n        address newDexRouter\n    ) external onlyAdmin onlyNotZero(newDexRouter) {\n        routerAddr = newDexRouter;\n    }\n\n    function setBridgeAddr(\n        address newBridgeAddr\n    ) external onlyAdmin onlyNotZero(newBridgeAddr) {\n        bridgeAddr = newBridgeAddr;\n    }\n\n    function _getBalanceOf(address _token) internal view returns (uint256) {\n        return _getBalanceOf(_token, address(this));\n    }\n\n    function _getBalanceOf(\n        address _token,\n        address _who\n    ) internal view returns (uint256) {\n        return\n            _token == ZookeyConstants.NATIVE_TOKEN\n                ? _who.balance\n                : IERC20(_token).balanceOf(_who);\n    }\n\n    function swap(\n        address fromToken,\n        uint256 fromTokenAmount,\n        address toToken,\n        bytes calldata routerData\n    ) public payable nonReentrant whenNotPaused {\n        _swap(fromToken, fromTokenAmount, toToken, false, routerData);\n    }\n\n    function _swap(\n        address _fromToken,\n        uint256 _fromTokenAmount,\n        address _toToken,\n        bool _needBridge,\n        bytes calldata routerData\n    ) internal {\n        require(_fromTokenAmount > 0, ZookeyReceiveErrors.FROM_TOKEN_AMOUNT);\n        bool success;\n        // 1. prepare and swap\n        if (_fromToken == ZookeyConstants.NATIVE_TOKEN) {\n            //FROM NATIVE\n            if (_toToken == ZookeyConstants.WNATIVE_TOKEN) {\n                //ETH => WETH\n                success = _swapWrap(\n                    address(this),\n                    msg.sender,\n                    _fromTokenAmount,\n                    false\n                );\n            } else {\n                // ETH => ERC20\n                (success, ) = routerAddr.call{value: _fromTokenAmount}(\n                    routerData\n                );\n            }\n        } else {\n            // FROM ERC20\n            if (\n                _fromToken == ZookeyConstants.WNATIVE_TOKEN &&\n                _toToken == ZookeyConstants.NATIVE_TOKEN\n            ) {\n                // WETH => ETH\n                success = _swapWrap(\n                    msg.sender,\n                    _needBridge ? address(this) : msg.sender,\n                    _fromTokenAmount,\n                    true\n                );\n            } else {\n                // ERC20 => ERC20, use routerAddr\n                _tokenRelayer(\n                    _fromToken,\n                    msg.sender,\n                    address(this),\n                    _fromTokenAmount,\n                    routerAddr\n                );\n                (success, ) = routerAddr.call{value: msg.value}(routerData);\n            }\n        }\n        require(success, ZookeyReceiveErrors.SWAP_RESULT_FAIL);\n    }\n\n    function swapBridge(\n        address fromToken,\n        uint256 fromTokenAmount,\n        address toToken,\n        bytes calldata routerData,\n        bytes calldata bridgeData\n    ) public payable nonReentrant whenNotPaused {\n        require(fromTokenAmount > 0, ZookeyReceiveErrors.BRIDGE_AMOUNT_ERR);\n        require(\n            bridgeData.length >= 32,\n            ZookeyReceiveErrors.BRIDGE_DATA_LENGTH_ERR\n        );\n        uint256 toTokenBeforeSwapBalance = _getBalanceOf(toToken);\n        _swap(fromToken, fromTokenAmount, toToken, true, routerData);\n        uint256 toTokenAfterSwapBalance = _getBalanceOf(toToken);\n\n        require(\n            toTokenAfterSwapBalance > 0 &&\n                toTokenAfterSwapBalance > toTokenBeforeSwapBalance,\n            ZookeyReceiveErrors.BRIDGE_BALANCE_ERR\n        );\n        uint256 toTokenBridgeBalance = toTokenAfterSwapBalance -\n            toTokenBeforeSwapBalance;\n        if (toToken != ZookeyConstants.NATIVE_TOKEN) {\n            TransferHelper.safeApprove(\n                toToken,\n                bridgeAddr,\n                toTokenBridgeBalance\n            );\n        }\n        (bool success, ) = bridgeAddr.call{\n            value: toToken == ZookeyConstants.NATIVE_TOKEN\n                ? toTokenBridgeBalance\n                : 0\n        }(_replaceLastUintInBytes(bridgeData, toTokenBridgeBalance));\n        require(success, ZookeyReceiveErrors.BRIDGE_RESULT_ERR);\n    }\n\n    function _replaceLastUintInBytes(\n        bytes memory _data,\n        uint256 _newValue\n    ) internal pure returns (bytes memory) {\n        assembly {\n            // 68 is because the start of the data is at 32, then 4 is taken by the function signature,\n            // the first 32-bit parameter position is between 36-68, so the second parameter starts at the 68th bit.\n            mstore(add(_data, 68), _newValue)\n        }\n        return _data;\n    }\n\n    function bridge(\n        address bridgeToken,\n        uint256 bridgeAmount,\n        bytes calldata bridgeData\n    ) public payable nonReentrant whenNotPaused {\n        require(bridgeAmount > 0, ZookeyReceiveErrors.BRIDGE_AMOUNT_ERR);\n        _bridge(bridgeToken, bridgeAmount, bridgeData);\n    }\n\n    function _bridge(\n        address _bridgeToken,\n        uint256 _bridgeAmount,\n        bytes calldata _bridgeData\n    ) internal {\n        require(\n            _bridgeData.length > 0,\n            ZookeyReceiveErrors.BRIDGE_DATA_LENGTH_ERR\n        );\n        uint256 bridgeAmount;\n        bool success;\n        if (_bridgeToken != ZookeyConstants.NATIVE_TOKEN) {\n            _tokenRelayer(\n                _bridgeToken,\n                msg.sender,\n                address(this),\n                _bridgeAmount,\n                bridgeAddr\n            );\n        } else {\n            bridgeAmount = msg.value;\n        }\n        (success, ) = bridgeAddr.call{value: bridgeAmount}(_bridgeData);\n        require(success, ZookeyReceiveErrors.BRIDGE_RESULT_ERR);\n    }\n\n    function _tokenRelayer(\n        address _fromToken,\n        address _transferFrom,\n        address _receiver,\n        uint256 _fromTokenAmount,\n        address _approveAddress\n    ) internal {\n        TransferHelper.safeTransferFrom(\n            _fromToken,\n            _transferFrom,\n            _receiver,\n            _fromTokenAmount\n        );\n        TransferHelper.safeApprove(\n            _fromToken,\n            _approveAddress,\n            _fromTokenAmount\n        );\n    }\n\n    /**\n     * @dev Internal function to swap and wrap tokens.\n     * @param from The address to transfer the tokens from.\n     * @param to The address to transfer the wrapped tokens to.\n     * @param amount The amount of tokens to swap and wrap.\n     * @param reversed Boolean indicating whether the swap is reversed (WETH => ETH).\n     * @return A boolean indicating the success of the swap and wrap operation.\n     */\n    function _swapWrap(\n        address from,\n        address to,\n        uint256 amount,\n        bool reversed\n    ) internal returns (bool) {\n        require(amount > 0, ZookeyReceiveErrors.WRAP_AMOUNT_ZERO);\n        // reversed == true: WNATIVE_TOKEN => NATIVE_TOKEN\n        if (reversed) {\n            IWETH(ZookeyConstants.WNATIVE_TOKEN).transferFrom(\n                from,\n                address(this),\n                amount\n            );\n            IWETH(ZookeyConstants.WNATIVE_TOKEN).withdraw(amount);\n            if (to != address(this)) {\n                (bool success, ) = payable(to).call{value: amount}(\"\");\n                require(success, ZookeyReceiveErrors.TRANSFER_ETH_FAILD);\n            }\n        } else {\n            // reversed == false: NATIVE_TOKEN => WNATIVE_TOKEN\n            IWETH(ZookeyConstants.WNATIVE_TOKEN).deposit{value: amount}();\n            if (to != address(this)) {\n                IERC20(ZookeyConstants.WNATIVE_TOKEN).transfer(to, amount);\n            }\n        }\n        return true;\n    }\n    receive() external payable {}\n\n    uint256[50] internal reserve;\n}\n"
      }
    },
    "settings": {
      "metadata": {
        "bytecodeHash": "none"
      },
      "optimizer": {
        "enabled": true,
        "runs": 99999
      },
      "viaIR": true,
      "evmVersion": "paris",
      "outputSelection": {
        "*": {
          "*": [
            "evm.bytecode",
            "evm.deployedBytecode",
            "devdoc",
            "userdoc",
            "metadata",
            "abi"
          ]
        }
      },
      "libraries": {}
    }
  }}