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/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-core/contracts/interfaces/callback/IUniswapV3SwapCallback.sol": {
        "content": "// SPDX-License-Identifier: GPL-2.0-or-later\npragma solidity >=0.5.0;\n\n/// @title Callback for IUniswapV3PoolActions#swap\n/// @notice Any contract that calls IUniswapV3PoolActions#swap must implement this interface\ninterface IUniswapV3SwapCallback {\n    /// @notice Called to `msg.sender` after executing a swap via IUniswapV3Pool#swap.\n    /// @dev In the implementation you must pay the pool tokens owed for the swap.\n    /// The caller of this method must be checked to be a UniswapV3Pool deployed by the canonical UniswapV3Factory.\n    /// amount0Delta and amount1Delta can both be 0 if no tokens were swapped.\n    /// @param amount0Delta The amount of token0 that was sent (negative) or must be received (positive) by the pool by\n    /// the end of the swap. If positive, the callback must send that amount of token0 to the pool.\n    /// @param amount1Delta The amount of token1 that was sent (negative) or must be received (positive) by the pool by\n    /// the end of the swap. If positive, the callback must send that amount of token1 to the pool.\n    /// @param data Any data passed through by the caller via the IUniswapV3PoolActions#swap call\n    function uniswapV3SwapCallback(\n        int256 amount0Delta,\n        int256 amount1Delta,\n        bytes calldata data\n    ) external;\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/base/LockAndMsgSender.sol": {
        "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.17;\n\ncontract LockAndMsgSender {\n    error ContractLocked();\n\n    /// @dev Used as a flag for identifying that msg.sender should be used, saves gas by sending more 0 bytes\n    address internal constant MSG_SENDER = address(1);\n\n    /// @dev Used as a flag for identifying address(this) should be used, saves gas by sending more 0 bytes\n    address internal constant ADDRESS_THIS = address(2);\n\n    address internal constant NOT_LOCKED_FLAG = address(1);\n    address internal lockedBy;\n\n    modifier isNotLocked() {\n        if (msg.sender != address(this)) {\n            if (lockedBy != NOT_LOCKED_FLAG) revert ContractLocked();\n            lockedBy = msg.sender;\n            _;\n            lockedBy = NOT_LOCKED_FLAG;\n        } else {\n            _;\n        }\n    }\n\n    function _initLockedBy() internal {\n        lockedBy = NOT_LOCKED_FLAG;\n    }\n\n    /// @notice Calculates the recipient address for a command\n    /// @param recipient The recipient or recipient-flag for the command\n    /// @return output The resultant recipient for the command\n    function map(address recipient) internal view returns (address) {\n        if (recipient == MSG_SENDER) {\n            return lockedBy;\n        } else if (recipient == ADDRESS_THIS) {\n            return address(this);\n        } else {\n            return recipient;\n        }\n    }\n}\n"
      },
      "contracts/interface/IStargateRouter.sol": {
        "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.20;\n\ninterface IStargateRouter {\n    struct lzTxObj {\n        uint256 dstGasForCall;\n        uint256 dstNativeAmount;\n        bytes dstNativeAddr;\n    }\n\n    function swap(\n        uint16 _dstChainId,\n        uint256 _srcPoolId,\n        uint256 _dstPoolId,\n        address payable _refundAddress,\n        uint256 _amountLD,\n        uint256 _minAmountLD,\n        lzTxObj memory _lzTxParams,\n        bytes calldata _to,\n        bytes calldata _payload\n    ) external payable;\n}\n"
      },
      "contracts/interface/ISwapRouter02.sol": {
        "content": "// SPDX-License-Identifier: GPL-2.0-or-later\npragma solidity >=0.7.5;\npragma abicoder v2;\n\nimport \"@uniswap/v3-core/contracts/interfaces/callback/IUniswapV3SwapCallback.sol\";\n\ninterface ISwapRouter02 {\n    /// @notice Swaps `amountIn` of one token for as much as possible of another token\n    /// @dev Setting `amountIn` to 0 will cause the contract to look up its own balance,\n    /// and swap the entire amount, enabling contracts to send tokens before calling this function.\n    /// @param amountIn The amount of token to swap\n    /// @param amountOutMin The minimum amount of output that must be received\n    /// @param path The ordered list of tokens to swap through\n    /// @param to The recipient address\n    /// @return amountOut The amount of the received token\n    function swapExactTokensForTokens(\n        uint256 amountIn,\n        uint256 amountOutMin,\n        address[] calldata path,\n        address to\n    ) external payable returns (uint256 amountOut);\n\n    /// @notice Swaps as little as possible of one token for an exact amount of another token\n    /// @param amountOut The amount of token to swap for\n    /// @param amountInMax The maximum amount of input that the caller will pay\n    /// @param path The ordered list of tokens to swap through\n    /// @param to The recipient address\n    /// @return amountIn The amount of token to pay\n    function swapTokensForExactTokens(\n        uint256 amountOut,\n        uint256 amountInMax,\n        address[] calldata path,\n        address to\n    ) external payable returns (uint256 amountIn);\n\n    struct ExactInputSingleParams {\n        address tokenIn;\n        address tokenOut;\n        uint24 fee;\n        address recipient;\n        uint256 amountIn;\n        uint256 amountOutMinimum;\n        uint160 sqrtPriceLimitX96;\n    }\n\n    /// @notice Swaps `amountIn` of one token for as much as possible of another token\n    /// @dev Setting `amountIn` to 0 will cause the contract to look up its own balance,\n    /// and swap the entire amount, enabling contracts to send tokens before calling this function.\n    /// @param params The parameters necessary for the swap, encoded as `ExactInputSingleParams` in calldata\n    /// @return amountOut The amount of the received token\n    function exactInputSingle(\n        ExactInputSingleParams calldata params\n    ) external payable returns (uint256 amountOut);\n\n    struct ExactInputParams {\n        bytes path;\n        address recipient;\n        uint256 amountIn;\n        uint256 amountOutMinimum;\n    }\n\n    /// @notice Swaps `amountIn` of one token for as much as possible of another along the specified path\n    /// @dev Setting `amountIn` to 0 will cause the contract to look up its own balance,\n    /// and swap the entire amount, enabling contracts to send tokens before calling this function.\n    /// @param params The parameters necessary for the multi-hop swap, encoded as `ExactInputParams` in calldata\n    /// @return amountOut The amount of the received token\n    function exactInput(\n        ExactInputParams calldata params\n    ) external payable returns (uint256 amountOut);\n\n    struct ExactOutputSingleParams {\n        address tokenIn;\n        address tokenOut;\n        uint24 fee;\n        address recipient;\n        uint256 amountOut;\n        uint256 amountInMaximum;\n        uint160 sqrtPriceLimitX96;\n    }\n\n    /// @notice Swaps as little as possible of one token for `amountOut` of another token\n    /// that may remain in the router after the swap.\n    /// @param params The parameters necessary for the swap, encoded as `ExactOutputSingleParams` in calldata\n    /// @return amountIn The amount of the input token\n    function exactOutputSingle(\n        ExactOutputSingleParams calldata params\n    ) external payable returns (uint256 amountIn);\n\n    struct ExactOutputParams {\n        bytes path;\n        address recipient;\n        uint256 amountOut;\n        uint256 amountInMaximum;\n    }\n\n    /// @notice Swaps as little as possible of one token for `amountOut` of another along the specified path (reversed)\n    /// that may remain in the router after the swap.\n    /// @param params The parameters necessary for the multi-hop swap, encoded as `ExactOutputParams` in calldata\n    /// @return amountIn The amount of the input token\n    function exactOutput(\n        ExactOutputParams calldata params\n    ) external payable returns (uint256 amountIn);\n}\n"
      },
      "contracts/interface/ISyncSwap.sol": {
        "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.20;\n\ninterface ISyncSwap {\n    struct SwapStep {\n        address pool; // The pool of the step.\n        bytes data; // The data to execute swap with the pool.\n        address callback;\n        bytes callbackData;\n    }\n\n    struct SwapPath {\n        SwapStep[] steps; // Steps of the path.\n        address tokenIn; // The input token of the path.\n        uint amountIn; // The input token amount of the path.\n    }\n\n    function swap(\n        SwapPath[] memory paths,\n        uint amountOutMin,\n        uint deadline\n    ) external payable returns (uint amountOut);\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/interface/IZookeyRouter.sol": {
        "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.20;\n\ninterface IZookeyRouter {\n    error ExecutionFailed(uint256 commandIndex, bytes message);\n\n    error TransactionDeadlinePassed();\n\n    function execute(\n        address fromToken,\n        address toToken,\n        bytes calldata commands,\n        bytes[] calldata inputs,\n        uint256 deadline\n    ) external payable;\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/Commands.sol": {
        "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.20;\n\n/// @title Commands\n/// @notice Command Flags used to decode commands\nlibrary Commands {\n    // Masks to extract certain bits of commands\n    bytes1 internal constant COMMAND_TYPE_MASK = 0x3f;\n\n    uint8 constant SWAP_IF_BOUNDARY = 0x09;\n    uint8 constant BRIDGE_IF_BOUNDARY = 0x13;\n    // swap 0x00 => 0x09\n\n    uint8 constant V3_SWAP_EXACT_IN = 0x00;\n    uint8 constant V2_SWAP_EXACT_IN = 0x01;\n    uint8 constant STARGATE_SWAP = 0x02;\n    uint8 constant SYNC_SWAP = 0x03;\n\n    // bridge 0x0a => 0x13\n    uint8 constant BRIDGE_ORBITER = 0x0a;\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/constants/ZookeyRouterConstants.sol": {
        "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.20;\n\nlibrary ZookeyRouterConstants {\n    /// @dev Used for identifying cases when this contract's balance of a token is to be used as an input\n    /// This value is equivalent to 1<<255, i.e. a singular 1 in the most significant bit.\n    uint256 internal constant CONTRACT_BALANCE =\n        0x8000000000000000000000000000000000000000000000000000000000000000;\n\n    // Mainnet 0x68b3465833fb72A70ecDF485E0e4C7bD8665Fc45\n    // Arbitrum 0x68b3465833fb72A70ecDF485E0e4C7bD8665Fc45\n    // Optimism 0x68b3465833fb72A70ecDF485E0e4C7bD8665Fc45\n    // Polygon 0x68b3465833fb72A70ecDF485E0e4C7bD8665Fc45\n    // Base 0x2626664c2603336E57B271c5C0b26F421741e481\n    // Scroll 0xfc30937f5cDe93Df8d48aCAF7e6f5D8D8A31F636\n    address internal constant UNI_SWAP_ROUTER_V3 =\n        0x68b3465833fb72A70ecDF485E0e4C7bD8665Fc45;\n\n    // Mainnet 0x68b3465833fb72A70ecDF485E0e4C7bD8665Fc45\n    // Arbitrum 0x68b3465833fb72A70ecDF485E0e4C7bD8665Fc45\n    // Optimism 0x68b3465833fb72A70ecDF485E0e4C7bD8665Fc45\n    // Polygon 0x68b3465833fb72A70ecDF485E0e4C7bD8665Fc45\n    // Base 0x2626664c2603336E57B271c5C0b26F421741e481\n    // Scroll 0xfc30937f5cDe93Df8d48aCAF7e6f5D8D8A31F636\n    address internal constant UNI_SWAP_ROUTER_V2 =\n        0x68b3465833fb72A70ecDF485E0e4C7bD8665Fc45;\n\n    // ETH:     0x8731d54E9D02c286767d56ac03e8037C07e01e98\n    // BNB      0x4a364f8c717cAAD9A442737Eb7b8A55cc6cf18D8\n    // POLYGON: 0x45A01E4e04F14f7A4a6702c74187c5F6222033cd\n    // ARB:     0x53Bf833A5d6c4ddA888F69c22C88C9f356a41614\n    // OP:      0xB0D502E938ed5f4df2E681fE6E419ff29631d62b\n    // BASE:    0x45f1A95A4D3f3836523F5c83673c797f4d4d263B\n    // Linea    0x2F6F07CDcf3588944Bf4C42aC74ff24bF56e7590\n    // Avalanche   0x45A01E4e04F14f7A4a6702c74187c5F6222033cd\n    address internal constant STARGATE_ROUTER =\n        0x8731d54E9D02c286767d56ac03e8037C07e01e98;\n\n    // ZK 0x2da10A1e27bF85cEdD8FFb1AbBe97e53391C0295\n    // Scroll 0x80e38291e06339d10AAB483C65695D004dBD5C69\n    address internal constant SYNCSWAP_ROUTER =\n        0x80e38291e06339d10AAB483C65695D004dBD5C69;\n}\n"
      },
      "contracts/libraries/errors/ZookeyRouterErrors.sol": {
        "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.20;\n\nlibrary ZookeyRouterErrors {\n    string internal constant SWAP_INPUTS_ERR = \"swap inputs err\";\n    string internal constant SWAP_COMMANDS_ERR = \"swap commands err\";\n    string internal constant TRANSACTION_DEADLINE = \"trans Deadline Passed\";\n    string internal constant EXECUTE_LENGTH_ERR = \"Execute Length Mismatch\";\n    string internal constant V3_TRANSFER_ERROR = \"v3 transfer err\";\n    string internal constant FROM_TOKEN_ADDR_ERR = \"ETH should use WETH\";\n    string internal constant STARGATE_SWAP_AMOUNT_ERR =\n        \"before amount should gt after amount\";\n    string internal constant SYNC_SWAP_AMOUNT_OUT_ERR =\n        \"swap amount out should gt 0\";\n}\n"
      },
      "contracts/ZookeyRouter.sol": {
        "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.20;\n\nimport \"@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol\";\nimport \"@uniswap/v3-periphery/contracts/libraries/TransferHelper.sol\";\nimport {Commands} from \"./libraries/Commands.sol\";\nimport {ZookeyConstants} from \"./libraries/constants/Common.sol\";\nimport {ZookeyRouterConstants} from \"./libraries/constants/ZookeyRouterConstants.sol\";\nimport {BytesLib} from \"./libraries/BytesLib.sol\";\nimport {ZookeyRouterErrors} from \"./libraries/errors/ZookeyRouterErrors.sol\";\nimport \"./interface/IWETH.sol\";\nimport {ISwapRouter02} from \"./interface/ISwapRouter02.sol\";\nimport {IZookeyRouter} from \"./interface/IZookeyRouter.sol\";\nimport {IStargateRouter} from \"./interface/IStargateRouter.sol\";\nimport {ISyncSwap} from \"./interface/ISyncSwap.sol\";\nimport \"./base/LockAndMsgSender.sol\";\n\ncontract ZookeyRouter is IZookeyRouter, OwnableUpgradeable, LockAndMsgSender {\n    using BytesLib for bytes;\n\n    modifier checkDeadline(uint256 deadline) {\n        if (block.timestamp > deadline) revert TransactionDeadlinePassed();\n        _;\n    }\n\n    /**\n     * @dev sets initials supply and the owner\n     */\n    function initialize(address _owner) external initializer {\n        __Ownable_init(_owner);\n        _initLockedBy();\n    }\n\n    function execute(\n        address fromToken,\n        address toToken,\n        bytes calldata commands,\n        bytes[] calldata inputs,\n        uint256 deadline\n    ) external payable isNotLocked {\n        require(commands.length > 0, ZookeyRouterErrors.SWAP_COMMANDS_ERR);\n        require(inputs.length > 0, ZookeyRouterErrors.SWAP_INPUTS_ERR);\n        require(\n            block.timestamp <= deadline,\n            ZookeyRouterErrors.TRANSACTION_DEADLINE\n        );\n        _execute(fromToken, toToken, commands, inputs, deadline);\n    }\n\n    function _execute(\n        address _fromToken,\n        address _toToken,\n        bytes calldata _commands,\n        bytes[] calldata _inputs,\n        uint256 _deadline\n    ) internal {\n        bool success;\n        uint256 numCommands = _commands.length;\n\n        require(\n            _inputs.length == numCommands,\n            ZookeyRouterErrors.EXECUTE_LENGTH_ERR\n        );\n\n        // loop through all given _commands, execute them and pass along outputs as defined\n        for (uint256 commandIndex = 0; commandIndex < numCommands; ) {\n            bytes1 command = _commands[commandIndex];\n\n            bytes calldata input = _inputs[commandIndex];\n\n            success = _dispatch(\n                _fromToken,\n                _toToken,\n                command,\n                input,\n                _deadline\n            );\n\n            if (!success) {\n                revert ExecutionFailed({\n                    commandIndex: commandIndex,\n                    message: \"dispatch err\"\n                });\n            }\n\n            unchecked {\n                commandIndex++;\n            }\n        }\n    }\n\n    function _dispatch(\n        address _fromToken,\n        address _toToken,\n        bytes1 _commandType,\n        bytes calldata _input,\n        uint256 _deadline\n    ) internal checkDeadline(_deadline) returns (bool success) {\n        uint256 command = uint8(_commandType & Commands.COMMAND_TYPE_MASK);\n        success = true;\n        if (command <= Commands.BRIDGE_IF_BOUNDARY) {\n            if (command <= Commands.SWAP_IF_BOUNDARY) {\n                if (command == Commands.V3_SWAP_EXACT_IN) {\n                    _swapV3ExactIn(_fromToken, _toToken, _input);\n                }\n                if (command == Commands.V2_SWAP_EXACT_IN) {\n                    _swapV2ExactIn(_fromToken, _toToken, _input);\n                }\n                if (command == Commands.STARGATE_SWAP) {\n                    _stargateSwap(_fromToken, _input);\n                }\n                if (command == Commands.SYNC_SWAP) {\n                    _syncSwap(_fromToken, _input);\n                }\n            }\n        } else {\n            success = false;\n        }\n    }\n\n    function _swapV3ExactIn(\n        address _fromToken,\n        address _toToken,\n        bytes calldata _input\n    ) internal {\n        address recipient;\n        uint256 fromTokenAmount;\n        uint256 amountOutMin;\n        bool onlyApprove;\n        // equivalent: abi.decode(inputs, (address, uint256, uint256, bytes))\n        assembly {\n            recipient := calldataload(_input.offset)\n            fromTokenAmount := calldataload(add(_input.offset, 0x20))\n            amountOutMin := calldataload(add(_input.offset, 0x40))\n            // 0x60 offset is the path, decoded below\n        }\n        bytes calldata path = _input.toBytes(3);\n\n        if (fromTokenAmount == ZookeyRouterConstants.CONTRACT_BALANCE) {\n            _fromToken = path.toAddress();\n            fromTokenAmount = IERC20(_fromToken).balanceOf(address(this));\n            onlyApprove = true;\n        }\n\n        if (_fromToken == ZookeyConstants.NATIVE_TOKEN) {\n            IWETH(ZookeyConstants.WNATIVE_TOKEN).deposit{value: msg.value}();\n            onlyApprove = true;\n            _fromToken = ZookeyConstants.WNATIVE_TOKEN;\n        }\n        address lastTokenBytes = address(\n            bytes20(path[path.length - 20:path.length])\n        );\n        bool needToETH = lastTokenBytes == ZookeyConstants.WNATIVE_TOKEN &&\n            _toToken == ZookeyConstants.NATIVE_TOKEN;\n        ISwapRouter02.ExactInputParams memory params = ISwapRouter02\n            .ExactInputParams({\n                path: path,\n                recipient: needToETH ? address(this) : map(recipient),\n                amountIn: fromTokenAmount,\n                amountOutMinimum: amountOutMin\n            });\n        _tokenRelayer(\n            _fromToken,\n            fromTokenAmount,\n            ZookeyRouterConstants.UNI_SWAP_ROUTER_V3,\n            onlyApprove\n        );\n        ISwapRouter02(ZookeyRouterConstants.UNI_SWAP_ROUTER_V3).exactInput(\n            params\n        );\n        if (needToETH) {\n            uint256 amount = IWETH(ZookeyConstants.WNATIVE_TOKEN).balanceOf(\n                address(this)\n            );\n            IWETH(ZookeyConstants.WNATIVE_TOKEN).withdraw(amount);\n            if (map(recipient) != address(this)) {\n                (bool success, ) = payable(map(recipient)).call{value: amount}(\n                    \"\"\n                );\n                require(success, ZookeyRouterErrors.V3_TRANSFER_ERROR);\n            }\n        }\n    }\n\n    function _swapV2ExactIn(\n        address _fromToken,\n        address _toToken,\n        bytes calldata _input\n    ) internal {\n        address recipient;\n        uint256 fromTokenAmount;\n        uint256 amountOutMin;\n        bool onlyApprove;\n        assembly {\n            recipient := calldataload(_input.offset)\n            fromTokenAmount := calldataload(add(_input.offset, 0x20))\n            amountOutMin := calldataload(add(_input.offset, 0x40))\n            // 0x60 offset is the path, decoded below\n        }\n        address[] calldata path = _input.toAddressArray(3);\n        if (fromTokenAmount == ZookeyRouterConstants.CONTRACT_BALANCE) {\n            _fromToken = path[0];\n            fromTokenAmount = IERC20(_fromToken).balanceOf(address(this));\n            onlyApprove = true;\n        }\n\n        if (_fromToken == ZookeyConstants.NATIVE_TOKEN) {\n            IWETH(ZookeyConstants.WNATIVE_TOKEN).deposit{value: msg.value}();\n            onlyApprove = true;\n            _fromToken = ZookeyConstants.WNATIVE_TOKEN;\n        }\n\n        address lastTokenBytes = address(path[path.length - 1]);\n\n        bool needToETH = lastTokenBytes == ZookeyConstants.WNATIVE_TOKEN &&\n            _toToken == ZookeyConstants.NATIVE_TOKEN;\n\n        _tokenRelayer(\n            _fromToken,\n            fromTokenAmount,\n            ZookeyRouterConstants.UNI_SWAP_ROUTER_V2,\n            onlyApprove\n        );\n        ISwapRouter02(ZookeyRouterConstants.UNI_SWAP_ROUTER_V2)\n            .swapExactTokensForTokens(\n                fromTokenAmount,\n                amountOutMin,\n                path,\n                needToETH ? address(this) : map(recipient)\n            );\n        if (needToETH) {\n            uint256 amount = IWETH(ZookeyConstants.WNATIVE_TOKEN).balanceOf(\n                address(this)\n            );\n            IWETH(ZookeyConstants.WNATIVE_TOKEN).withdraw(amount);\n            if (map(recipient) != address(this)) {\n                (bool success, ) = payable(map(recipient)).call{value: amount}(\n                    \"\"\n                );\n                require(success, ZookeyRouterErrors.V3_TRANSFER_ERROR);\n            }\n        }\n    }\n\n    function _stargateSwap(address _fromToken, bytes calldata _input) internal {\n        (\n            uint16 dstChainId,\n            uint256 srcPoolId,\n            uint256 dstPoolId,\n            address payable refundAddress,\n            uint256 amountLD,\n            uint256 minAmountLD,\n            IStargateRouter.lzTxObj memory lzTxParams,\n            bytes memory to,\n            bytes memory payload\n        ) = abi.decode(\n                _input,\n                (\n                    uint16,\n                    uint256,\n                    uint256,\n                    address,\n                    uint256,\n                    uint256,\n                    IStargateRouter.lzTxObj,\n                    bytes,\n                    bytes\n                )\n            );\n        _tokenRelayer(\n            _fromToken,\n            amountLD,\n            ZookeyRouterConstants.STARGATE_ROUTER,\n            false\n        );\n        // perform a Stargate swap() in a solidity smart contract function\n        // the msg.value is the \"fee\" that Stargate needs to pay for the cross chain message\n        uint256 beforeBalance = address(this).balance;\n        IStargateRouter(ZookeyRouterConstants.STARGATE_ROUTER).swap{\n            value: msg.value\n        }(\n            dstChainId,\n            srcPoolId, // source pool id\n            dstPoolId, // dest pool id\n            refundAddress, // refund address. extra gas (if any) is returned to this address\n            amountLD, // quantity to swap in LD, (local decimals)\n            minAmountLD, // the min qty you would accept in LD (local decimals)\n            lzTxParams, // 0 additional gasLimit increase, 0 airdrop, at 0x address\n            to, // the address to send the tokens to on the destination\n            payload // bytes param, if you wish to send additional payload you can abi.encode() them here\n        );\n        require(\n            beforeBalance > address(this).balance,\n            ZookeyRouterErrors.STARGATE_SWAP_AMOUNT_ERR\n        );\n    }\n\n    function _syncSwap(address _fromToken, bytes calldata _input) internal {\n        (\n            ISyncSwap.SwapPath[] memory paths,\n            uint256 fromTokenIn,\n            uint256 amountOutMin,\n            uint256 deadline\n        ) = abi.decode(\n                _input,\n                (ISyncSwap.SwapPath[], uint256, uint256, uint256)\n            );\n        if (_fromToken != ZookeyConstants.NATIVE_TOKEN) {\n            _tokenRelayer(\n                _fromToken,\n                fromTokenIn,\n                ZookeyRouterConstants.SYNCSWAP_ROUTER,\n                false\n            );\n        }\n        uint256 amountOut = ISyncSwap(ZookeyRouterConstants.SYNCSWAP_ROUTER)\n            .swap{value: msg.value}(paths, amountOutMin, deadline);\n        require(amountOut > 0, ZookeyRouterErrors.SYNC_SWAP_AMOUNT_OUT_ERR);\n    }\n\n    function _tokenRelayer(\n        address _fromToken,\n        uint256 _fromTokenAmount,\n        address _approveTo,\n        bool _onlyApprove\n    ) internal {\n        if (!_onlyApprove) {\n            TransferHelper.safeTransferFrom(\n                _fromToken,\n                msg.sender,\n                address(this),\n                _fromTokenAmount\n            );\n        }\n        TransferHelper.safeApprove(_fromToken, _approveTo, _fromTokenAmount);\n    }\n\n    /// @notice To receive ETH from WETH and refund\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": {}
    }
  }}