added uniswap v3

This commit is contained in:
pradyuman-verma 2022-01-16 15:13:58 +05:30
parent a786a17fcf
commit cb2d3bec48
No known key found for this signature in database
GPG Key ID: E36FD6BC8923221F
4 changed files with 954 additions and 0 deletions

View File

@ -0,0 +1,35 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.7.0;
contract Events {
event LogMint(
uint256 indexed tokenId,
uint256 liquidity,
uint256 amtA,
uint256 amtB,
int24 tickLower,
int24 tickUpper
);
event LogDeposit(
uint256 indexed tokenId,
uint256 liquidity,
uint256 amountA,
uint256 amountB
);
event LogWithdraw(
uint256 indexed tokenId,
uint256 liquidity,
uint256 amountA,
uint256 amountB
);
event LogCollect(
uint256 tokenId,
uint256 amountA,
uint256 amountB
);
event LogBurnPosition(uint256 tokenId);
}

View File

@ -0,0 +1,288 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.7.6;
pragma abicoder v2;
import {TokenInterface} from "../../../common/interfaces.sol";
import {DSMath} from "../../../common/math.sol";
import {Basic} from "../../../common/basic.sol";
import "./interface.sol";
import "@uniswap/v3-core/contracts/interfaces/IUniswapV3Pool.sol";
import "@uniswap/v3-core/contracts/libraries/TickMath.sol";
import "@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol";
import "@uniswap/v3-periphery/contracts/libraries/TransferHelper.sol";
abstract contract Helpers is DSMath, Basic {
/**
* @dev uniswap v3 NFT Position Manager & Swap Router
*/
INonfungiblePositionManager constant nftManager =
INonfungiblePositionManager(0xC36442b4a4522E871399CD717aBDD847Ab11FE88);
ISwapRouter constant swapRouter =
ISwapRouter(0xE592427A0AEce92De3Edee1F18E0157C05861564);
struct MintParams {
address tokenA;
address tokenB;
uint24 fee;
int24 tickLower;
int24 tickUpper;
uint256 amtA;
uint256 amtB;
uint256 slippage;
}
/**
* @dev Get Last NFT Index
* @param user: User address
*/
function _getLastNftId(address user)
internal
view
returns (uint256 tokenId)
{
uint256 len = nftManager.balanceOf(user);
tokenId = nftManager.tokenOfOwnerByIndex(user, len - 1);
}
function getMinAmount(
TokenInterface token,
uint256 amt,
uint256 slippage
) internal view returns (uint256 minAmt) {
uint256 _amt18 = convertTo18(token.decimals(), amt);
minAmt = wmul(_amt18, sub(WAD, slippage));
minAmt = convert18ToDec(token.decimals(), minAmt);
}
function sortTokenAddress(address _token0, address _token1)
internal
view
returns (address token0, address token1)
{
if (_token0 > _token1) {
(token0, token1) = (_token1, _token0);
} else {
(token0, token1) = (_token0, _token1);
}
}
/**
* @dev Mint function which interact with Uniswap v3
*/
function _mint(MintParams memory params)
internal
returns (
uint256 tokenId,
uint128 liquidity,
uint256 amountA,
uint256 amountB
)
{
(TokenInterface _token0, TokenInterface _token1) = changeEthAddress(
params.tokenA,
params.tokenB
);
uint256 _amount0 = params.amtA == uint256(-1)
? getTokenBal(TokenInterface(params.tokenA))
: params.amtA;
uint256 _amount1 = params.amtB == uint256(-1)
? getTokenBal(TokenInterface(params.tokenB))
: params.amtB;
convertEthToWeth(address(_token0) == wethAddr, _token0, _amount0);
convertEthToWeth(address(_token1) == wethAddr, _token1, _amount1);
approve(_token0, address(nftManager), _amount0);
approve(_token1, address(nftManager), _amount1);
{
(address token0, ) = sortTokenAddress(
address(_token0),
address(_token1)
);
if (token0 != address(_token0)) {
(_token0, _token1) = (_token1, _token0);
(_amount0, _amount1) = (_amount1, _amount0);
}
}
uint256 _minAmt0 = getMinAmount(_token0, _amount0, params.slippage);
uint256 _minAmt1 = getMinAmount(_token1, _amount1, params.slippage);
INonfungiblePositionManager.MintParams
memory params = INonfungiblePositionManager.MintParams(
address(_token0),
address(_token1),
params.fee,
params.tickLower,
params.tickUpper,
_amount0,
_amount1,
_minAmt0,
_minAmt1,
address(this),
block.timestamp
);
(tokenId, liquidity, amountA, amountB) = nftManager.mint(params);
}
function getNftTokenPairAddresses(uint256 _tokenId)
internal
view
returns (address token0, address token1)
{
(bool success, bytes memory data) = address(nftManager).staticcall(
abi.encodeWithSelector(nftManager.positions.selector, _tokenId)
);
require(success, "fetching positions failed");
{
(, , token0, token1, , , , ) = abi.decode(
data,
(
uint96,
address,
address,
address,
uint24,
int24,
int24,
uint128
)
);
}
}
/**
* @dev Check if token address is etherAddr and convert it to weth
*/
function _checkETH(
address _token0,
address _token1,
uint256 _amount0,
uint256 _amount1
) internal {
bool isEth0 = _token0 == wethAddr;
bool isEth1 = _token1 == wethAddr;
convertEthToWeth(isEth0, TokenInterface(_token0), _amount0);
convertEthToWeth(isEth1, TokenInterface(_token1), _amount1);
approve(TokenInterface(_token0), address(nftManager), _amount0);
approve(TokenInterface(_token1), address(nftManager), _amount1);
}
/**
* @dev addLiquidityWrapper function wrapper of _addLiquidity
*/
function _addLiquidityWrapper(
uint256 tokenId,
uint256 amountA,
uint256 amountB,
uint256 slippage
)
internal
returns (
uint256 liquidity,
uint256 amtA,
uint256 amtB
)
{
(address token0, address token1) = getNftTokenPairAddresses(tokenId);
(liquidity, amtA, amtB) = _addLiquidity(
tokenId,
token0,
token1,
amountA,
amountB,
slippage
);
}
/**
* @dev addLiquidity function which interact with Uniswap v3
*/
function _addLiquidity(
uint256 _tokenId,
address _token0,
address _token1,
uint256 _amount0,
uint256 _amount1,
uint256 _slippage
)
internal
returns (
uint128 liquidity,
uint256 amount0,
uint256 amount1
)
{
_checkETH(_token0, _token1, _amount0, _amount1);
uint256 _amount0Min = getMinAmount(
TokenInterface(_token0),
_amount0,
_slippage
);
uint256 _amount1Min = getMinAmount(
TokenInterface(_token1),
_amount1,
_slippage
);
INonfungiblePositionManager.IncreaseLiquidityParams
memory params = INonfungiblePositionManager.IncreaseLiquidityParams(
_tokenId,
_amount0,
_amount1,
_amount0Min,
_amount1Min,
block.timestamp
);
(liquidity, amount0, amount1) = nftManager.increaseLiquidity(params);
}
/**
* @dev decreaseLiquidity function which interact with Uniswap v3
*/
function _decreaseLiquidity(
uint256 _tokenId,
uint128 _liquidity,
uint256 _amount0Min,
uint256 _amount1Min
) internal returns (uint256 amount0, uint256 amount1) {
INonfungiblePositionManager.DecreaseLiquidityParams
memory params = INonfungiblePositionManager.DecreaseLiquidityParams(
_tokenId,
_liquidity,
_amount0Min,
_amount1Min,
block.timestamp
);
(amount0, amount1) = nftManager.decreaseLiquidity(params);
}
/**
* @dev collect function which interact with Uniswap v3
*/
function _collect(
uint256 _tokenId,
uint128 _amount0Max,
uint128 _amount1Max
) internal returns (uint256 amount0, uint256 amount1) {
INonfungiblePositionManager.CollectParams
memory params = INonfungiblePositionManager.CollectParams(
_tokenId,
address(this),
_amount0Max,
_amount1Max
);
(amount0, amount1) = nftManager.collect(params);
}
/**
* @dev Burn Function
*/
function _burn(uint256 _tokenId) internal {
nftManager.burn(_tokenId);
}
}

View File

@ -0,0 +1,420 @@
// 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;
}

View File

@ -0,0 +1,211 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.7.6;
pragma abicoder v2;
/**
* @title Uniswap v3.
* @dev Decentralized Exchange.
*/
import {TokenInterface} from "../../../common/interfaces.sol";
import {Helpers} from "./helpers.sol";
import {Events} from "./events.sol";
abstract contract UniswapResolver is Helpers, Events {
/**
* @dev Mint New Position
* @notice Mint New NFT LP Position
* @param tokenA tokenA addreess
* @param tokenB tokenB addreess
* @param fee fee percentage
* @param tickLower Lower tick
* @param tickUpper Upper tick
* @param amtA amount of tokenA
* @param amtB amount of tokenB
* @param slippage slippage percentage
* @param getIds ID to retrieve amtA
* @param setId ID stores the amount of LP token
*/
function mint(
address tokenA,
address tokenB,
uint24 fee,
int24 tickLower,
int24 tickUpper,
uint256 amtA,
uint256 amtB,
uint256 slippage,
uint256[] calldata getIds,
uint256 setId
)
external
payable
returns (string memory _eventName, bytes memory _eventParam)
{
MintParams memory params;
{
params = MintParams(
tokenA,
tokenB,
fee,
tickLower,
tickUpper,
amtA,
amtB,
slippage
);
}
params.amtA = getUint(getIds[0], params.amtA);
params.amtB = getUint(getIds[1], params.amtB);
(
uint256 _tokenId,
uint256 liquidity,
uint256 amountA,
uint256 amountB
) = _mint(params);
setUint(setId, liquidity);
_eventName = "LogMint(uint256,uint256,uint256,uint256,int24,int24)";
_eventParam = abi.encode(
_tokenId,
liquidity,
amountA,
amountB,
params.tickLower,
params.tickUpper
);
}
/**
* @dev Increase Liquidity
* @notice Increase Liquidity of NFT Position
* @param tokenId NFT LP Token ID.
* @param amountA tokenA amounts.
* @param amountB tokenB amounts.
* @param slippage slippage.
* @param getIds IDs to retrieve token amounts
* @param setId stores the liquidity amount
*/
function deposit(
uint256 tokenId,
uint256 amountA,
uint256 amountB,
uint256 slippage,
uint256[] calldata getIds,
uint256 setId
)
external
payable
returns (string memory _eventName, bytes memory _eventParam)
{
if (tokenId == 0) tokenId = _getLastNftId(address(this));
amountA = getUint(getIds[0], amountA);
amountB = getUint(getIds[1], amountB);
(
uint256 _liquidity,
uint256 _amtA,
uint256 _amtB
) = _addLiquidityWrapper(tokenId, amountA, amountB, slippage);
setUint(setId, _liquidity);
_eventName = "LogDeposit(uint256,uint256,uint256,uint256)";
_eventParam = abi.encode(tokenId, _liquidity, _amtA, _amtB);
}
/**
* @dev Decrease Liquidity
* @notice Decrease Liquidity of NFT Position
* @param tokenId NFT LP Token ID.
* @param liquidity LP Token amount.
* @param amountAMin Min amount of tokenA.
* @param amountBMin Min amount of tokenB.
* @param getId ID to retrieve LP token amounts
* @param setIds stores the amount of output tokens
*/
function withdraw(
uint256 tokenId,
uint256 liquidity,
uint256 amountAMin,
uint256 amountBMin,
uint256 getId,
uint256[] calldata setIds
)
external
payable
returns (string memory _eventName, bytes memory _eventParam)
{
if (tokenId == 0) tokenId = _getLastNftId(address(this));
uint128 _liquidity = uint128(getUint(getId, liquidity));
(uint256 _amtA, uint256 _amtB) = _decreaseLiquidity(
tokenId,
_liquidity,
amountAMin,
amountBMin
);
setUint(setIds[0], _amtA);
setUint(setIds[1], _amtB);
_eventName = "LogWithdraw(uint256,uint256,uint256,uint256)";
_eventParam = abi.encode(tokenId, _liquidity, _amtA, _amtB);
}
/**
* @dev Collect function
* @notice Collect from NFT Position
* @param tokenId NFT LP Token ID.
* @param amount0Max Max amount of token0.
* @param amount1Max Max amount of token1.
* @param getIds IDs to retrieve amounts
* @param setIds stores the amount of output tokens
*/
function collect(
uint256 tokenId,
uint256 amount0Max,
uint256 amount1Max,
uint256[] calldata getIds,
uint256[] calldata setIds
)
external
payable
returns (string memory _eventName, bytes memory _eventParam)
{
if (tokenId == 0) tokenId = _getLastNftId(address(this));
uint128 _amount0Max = uint128(getUint(getIds[0], amount0Max));
uint128 _amount1Max = uint128(getUint(getIds[1], amount1Max));
(uint256 amount0, uint256 amount1) = _collect(
tokenId,
_amount0Max,
_amount1Max
);
setUint(setIds[0], amount0);
setUint(setIds[1], amount1);
_eventName = "LogCollect(uint256,uint256,uint256)";
_eventParam = abi.encode(tokenId, amount0, amount1);
}
/**
* @dev Burn Function
* @notice Burn NFT LP Position
* @param tokenId NFT LP Token ID
*/
function burn(uint256 tokenId)
external
payable
returns (string memory _eventName, bytes memory _eventParam)
{
if (tokenId == 0) tokenId = _getLastNftId(address(this));
_burn(tokenId);
_eventName = "LogBurnPosition(uint256)";
_eventParam = abi.encode(tokenId);
}
}
contract ConnectV2UniswapV3Optimism is UniswapResolver {
string public constant name = "UniswapV3-v1";
}