dsa-connectors/contracts/mainnet/connectors/uniswap/v3_swap/helpers.sol
2022-05-02 01:57:10 +05:30

160 lines
4.5 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";
abstract contract Helpers is DSMath, Basic {
/**
* @dev uniswap v3 Swap Router
*/
ISwapRouter constant swapRouter =
ISwapRouter(0xE592427A0AEce92De3Edee1F18E0157C05861564);
struct BuyInfo {
address buyAddr; //token to be bought
address sellAddr; //token to be sold
uint24 fee; //pool fees for buyAddr-sellAddr token pair
uint256 unitAmt; //The unit amount of sellAmt/buyAmt with slippage
uint256 buyAmt; //amount of token to be bought
uint256 getId; //Id to get buyAmt
uint256 setId; //Id to store sellAmt
}
struct SellInfo {
address buyAddr; //token to be bought
address sellAddr; //token to be sold
uint24 fee; //pool fees for buyAddr-sellAddr token pair
uint256 unitAmt; //The unit amount of buyAmt/sellAmt with slippage.
uint256 sellAmt; //amount of token to be bought
uint256 getId; //Id to get buyAmt
uint256 setId; //Id to store sellAmt
}
/**
* @dev Buy Function
* @notice Swap token(sellAddr) with token(buyAddr), buy token with minimum sell token
* @param buyData Data input for the buy action
*/
function _buy(
BuyInfo memory buyData
)
internal
payable
returns (string memory _eventName, bytes memory _eventParam)
{
uint256 _buyAmt = getUint(buyData.getId, buyData.buyAmt);
ISwapRouter.ExactOutputSingleParams memory params;
(TokenInterface _buyAddr, TokenInterface _sellAddr) = changeEthAddress(
buyData.buyAddr,
buyData.sellAddr
);
uint _slippageAmt = convert18ToDec(_sellAddr.decimals(),
wmul(buyData.unitAmt, convertTo18(_buyAddr.decimals(), _buyAmt))
);
bool isEth = address(_sellAddr) == wethAddr;
convertEthToWeth(isEth, _sellAddr, _slippageAmt);
approve(_sellAddr, address(swapRouter), _slippageAmt);
{
params = ISwapRouter.ExactOutputSingleParams({
tokenIn: buyData.sellAddr,
tokenOut: buyData.buyAddr,
fee: buyData.fee,
recipient: address(this),
deadline: block.timestamp + 1,
amountOut: _buyAmt,
amountInMaximum: _slippageAmt, //require(_sellAmt <= amountInMaximum)
sqrtPriceLimitX96: 0
});
}
uint256 _sellAmt = swapRouter.exactOutputSingle(params);
require(_slippageAmt >= _sellAmt, "Too much slippage");
isEth = address(_buyAddr) == wethAddr;
convertWethToEth(isEth, _buyAddr, _buyAmt);
setUint(buyData.setId, _sellAmt);
_eventName = "LogBuy(address,address,uint256,uint256,uint256,uint256)";
_eventParam = abi.encode(
buyData.buyAddr,
buyData.sellAddr,
_buyAmt,
_sellAmt,
buyData.getId,
buyData.setId
);
}
/**
* @dev Sell Function
* @notice Swap token(sellAddr) with token(buyAddr), to get max buy tokens
* @param sellData Data input for the sell action
*/
function _sell(
SellInfo memory sellData
)
internal
payable
returns (string memory _eventName, bytes memory _eventParam)
{
uint256 _sellAmt = getUint(sellData.getId, sellData.sellAmt);
(TokenInterface _buyAddr, TokenInterface _sellAddr) = changeEthAddress(
sellData.buyAddr,
sellData.sellAddr
);
if (_sellAmt == uint(-1)) {
_sellAmt = sellData.sellAddr == ethAddr
? address(this).balance
: _sellAddr.balanceOf(address(this));
}
uint _slippageAmt = convert18ToDec(_buyAddr.decimals(),
wmul(sellData.unitAmt, convertTo18(_sellAddr.decimals(), _sellAmt))
);
bool isEth = address(_sellAddr) == wethAddr;
convertEthToWeth(isEth, _sellAddr, _sellAmt);
approve(_sellAddr, address(swapRouter), _sellAmt);
ISwapRouter.ExactInputSingleParams memory params;
{
params = ISwapRouter.ExactInputSingleParams({
tokenIn: sellData.sellAddr,
tokenOut: sellData.buyAddr,
fee: sellData.fee,
recipient: address(this),
deadline: block.timestamp + 1,
amountIn: _sellAmt,
amountOutMinimum: _slippageAmt, //require(_buyAmt >= amountOutMinimum)
sqrtPriceLimitX96: 0
});
}
uint256 _buyAmt = swapRouter.exactInputSingle(params);
require(_slippageAmt <= _buyAmt, "Too much slippage");
isEth = address(_buyAddr) == wethAddr;
convertWethToEth(isEth, _buyAddr, _buyAmt);
setUint(sellData.setId, _buyAmt);
_eventName = "LogSell(address,address,uint256,uint256,uint256,uint256)";
_eventParam = abi.encode(
sellData.buyAddr,
sellData.sellAddr,
_buyAmt,
_sellAmt,
sellData.getId,
sellData.setId
);
}
}