// SPDX-License-Identifier: MIT pragma solidity ^0.7.6; pragma abicoder v2; import "@openzeppelin/contracts/token/ERC721/IERC721.sol"; import "@openzeppelin/contracts/token/ERC721/IERC721Metadata.sol"; import "@openzeppelin/contracts/token/ERC721/IERC721Enumerable.sol"; /** * @title Callback for IUniswapV3PoolActions#swap * @notice Any contract that calls IUniswapV3PoolActions#swap must implement this interface */ interface IUniswapV3SwapCallback { /** * @notice Called to `msg.sender` after executing a swap via IUniswapV3Pool#swap. * @dev In the implementation you must pay the pool tokens owed for the swap. * The caller of this method must be checked to be a UniswapV3Pool deployed by the canonical UniswapV3Factory. * amount0Delta and amount1Delta can both be 0 if no tokens were swapped. * @param amount0Delta The amount of token0 that was sent (negative) or must be received (positive) by the pool by * the end of the swap. If positive, the callback must send that amount of token0 to the pool. * @param amount1Delta The amount of token1 that was sent (negative) or must be received (positive) by the pool by * the end of the swap. If positive, the callback must send that amount of token1 to the pool. * @param data Any data passed through by the caller via the IUniswapV3PoolActions#swap call */ function uniswapV3SwapCallback( int256 amount0Delta, int256 amount1Delta, bytes calldata data ) external; } interface ISwapRouter is IUniswapV3SwapCallback { struct ExactInputSingleParams { address tokenIn; address tokenOut; uint24 fee; address recipient; uint256 deadline; uint256 amountIn; uint256 amountOutMinimum; uint160 sqrtPriceLimitX96; } /** * @notice Swaps `amountIn` of one token for as much as possible of another token * @param params The parameters necessary for the swap, encoded as `ExactInputSingleParams` in calldata * @return amountOut The amount of the received token */ function exactInputSingle(ExactInputSingleParams calldata params) external payable returns (uint256 amountOut); struct ExactInputParams { bytes path; address recipient; uint256 deadline; uint256 amountIn; uint256 amountOutMinimum; } /** * @notice Swaps `amountIn` of one token for as much as possible of another along the specified path * @param params The parameters necessary for the multi-hop swap, encoded as `ExactInputParams` in calldata * @return amountOut The amount of the received token */ function exactInput(ExactInputParams calldata params) external payable returns (uint256 amountOut); struct ExactOutputSingleParams { address tokenIn; address tokenOut; uint24 fee; address recipient; uint256 deadline; uint256 amountOut; uint256 amountInMaximum; uint160 sqrtPriceLimitX96; } /** * @notice Swaps as little as possible of one token for `amountOut` of another token * @param params The parameters necessary for the swap, encoded as `ExactOutputSingleParams` in calldata * @return amountIn The amount of the input token */ function exactOutputSingle(ExactOutputSingleParams calldata params) external payable returns (uint256 amountIn); struct ExactOutputParams { bytes path; address recipient; uint256 deadline; uint256 amountOut; uint256 amountInMaximum; } /** * @notice Swaps as little as possible of one token for `amountOut` of another along the specified path (reversed) * @param params The parameters necessary for the multi-hop swap, encoded as `ExactOutputParams` in calldata * @return amountIn The amount of the input token */ function exactOutput(ExactOutputParams calldata params) external payable returns (uint256 amountIn); } /** * @title Creates and initializes V3 Pools * @notice Provides a method for creating and initializing a pool, if necessary, for bundling with other methods that * require the pool to exist. */ interface IPoolInitializer { /** * @notice Creates a new pool if it does not exist, then initializes if not initialized * @dev This method can be bundled with others via IMulticall for the first action (e.g. mint) performed against a pool * @param token0 The contract address of token0 of the pool * @param token1 The contract address of token1 of the pool * @param fee The fee amount of the v3 pool for the specified token pair * @param sqrtPriceX96 The initial square root price of the pool as a Q64.96 value * @return pool Returns the pool address based on the pair of tokens and fee, will return the newly created pool address if necessary */ function createAndInitializePoolIfNecessary( address token0, address token1, uint24 fee, uint160 sqrtPriceX96 ) external payable returns (address pool); } /** * @title Immutable state * @notice Functions that return immutable state of the router */ interface IPeripheryImmutableState { /// @return Returns the address of the Uniswap V3 factory function factory() external view returns (address); /// @return Returns the address of WETH9 function WETH9() external view returns (address); } /** * @title Periphery Payments * @notice Functions to ease deposits and withdrawals of ETH */ interface IPeripheryPayments { /** * @notice Unwraps the contract's WETH9 balance and sends it to recipient as ETH. * @dev The amountMinimum parameter prevents malicious contracts from stealing WETH9 from users. * @param amountMinimum The minimum amount of WETH9 to unwrap * @param recipient The address receiving ETH */ function unwrapWETH9(uint256 amountMinimum, address recipient) external payable; /** * @notice Refunds any ETH balance held by this contract to the `msg.sender` * @dev Useful for bundling with mint or increase liquidity that uses ether, or exact output swaps * that use ether for the input amount */ function refundETH() external payable; /** * @notice Transfers the full amount of a token held by this contract to recipient * @dev The amountMinimum parameter prevents malicious contracts from stealing the token from users * @param token The contract address of the token which will be transferred to `recipient` * @param amountMinimum The minimum amount of token required for a transfer * @param recipient The destination address of the token */ function sweepToken( address token, uint256 amountMinimum, address recipient ) external payable; } /** * @title ERC721 with permit * @notice Extension to ERC721 that includes a permit function for signature based approvals */ interface IERC721Permit is IERC721 { /** * @notice The permit typehash used in the permit signature * @return The typehash for the permit */ function PERMIT_TYPEHASH() external pure returns (bytes32); /** * @notice The domain separator used in the permit signature * @return The domain seperator used in encoding of permit signature */ function DOMAIN_SEPARATOR() external view returns (bytes32); /** * @notice Approve of a specific token ID for spending by spender via signature * @param spender The account that is being approved * @param tokenId The ID of the token that is being approved for spending * @param deadline The deadline timestamp by which the call must be mined for the approve to work * @param v Must produce valid secp256k1 signature from the holder along with `r` and `s` * @param r Must produce valid secp256k1 signature from the holder along with `v` and `s` * @param s Must produce valid secp256k1 signature from the holder along with `r` and `v` */ function permit( address spender, uint256 tokenId, uint256 deadline, uint8 v, bytes32 r, bytes32 s ) external payable; } /** * @title Non-fungible token for positions * @notice Wraps Uniswap V3 positions in a non-fungible token interface which allows for them to be transferred * and authorized. */ interface INonfungiblePositionManager is IPoolInitializer, IPeripheryPayments, IPeripheryImmutableState, IERC721Metadata, IERC721Enumerable, IERC721Permit { /** * @notice Emitted when liquidity is increased for a position NFT * @dev Also emitted when a token is minted * @param tokenId The ID of the token for which liquidity was increased * @param liquidity The amount by which liquidity for the NFT position was increased * @param amount0 The amount of token0 that was paid for the increase in liquidity * @param amount1 The amount of token1 that was paid for the increase in liquidity */ event IncreaseLiquidity( uint256 indexed tokenId, uint128 liquidity, uint256 amount0, uint256 amount1 ); /** * @notice Emitted when liquidity is decreased for a position NFT * @param tokenId The ID of the token for which liquidity was decreased * @param liquidity The amount by which liquidity for the NFT position was decreased * @param amount0 The amount of token0 that was accounted for the decrease in liquidity * @param amount1 The amount of token1 that was accounted for the decrease in liquidity */ event DecreaseLiquidity( uint256 indexed tokenId, uint128 liquidity, uint256 amount0, uint256 amount1 ); /** * @notice Emitted when tokens are collected for a position NFT * @dev The amounts reported may not be exactly equivalent to the amounts transferred, due to rounding behavior * @param tokenId The ID of the token for which underlying tokens were collected * @param recipient The address of the account that received the collected tokens * @param amount0 The amount of token0 owed to the position that was collected * @param amount1 The amount of token1 owed to the position that was collected */ event Collect( uint256 indexed tokenId, address recipient, uint256 amount0, uint256 amount1 ); /** * @notice Returns the position information associated with a given token ID. * @dev Throws if the token ID is not valid. * @param tokenId The ID of the token that represents the position * @return nonce The nonce for permits * @return operator The address that is approved for spending * @return token0 The address of the token0 for a specific pool * @return token1 The address of the token1 for a specific pool * @return fee The fee associated with the pool * @return tickLower The lower end of the tick range for the position * @return tickUpper The higher end of the tick range for the position * @return liquidity The liquidity of the position * @return feeGrowthInside0LastX128 The fee growth of token0 as of the last action on the individual position * @return feeGrowthInside1LastX128 The fee growth of token1 as of the last action on the individual position * @return tokensOwed0 The uncollected amount of token0 owed to the position as of the last computation * @return tokensOwed1 The uncollected amount of token1 owed to the position as of the last computation */ function positions(uint256 tokenId) external view returns ( uint96 nonce, address operator, address token0, address token1, uint24 fee, int24 tickLower, int24 tickUpper, uint128 liquidity, uint256 feeGrowthInside0LastX128, uint256 feeGrowthInside1LastX128, uint128 tokensOwed0, uint128 tokensOwed1 ); struct MintParams { address token0; address token1; uint24 fee; int24 tickLower; int24 tickUpper; uint256 amount0Desired; uint256 amount1Desired; uint256 amount0Min; uint256 amount1Min; address recipient; uint256 deadline; } /** * @notice Creates a new position wrapped in a NFT * @dev Call this when the pool does exist and is initialized. Note that if the pool is created but not initialized * a method does not exist, i.e. the pool is assumed to be initialized. * @param params The params necessary to mint a position, encoded as `MintParams` in calldata * @return tokenId The ID of the token that represents the minted position * @return liquidity The amount of liquidity for this position * @return amount0 The amount of token0 * @return amount1 The amount of token1 */ function mint(MintParams calldata params) external payable returns ( uint256 tokenId, uint128 liquidity, uint256 amount0, uint256 amount1 ); struct IncreaseLiquidityParams { uint256 tokenId; uint256 amount0Desired; uint256 amount1Desired; uint256 amount0Min; uint256 amount1Min; uint256 deadline; } /** * @notice Increases the amount of liquidity in a position, with tokens paid by the `msg.sender` * @param params tokenId The ID of the token for which liquidity is being increased, * amount0Desired The desired amount of token0 to be spent, * amount1Desired The desired amount of token1 to be spent, * amount0Min The minimum amount of token0 to spend, which serves as a slippage check, * amount1Min The minimum amount of token1 to spend, which serves as a slippage check, * deadline The time by which the transaction must be included to effect the change * @return liquidity The new liquidity amount as a result of the increase * @return amount0 The amount of token0 to acheive resulting liquidity * @return amount1 The amount of token1 to acheive resulting liquidity */ function increaseLiquidity(IncreaseLiquidityParams calldata params) external payable returns ( uint128 liquidity, uint256 amount0, uint256 amount1 ); struct DecreaseLiquidityParams { uint256 tokenId; uint128 liquidity; uint256 amount0Min; uint256 amount1Min; uint256 deadline; } /** * @notice Decreases the amount of liquidity in a position and accounts it to the position * @param params tokenId The ID of the token for which liquidity is being decreased, * amount The amount by which liquidity will be decreased, * amount0Min The minimum amount of token0 that should be accounted for the burned liquidity, * amount1Min The minimum amount of token1 that should be accounted for the burned liquidity, * deadline The time by which the transaction must be included to effect the change * @return amount0 The amount of token0 accounted to the position's tokens owed * @return amount1 The amount of token1 accounted to the position's tokens owed */ function decreaseLiquidity(DecreaseLiquidityParams calldata params) external payable returns (uint256 amount0, uint256 amount1); struct CollectParams { uint256 tokenId; address recipient; uint128 amount0Max; uint128 amount1Max; } /** * @notice Collects up to a maximum amount of fees owed to a specific position to the recipient * @param params tokenId The ID of the NFT for which tokens are being collected, * recipient The account that should receive the tokens, * amount0Max The maximum amount of token0 to collect, * amount1Max The maximum amount of token1 to collect * @return amount0 The amount of fees collected in token0 * @return amount1 The amount of fees collected in token1 */ function collect(CollectParams calldata params) external payable returns (uint256 amount0, uint256 amount1); /** * @notice Burns a token ID, which deletes it from the NFT contract. The token must have 0 liquidity and all tokens * must be collected first. * @param tokenId The ID of the token that is being burned */ function burn(uint256 tokenId) external payable; }