dsa-connectors/contracts/mainnet/connectors/uniswapV3/helpers.sol

266 lines
7.7 KiB
Solidity
Raw Normal View History

2021-08-10 14:54:21 +00:00
pragma solidity ^0.7.6;
2021-08-08 09:29:35 +00:00
pragma abicoder v2;
import {TokenInterface} from "../../common/interfaces.sol";
import {DSMath} from "../../common/math.sol";
import {Basic} from "../../common/basic.sol";
2021-08-10 14:54:21 +00:00
import "./interface.sol";
2021-08-08 09:29:35 +00:00
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
*/
2021-08-09 14:58:28 +00:00
INonfungiblePositionManager constant nftManager =
2021-08-08 09:29:35 +00:00
INonfungiblePositionManager(0xC36442b4a4522E871399CD717aBDD847Ab11FE88);
2021-08-09 14:58:28 +00:00
ISwapRouter constant swapRouter =
2021-08-08 09:29:35 +00:00
ISwapRouter(0xE592427A0AEce92De3Edee1F18E0157C05861564);
struct MintParams {
2021-08-09 20:08:48 +00:00
address tokenA;
address tokenB;
2021-08-08 09:29:35 +00:00
uint24 fee;
int24 tickLower;
int24 tickUpper;
2021-08-09 20:08:48 +00:00
uint256 amtA;
2021-08-10 14:54:21 +00:00
uint256 amtB;
2021-08-09 20:08:48 +00:00
uint256 slippage;
2021-08-09 18:30:38 +00:00
}
2021-08-12 22:12:11 +00:00
/**
* @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);
}
2021-08-09 18:30:38 +00:00
function getMinAmount(
TokenInterface token,
2021-08-09 20:08:48 +00:00
uint256 amt,
uint256 slippage
) internal view returns (uint256 minAmt) {
uint256 _amt18 = convertTo18(token.decimals(), amt);
2021-08-09 18:30:38 +00:00
minAmt = wmul(_amt18, sub(WAD, slippage));
minAmt = convert18ToDec(token.decimals(), minAmt);
2021-08-08 09:29:35 +00:00
}
/**
* @dev Mint function which interact with Uniswap v3
*/
function _mint(MintParams memory params)
internal
returns (
uint256 tokenId,
uint128 liquidity,
2021-08-12 22:12:11 +00:00
uint256 amountA,
uint256 amountB
2021-08-08 09:29:35 +00:00
)
{
2021-08-09 18:30:38 +00:00
(TokenInterface _token0, TokenInterface _token1) = changeEthAddress(
2021-08-09 20:08:48 +00:00
params.tokenA,
params.tokenB
2021-08-08 09:29:35 +00:00
);
2021-08-09 20:08:48 +00:00
uint256 _amount0 = params.amtA == uint256(-1)
? getTokenBal(TokenInterface(params.tokenA))
: params.amtA;
2021-08-10 16:42:18 +00:00
uint256 _amount1 = params.amtB == uint256(-1)
? getTokenBal(TokenInterface(params.tokenB))
2021-08-10 14:54:21 +00:00
: params.amtB;
2021-08-09 20:08:48 +00:00
2021-08-12 22:12:11 +00:00
convertEthToWeth(address(_token0) == wethAddr, _token0, _amount0);
convertEthToWeth(address(_token1) == wethAddr, _token1, _amount1);
2021-08-09 21:09:14 +00:00
2021-08-10 04:53:49 +00:00
approve(_token0, address(nftManager), _amount0);
approve(_token1, address(nftManager), _amount1);
2021-08-09 20:08:48 +00:00
uint256 _minAmt0 = getMinAmount(_token0, _amount0, params.slippage);
uint256 _minAmt1 = getMinAmount(_token1, _amount1, params.slippage);
2021-08-09 18:30:38 +00:00
2021-08-08 09:29:35 +00:00
INonfungiblePositionManager.MintParams
memory params = INonfungiblePositionManager.MintParams(
2021-08-10 04:53:49 +00:00
address(_token0),
address(_token1),
2021-08-08 09:29:35 +00:00
params.fee,
params.tickLower,
params.tickUpper,
_amount0,
_amount1,
2021-08-09 18:30:38 +00:00
_minAmt0,
_minAmt1,
2021-08-08 09:29:35 +00:00
address(this),
block.timestamp
);
2021-08-12 22:12:11 +00:00
(tokenId, liquidity, amountA, amountB) = nftManager.mint(params);
2021-08-08 09:29:35 +00:00
}
2021-08-20 20:10:38 +00:00
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
)
);
}
}
2021-08-10 15:18:33 +00:00
/**
* @dev Check if token address is etherAddr and convert it to weth
*/
2021-08-10 14:54:21 +00:00
function _checkETH(
address _token0,
address _token1,
2021-08-10 14:54:21 +00:00
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
)
{
2021-08-20 20:10:38 +00:00
(address token0, address token1) = getNftTokenPairAddresses(tokenId);
(liquidity, amtA, amtB) = _addLiquidity(
tokenId,
token0,
token1,
amountA,
amountB,
slippage
);
2021-08-10 14:54:21 +00:00
}
2021-08-08 09:29:35 +00:00
/**
* @dev addLiquidity function which interact with Uniswap v3
*/
function _addLiquidity(
uint256 _tokenId,
address _token0,
address _token1,
2021-08-10 14:54:21 +00:00
uint256 _amount0,
uint256 _amount1,
2021-08-12 22:12:11 +00:00
uint256 _slippage
2021-08-08 09:29:35 +00:00
)
internal
returns (
uint128 liquidity,
uint256 amount0,
uint256 amount1
)
{
_checkETH(_token0, _token1, _amount0, _amount1);
2021-08-12 22:12:11 +00:00
uint256 _amount0Min = getMinAmount(
TokenInterface(_token0),
_amount0,
_slippage
);
uint256 _amount1Min = getMinAmount(
TokenInterface(_token1),
_amount1,
_slippage
);
2021-08-08 09:29:35 +00:00
INonfungiblePositionManager.IncreaseLiquidityParams
memory params = INonfungiblePositionManager.IncreaseLiquidityParams(
_tokenId,
2021-08-10 14:54:21 +00:00
_amount0,
_amount1,
2021-08-09 14:58:28 +00:00
_amount0Min,
_amount1Min,
2021-08-08 09:29:35 +00:00
block.timestamp
);
2021-08-08 09:29:35 +00:00
(liquidity, amount0, amount1) = nftManager.increaseLiquidity(params);
}
/**
* @dev decreaseLiquidity function which interact with Uniswap v3
*/
function _decreaseLiquidity(
uint256 _tokenId,
2021-08-09 14:58:28 +00:00
uint128 _liquidity,
uint256 _amount0Min,
2021-08-09 20:08:48 +00:00
uint256 _amount1Min
2021-08-08 09:29:35 +00:00
) internal returns (uint256 amount0, uint256 amount1) {
INonfungiblePositionManager.DecreaseLiquidityParams
memory params = INonfungiblePositionManager.DecreaseLiquidityParams(
_tokenId,
_liquidity,
2021-08-09 14:58:28 +00:00
_amount0Min,
2021-08-09 20:08:48 +00:00
_amount1Min,
2021-08-08 09:29:35 +00:00
block.timestamp
);
(amount0, amount1) = nftManager.decreaseLiquidity(params);
}
/**
* @dev collect function which interact with Uniswap v3
*/
function _collect(
uint256 _tokenId,
2021-08-12 22:12:11 +00:00
uint128 _amount0Max,
uint128 _amount1Max
2021-08-08 09:29:35 +00:00
) internal returns (uint256 amount0, uint256 amount1) {
INonfungiblePositionManager.CollectParams
memory params = INonfungiblePositionManager.CollectParams(
_tokenId,
address(this),
2021-08-12 22:12:11 +00:00
_amount0Max,
_amount1Max
2021-08-08 09:29:35 +00:00
);
(amount0, amount1) = nftManager.collect(params);
}
2021-08-10 15:18:33 +00:00
/**
* @dev Burn Function
*/
function _burn(uint256 _tokenId) internal {
nftManager.burn(_tokenId);
}
2021-08-08 09:29:35 +00:00
}