creation_sourcecode: {{
    "language": "Solidity",
    "sources": {
      "contracts/connectors/UniswapV3Connector.sol": {
        "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"../interfaces/ILiquidityConnector.sol\";\nimport \"../interfaces/external/uniswap/INonfungiblePositionManager.sol\";\nimport \"../interfaces/external/uniswap/ISwapRouter.sol\";\n\nstruct UniswapV3AddLiquidityExtraData {\n    int24 tickLower;\n    int24 tickUpper;\n    uint24 fee;\n}\n\nstruct UniswapV3RemoveLiquidityExtraData {\n    uint256 tokenId;\n    uint128 amount0Max;\n    uint128 amount1Max;\n}\n\nstruct UniswapV3SwapExtraData {\n    address pool;\n    bytes path;\n}\n\ncontract UniswapV3Connector is ILiquidityConnector {\n    constructor() { }\n\n    function addLiquidity(AddLiquidityData memory addLiquidityData)\n        external\n        payable\n        override\n    {\n        UniswapV3AddLiquidityExtraData memory extra = abi.decode(\n            addLiquidityData.extraData, (UniswapV3AddLiquidityExtraData)\n        );\n\n        INonfungiblePositionManager.MintParams memory params =\n        INonfungiblePositionManager.MintParams({\n            token0: addLiquidityData.tokens[0],\n            token1: addLiquidityData.tokens[1],\n            fee: extra.fee,\n            tickLower: extra.tickLower,\n            tickUpper: extra.tickUpper,\n            amount0Desired: addLiquidityData.desiredAmounts[0],\n            amount1Desired: addLiquidityData.desiredAmounts[1],\n            amount0Min: addLiquidityData.minAmounts[0],\n            amount1Min: addLiquidityData.minAmounts[1],\n            recipient: address(this),\n            deadline: block.timestamp + 1\n        });\n\n        //(uint256 tokenId, uint128 liquidity, uint256 amount0, uint256 amount1)\n        // =\n        INonfungiblePositionManager(addLiquidityData.router).mint(params);\n    }\n\n    function removeLiquidity(RemoveLiquidityData memory removeLiquidityData)\n        external\n        override\n    {\n        UniswapV3RemoveLiquidityExtraData memory extra = abi.decode(\n            removeLiquidityData.extraData, (UniswapV3RemoveLiquidityExtraData)\n        );\n\n        (,,,,,,, uint128 liquidity,,,,) = INonfungiblePositionManager(\n            removeLiquidityData.router\n        ).positions(extra.tokenId);\n        INonfungiblePositionManager.DecreaseLiquidityParams memory params =\n        INonfungiblePositionManager.DecreaseLiquidityParams({\n            tokenId: extra.tokenId,\n            liquidity: liquidity,\n            amount0Min: removeLiquidityData.minAmountsOut[0],\n            amount1Min: removeLiquidityData.minAmountsOut[1],\n            deadline: block.timestamp + 1\n        });\n\n        INonfungiblePositionManager(removeLiquidityData.router)\n            .decreaseLiquidity(params);\n\n        INonfungiblePositionManager(removeLiquidityData.router).collect(\n            INonfungiblePositionManager.CollectParams({\n                tokenId: extra.tokenId,\n                recipient: address(this),\n                amount0Max: extra.amount0Max,\n                amount1Max: extra.amount1Max\n            })\n        );\n\n        INonfungiblePositionManager(removeLiquidityData.router).burn(\n            extra.tokenId\n        );\n    }\n\n    function swapExactTokensForTokens(SwapData memory swapData)\n        external\n        payable\n        override\n    {\n        UniswapV3SwapExtraData memory extraData =\n            abi.decode(swapData.extraData, (UniswapV3SwapExtraData));\n\n        IERC20(swapData.tokenIn).approve(\n            address(extraData.pool), swapData.amountIn\n        );\n\n        ISwapRouter.ExactInputParams memory params = ISwapRouter\n            .ExactInputParams({\n            path: extraData.path,\n            recipient: address(this),\n            deadline: block.timestamp + 1,\n            amountIn: swapData.amountIn,\n            amountOutMinimum: swapData.minAmountOut\n        });\n\n        ISwapRouter(swapData.router).exactInput(params);\n    }\n}\n"
      },
      "lib/openzeppelin-contracts/contracts/token/ERC20/IERC20.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol)\n\npragma solidity ^0.8.0;\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 amount of tokens in existence.\n     */\n    function totalSupply() external view returns (uint256);\n\n    /**\n     * @dev Returns the amount of tokens owned by `account`.\n     */\n    function balanceOf(address account) external view returns (uint256);\n\n    /**\n     * @dev Moves `amount` 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 amount) 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 `amount` as the allowance of `spender` over the 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 amount) external returns (bool);\n\n    /**\n     * @dev Moves `amount` tokens from `from` to `to` using the\n     * allowance mechanism. `amount` 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(\n        address from,\n        address to,\n        uint256 amount\n    ) external returns (bool);\n}\n"
      },
      "contracts/interfaces/ILiquidityConnector.sol": {
        "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nstruct AddLiquidityData {\n    address router;\n    address lpToken;\n    address[] tokens;\n    uint256[] desiredAmounts;\n    uint256[] minAmounts;\n    bytes extraData;\n}\n\nstruct RemoveLiquidityData {\n    address router;\n    address lpToken;\n    address[] tokens;\n    uint256 lpAmountIn;\n    uint256[] minAmountsOut;\n    bytes extraData;\n}\n\nstruct SwapData {\n    address router;\n    uint256 amountIn;\n    uint256 minAmountOut;\n    address tokenIn;\n    bytes extraData;\n}\n\ninterface ILiquidityConnector {\n    function addLiquidity(AddLiquidityData memory addLiquidityData)\n        external\n        payable;\n\n    function removeLiquidity(RemoveLiquidityData memory removeLiquidityData)\n        external;\n\n    function swapExactTokensForTokens(SwapData memory swapData)\n        external\n        payable;\n}\n"
      },
      "contracts/interfaces/external/uniswap/INonfungiblePositionManager.sol": {
        "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\ninterface INonfungiblePositionManager {\n    struct IncreaseLiquidityParams {\n        uint256 tokenId;\n        uint256 amount0Desired;\n        uint256 amount1Desired;\n        uint256 amount0Min;\n        uint256 amount1Min;\n        uint256 deadline;\n    }\n\n    struct MintParams {\n        address token0;\n        address token1;\n        uint24 fee;\n        int24 tickLower;\n        int24 tickUpper;\n        uint256 amount0Desired;\n        uint256 amount1Desired;\n        uint256 amount0Min;\n        uint256 amount1Min;\n        address recipient;\n        uint256 deadline;\n    }\n\n    struct DecreaseLiquidityParams {\n        uint256 tokenId;\n        uint128 liquidity;\n        uint256 amount0Min;\n        uint256 amount1Min;\n        uint256 deadline;\n    }\n\n    struct CollectParams {\n        uint256 tokenId;\n        address recipient;\n        uint128 amount0Max;\n        uint128 amount1Max;\n    }\n\n    function increaseLiquidity(IncreaseLiquidityParams memory params)\n        external\n        payable\n        returns (uint256 amount0, uint256 amount1, uint256 liquidity);\n\n    function decreaseLiquidity(DecreaseLiquidityParams calldata params)\n        external\n        payable\n        returns (uint256 amount0, uint256 amount1);\n\n    function mint(MintParams memory params)\n        external\n        payable\n        returns (uint256 tokenId, uint256 amount0, uint256 amount1);\n\n    function collect(CollectParams calldata params)\n        external\n        payable\n        returns (uint256 amount0, uint256 amount1);\n\n    function burn(uint256 tokenId) external payable;\n\n    function positions(uint256 tokenId)\n        external\n        view\n        returns (\n            uint96 nonce,\n            address operator,\n            address token0,\n            address token1,\n            uint24 fee,\n            int24 tickLower,\n            int24 tickUpper,\n            uint128 liquidity,\n            uint256 feeGrowthInside0LastX128,\n            uint256 feeGrowthInside1LastX128,\n            uint128 tokensOwed0,\n            uint128 tokensOwed1\n        );\n}\n"
      },
      "contracts/interfaces/external/uniswap/ISwapRouter.sol": {
        "content": "// SPDX-License-Identifier: GPL-2.0-or-later\npragma solidity >=0.7.5;\n\n/// @title Router token swapping functionality\n/// @notice Functions for swapping tokens via Uniswap V3\ninterface ISwapRouter {\n    struct ExactInputSingleParams {\n        address tokenIn;\n        address tokenOut;\n        uint24 fee;\n        address recipient;\n        uint256 deadline;\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\n    /// token\n    /// @param params The parameters necessary for the swap, encoded as\n    /// `ExactInputSingleParams` in calldata\n    /// @return amountOut The amount of the received token\n    function exactInputSingle(ExactInputSingleParams calldata params)\n        external\n        payable\n        returns (uint256 amountOut);\n\n    struct ExactInputParams {\n        bytes path;\n        address recipient;\n        uint256 deadline;\n        uint256 amountIn;\n        uint256 amountOutMinimum;\n    }\n\n    /// @notice Swaps `amountIn` of one token for as much as possible of another\n    /// along the specified path\n    /// @param params The parameters necessary for the multi-hop swap, encoded\n    /// as `ExactInputParams` in calldata\n    /// @return amountOut The amount of the received token\n    function exactInput(ExactInputParams calldata params)\n        external\n        payable\n        returns (uint256 amountOut);\n\n    struct ExactOutputSingleParams {\n        address tokenIn;\n        address tokenOut;\n        uint24 fee;\n        address recipient;\n        uint256 deadline;\n        uint256 amountOut;\n        uint256 amountInMaximum;\n        uint160 sqrtPriceLimitX96;\n    }\n\n    /// @notice Swaps as little as possible of one token for `amountOut` of\n    /// another token\n    /// @param params The parameters necessary for the swap, encoded as\n    /// `ExactOutputSingleParams` in calldata\n    /// @return amountIn The amount of the input token\n    function exactOutputSingle(ExactOutputSingleParams calldata params)\n        external\n        payable\n        returns (uint256 amountIn);\n\n    struct ExactOutputParams {\n        bytes path;\n        address recipient;\n        uint256 deadline;\n        uint256 amountOut;\n        uint256 amountInMaximum;\n    }\n\n    /// @notice Swaps as little as possible of one token for `amountOut` of\n    /// another along the specified path (reversed)\n    /// @param params The parameters necessary for the multi-hop swap, encoded\n    /// as `ExactOutputParams` in calldata\n    /// @return amountIn The amount of the input token\n    function exactOutput(ExactOutputParams calldata params)\n        external\n        payable\n        returns (uint256 amountIn);\n}\n"
      }
    },
    "settings": {
      "remappings": [
        "solmate/=lib/solmate/src/",
        "@openzeppelin/=lib/openzeppelin-contracts/",
        "@uniswap/v3-periphery/=lib/v3-periphery/",
        "@uniswap/v3-core/=lib/v3-core/",
        "ds-test/=lib/forge-std/lib/ds-test/src/",
        "forge-std/=lib/forge-std/src/",
        "openzeppelin-contracts/=lib/openzeppelin-contracts/"
      ],
      "optimizer": {
        "enabled": true,
        "runs": 200
      },
      "metadata": {
        "useLiteralContent": false,
        "bytecodeHash": "ipfs",
        "appendCBOR": true
      },
      "outputSelection": {
        "*": {
          "*": [
            "evm.bytecode",
            "evm.deployedBytecode",
            "devdoc",
            "userdoc",
            "metadata",
            "abi"
          ]
        }
      },
      "evmVersion": "paris",
      "viaIR": false,
      "libraries": {}
    }
  }}