mirror of
https://github.com/Instadapp/dsa-connectors.git
synced 2024-07-29 22:37:00 +00:00
Update swapExactTokensForTokens function
This commit is contained in:
parent
da2eaaba0f
commit
260e0799ee
|
@ -1,34 +1,7 @@
|
|||
pragma solidity ^0.7.0;
|
||||
|
||||
contract Events {
|
||||
event LogMint(
|
||||
uint256 indexed tokenId,
|
||||
uint256 liquidity,
|
||||
uint256 amtA,
|
||||
uint256 amtB,
|
||||
int24 tickLower,
|
||||
int24 tickUpper
|
||||
event LogSwapExactTokensForTokens(
|
||||
uint256 amountOut
|
||||
);
|
||||
|
||||
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);
|
||||
}
|
||||
|
|
|
@ -16,8 +16,17 @@ abstract contract Helpers is DSMath, Basic {
|
|||
*/
|
||||
INonfungiblePositionManager constant nftManager =
|
||||
INonfungiblePositionManager(0xC36442b4a4522E871399CD717aBDD847Ab11FE88);
|
||||
ISwapRouter constant swapRouter =
|
||||
ISwapRouter internal constant swapRouter =
|
||||
ISwapRouter(0xE592427A0AEce92De3Edee1F18E0157C05861564);
|
||||
bytes32 internal constant POOL_INIT_CODE_HASH =
|
||||
0xe34f199b19b2b4f47f68442619d555527d244f78a3297ea89325f843f87b8b54;
|
||||
|
||||
address constant COMMON_ADDRESSES = [
|
||||
0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2, // WETH
|
||||
0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48, // USDC
|
||||
0xdAC17F958D2ee523a2206206994597C13D831ec7, // USDT
|
||||
0x6b175474e89094c44da98b954eedeac495271d0f, // DAI
|
||||
]
|
||||
|
||||
struct MintParams {
|
||||
address tokenA;
|
||||
|
@ -43,6 +52,85 @@ abstract contract Helpers is DSMath, Basic {
|
|||
tokenId = nftManager.tokenOfOwnerByIndex(user, len - 1);
|
||||
}
|
||||
|
||||
function getPrice(address tokenIn, address tokenOut, uint24 fee)
|
||||
external
|
||||
view
|
||||
returns (uint256 price)
|
||||
{
|
||||
IUniswapV3Pool pool = IUniswapV3Pool(factory.getPool(tokenIn, tokenOut, fee);
|
||||
(uint160 sqrtPriceX96,,,,,,) = pool.slot0();
|
||||
return uint(sqrtPriceX96).mul(uint(sqrtPriceX96)).mul(1e18) >> (96 * 2);
|
||||
}
|
||||
|
||||
function getPoolAddress(
|
||||
address tokenA,
|
||||
address tokenB,
|
||||
uint24 fee
|
||||
) internal pure returns (address pool) {
|
||||
if (tokenA > tokenB) (tokenA, tokenB) = (tokenB, tokenA);
|
||||
return
|
||||
computeAddress(
|
||||
0x1F98431c8aD98523631AE4a59f267346ea31F984,
|
||||
PoolKey({token0: tokenA, token1: tokenB, fee: fee})
|
||||
);
|
||||
}
|
||||
|
||||
function computeAddress(address factory, PoolKey memory key)
|
||||
internal
|
||||
pure
|
||||
returns (address pool)
|
||||
{
|
||||
require(key.token0 < key.token1);
|
||||
pool = address(
|
||||
uint160(
|
||||
uint256(
|
||||
keccak256(
|
||||
abi.encodePacked(
|
||||
hex"ff",
|
||||
factory,
|
||||
keccak256(
|
||||
abi.encode(key.token0, key.token1, key.fee)
|
||||
),
|
||||
POOL_INIT_CODE_HASH
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
);
|
||||
}
|
||||
function getParams(
|
||||
address tokenIn,
|
||||
address tokenOut,
|
||||
address recipient,
|
||||
uint24 fee,
|
||||
uint256 amountIn,
|
||||
uint256 amountOutMinimum
|
||||
) internal view returns (ISwapRouter.ExactInputSingleParams memory params) {
|
||||
params = ISwapRouter.ExactInputSingleParams({
|
||||
tokenIn: tokenIn,
|
||||
tokenOut: tokenOut,
|
||||
fee: fee,
|
||||
recipient: recipient,
|
||||
deadline: block.timestamp + 1,
|
||||
amountIn: amountIn,
|
||||
amountOutMinimum: amountOutMinimum,
|
||||
sqrtPriceLimitX96: getPriceLimit(
|
||||
amountIn,
|
||||
tokenIn < tokenOut,
|
||||
tokenIn,
|
||||
tokenOut,
|
||||
fee
|
||||
)
|
||||
});
|
||||
}
|
||||
|
||||
function swapSingleInput(ISwapRouter.ExactInputSingleParams memory params)
|
||||
internal
|
||||
returns (uint256)
|
||||
{
|
||||
return (uint256(swapRouter.exactInputSingle(params)));
|
||||
}
|
||||
|
||||
function getMinAmount(
|
||||
TokenInterface token,
|
||||
uint256 amt,
|
||||
|
|
|
@ -12,33 +12,65 @@ import {Events} from "./events.sol";
|
|||
|
||||
abstract contract UniswapResolver is Helpers, Events {
|
||||
function swapExactTokensForTokens(
|
||||
uint amountIn,
|
||||
uint amountOutMin,
|
||||
bytes path,
|
||||
address to,
|
||||
uint deadline
|
||||
) external virtual override ensure(deadline) returns (uint[] memory amounts) {
|
||||
amounts = UniswapV2Library.getAmountsOut(factory, amountIn, path);
|
||||
require(amounts[amounts.length - 1] >= amountOutMin, 'UniswapV2Router: INSUFFICIENT_OUTPUT_AMOUNT');
|
||||
TransferHelper.safeTransferFrom(
|
||||
path[0], msg.sender, UniswapV2Library.pairFor(factory, path[0], path[1]), amounts[0]
|
||||
);
|
||||
_swap(amounts, path, to);
|
||||
}
|
||||
address tokenIn,
|
||||
address tokenOut,
|
||||
address recipient,
|
||||
uint256 deadline,
|
||||
uint24 fee,
|
||||
uint256 amountIn,
|
||||
uint256 amountOutMinimum
|
||||
)
|
||||
external
|
||||
payable
|
||||
returns (string memory _eventName, bytes memory _eventParam)
|
||||
{
|
||||
address poolAddr = getPoolAddress(tokenIn, tokenOut, fee);
|
||||
uint256 maxPrice = 0;
|
||||
uint pathIndex = 0;
|
||||
|
||||
function swapTokensForExactTokens(
|
||||
uint amountOut,
|
||||
uint amountInMax,
|
||||
bytes path,
|
||||
address to,
|
||||
uint deadline
|
||||
) external virtual override ensure(deadline) returns (uint[] memory amounts) {
|
||||
amounts = UniswapV2Library.getAmountsIn(factory, amountOut, path);
|
||||
require(amounts[0] <= amountInMax, 'UniswapV2Router: EXCESSIVE_INPUT_AMOUNT');
|
||||
TransferHelper.safeTransferFrom(
|
||||
path[0], msg.sender, UniswapV2Library.pairFor(factory, path[0], path[1]), amounts[0]
|
||||
for (uint i = 0; i < COMMON_ADDRESSES.length; i++) {
|
||||
uint256 price1 = getPrice(tokenIn, COMMON_ADDRESSES[i], fee);
|
||||
uint256 price2 = getPrice(COMMON_ADDRESSES[i], tokenOut, fee);
|
||||
uint256 price = (price1 + price2) / 2;
|
||||
|
||||
if (maxPrice < price) {
|
||||
maxPrice = price;
|
||||
pathIndex = i;
|
||||
}
|
||||
}
|
||||
|
||||
if (poolAddr != address(0)) {
|
||||
uint256 price = getPrice(tokenIn, tokenOut, fee);
|
||||
|
||||
if (maxPrice < price) {
|
||||
maxPrice = price;
|
||||
}
|
||||
}
|
||||
|
||||
IERC20(tokenIn).safeApprove(address(swapRouter), amountIn);
|
||||
uint256 amountOut1 = swapSingleInput(
|
||||
getParams(
|
||||
tokenIn,
|
||||
COMMON_ADDRESSES[pathIndex],
|
||||
recipient,
|
||||
fee,
|
||||
amountIn,
|
||||
amountOutMinimum
|
||||
)
|
||||
);
|
||||
_swap(amounts, path, to);
|
||||
uint256 amountOut = swapSingleInput(
|
||||
getParams(
|
||||
COMMON_ADDRESSES[pathIndex],
|
||||
tokenOut
|
||||
recipient,
|
||||
fee,
|
||||
amountOut1,
|
||||
amountOutMinimum
|
||||
)
|
||||
);
|
||||
|
||||
_eventName = "LogSwapExactTokensForTokens(uint256)";
|
||||
_eventParam = abi.encode(amountOut);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user