mirror of
https://github.com/Instadapp/dsa-connectors.git
synced 2024-07-29 22:37:00 +00:00
265 lines
7.6 KiB
Solidity
265 lines
7.6 KiB
Solidity
//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);
|
|
|
|
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);
|
|
}
|
|
|
|
/**
|
|
* @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);
|
|
|
|
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);
|
|
}
|
|
}
|