From 5a59c1d89cce0fae4b28a275717040da112533b5 Mon Sep 17 00:00:00 2001 From: tim Date: Tue, 29 Oct 2024 00:31:53 -0400 Subject: [PATCH] SwapOrder.inverted bugfixes --- src/core/OrderLib.sol | 9 +++++++-- src/core/UniswapSwapper.sol | 28 ++++++++++++++++------------ 2 files changed, 23 insertions(+), 14 deletions(-) diff --git a/src/core/OrderLib.sol b/src/core/OrderLib.sol index fe0cd7c..ee4375e 100644 --- a/src/core/OrderLib.sol +++ b/src/core/OrderLib.sol @@ -3,6 +3,7 @@ pragma solidity 0.8.26; import "@forge-std/console2.sol"; import {IUniswapV3Pool} from "@uniswap/v3-core/contracts/interfaces/IUniswapV3Pool.sol"; +import {FullMath} from "@uniswap/v3-core/contracts/libraries/FullMath.sol"; import {Util} from "./Util.sol"; import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; import {IEEE754, float} from "./IEEE754.sol"; @@ -239,11 +240,15 @@ library OrderLib { // console2.log('slippage'); uint256 protectedPrice = router.protectedPrice(order.route.exchange, order.tokenIn, order.tokenOut, order.route.fee, order.inverted); - // minIntercept is interpreted as the slippage ratio + // minLine.intercept is interpreted as the slippage ratio uint256 slippage = uint256(tranche.minLine.intercept.toFixed(96)); - v.limit = protectedPrice * 2**96 / (2**96+slippage); + bool buy = (order.tokenIn > order.tokenOut) != order.inverted; + v.limit = buy ? + FullMath.mulDiv( protectedPrice, 2**96+slippage, 2**96) : + FullMath.mulDiv( protectedPrice, 2**96, 2**96+slippage); // console2.log(protectedPrice); // console2.log(slippage); + // console2.log(buy); // console2.log(v.limit); } diff --git a/src/core/UniswapSwapper.sol b/src/core/UniswapSwapper.sol index 84c8856..c88c44f 100644 --- a/src/core/UniswapSwapper.sol +++ b/src/core/UniswapSwapper.sol @@ -70,9 +70,8 @@ contract UniswapV3Swapper { function _univ3_swap(IRouter.SwapParams memory params) internal returns (uint256 amountIn, uint256 amountOut) { if( params.limitPriceX96 != 0 ) { - // convert to output/input which is what the _univ3_* methods expect - bool inputInverted = params.tokenIn > params.tokenOut; - if (params.inverted!=inputInverted) { + // convert to the standard tokenOut/tokenIn which is what the _univ3_* methods expect + if (params.inverted) { // console2.log('inverting params.limitPriceX96'); // console2.log(params.limitPriceX96); params.limitPriceX96 = Util.invertX96(params.limitPriceX96); @@ -111,13 +110,13 @@ contract UniswapV3Swapper { // console2.log(address(swapRouter)); amountIn = params.amount; - uint256 balance = IERC20(params.tokenIn).balanceOf(address(this)); + uint256 startingBalanceIn = IERC20(params.tokenIn).balanceOf(address(this)); // console2.log('amountIn balance'); // console2.log(balance); - if( balance == 0 || balance < params.minAmount ) // minAmount is units of input token + if( startingBalanceIn == 0 || startingBalanceIn < params.minAmount ) // minAmount is units of input token revert('IIA'); - if( balance < amountIn ) - amountIn = balance; + if( startingBalanceIn < amountIn ) + amountIn = startingBalanceIn; TransferHelper.safeApprove(params.tokenIn, address(swapRouter), amountIn); // if (params.sqrtPriceLimitX96 == 0) @@ -132,6 +131,8 @@ contract UniswapV3Swapper { tokenIn: params.tokenIn, tokenOut: params.tokenOut, fee: params.maxFee, recipient: params.recipient, deadline: block.timestamp, amountIn: amountIn, amountOutMinimum: 1, sqrtPriceLimitX96: sqrtPriceLimitX96 })); + uint256 endingBalanceIn = IERC20(params.tokenIn).balanceOf(address(this)); + amountIn = startingBalanceIn - endingBalanceIn; // console2.log('swapped'); // console2.log(amountOut); TransferHelper.safeApprove(params.tokenIn, address(swapRouter), 0); @@ -151,10 +152,11 @@ contract UniswapV3Swapper { // uint256 amountInMaximum; // uint160 sqrtPriceLimitX96; // } - uint256 balance = IERC20(params.tokenIn).balanceOf(address(this)); - if( balance == 0 ) + uint256 startingBalanceIn = IERC20(params.tokenIn).balanceOf(address(this)); + if( startingBalanceIn == 0 ) revert('IIA'); - uint256 maxAmountIn = balance; + uint256 maxAmountIn = startingBalanceIn; + uint256 startingBalanceOut = IERC20(params.tokenOut).balanceOf(address(this)); // console2.log('swapExactOutput'); // console2.log(address(this)); @@ -181,7 +183,8 @@ contract UniswapV3Swapper { sqrtPriceLimitX96: sqrtPriceLimitX96 })) returns (uint256 amtIn) { amountIn = amtIn; - amountOut = params.amount; + uint256 endingBalanceOut = IERC20(params.tokenOut).balanceOf(address(this)); + amountOut = endingBalanceOut - startingBalanceOut; } catch Error( string memory reason ) { // todo check reason before trying exactinput @@ -190,7 +193,8 @@ contract UniswapV3Swapper { tokenIn: params.tokenIn, tokenOut: params.tokenOut, fee: params.maxFee, recipient: params.recipient, deadline: block.timestamp, amountIn: maxAmountIn, amountOutMinimum: 1, sqrtPriceLimitX96: sqrtPriceLimitX96 })) returns (uint256 amtOut) { - amountIn = maxAmountIn; + uint256 endingBalanceIn = IERC20(params.tokenIn).balanceOf(address(this)); + amountIn = startingBalanceIn - endingBalanceIn; amountOut = amtOut; } catch Error( string memory ) {