Update swapExactTokensForTokens function

This commit is contained in:
cryptoDev222 2021-12-13 16:19:07 -06:00
parent da2eaaba0f
commit 260e0799ee
3 changed files with 148 additions and 55 deletions

View File

@ -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);
}

View File

@ -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,

View File

@ -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);
}
}