From 1e9971d546803c090ae89e32a743522ad485216d Mon Sep 17 00:00:00 2001 From: Shuhui Luo Date: Wed, 21 Jun 2023 12:48:54 -0700 Subject: [PATCH 01/16] Refactor and optimize `SwapMath` --- .forge-snapshots/simple swap.snap | 2 +- ...p against liquidity with native token.snap | 2 +- .forge-snapshots/swap against liquidity.snap | 2 +- .forge-snapshots/swap with hooks.snap | 2 +- .forge-snapshots/swap with native.snap | 2 +- contracts/libraries/Pool.sol | 6 +- contracts/libraries/SwapMath.sol | 95 +++++++++++-------- test/SwapMath.spec.ts | 3 +- .../PoolManager.gas.spec.ts.snap | 36 +++---- test/__snapshots__/PoolManager.spec.ts.snap | 2 +- test/__snapshots__/SwapMath.spec.ts.snap | 16 ++-- 11 files changed, 90 insertions(+), 78 deletions(-) diff --git a/.forge-snapshots/simple swap.snap b/.forge-snapshots/simple swap.snap index 9d37b2d38..18790af05 100644 --- a/.forge-snapshots/simple swap.snap +++ b/.forge-snapshots/simple swap.snap @@ -1 +1 @@ -67737 \ No newline at end of file +67435 \ No newline at end of file diff --git a/.forge-snapshots/swap against liquidity with native token.snap b/.forge-snapshots/swap against liquidity with native token.snap index 0bdc58141..980447cc1 100644 --- a/.forge-snapshots/swap against liquidity with native token.snap +++ b/.forge-snapshots/swap against liquidity with native token.snap @@ -1 +1 @@ -161615 \ No newline at end of file +160694 \ No newline at end of file diff --git a/.forge-snapshots/swap against liquidity.snap b/.forge-snapshots/swap against liquidity.snap index 53e4507aa..a3e330e75 100644 --- a/.forge-snapshots/swap against liquidity.snap +++ b/.forge-snapshots/swap against liquidity.snap @@ -1 +1 @@ -146322 \ No newline at end of file +145401 \ No newline at end of file diff --git a/.forge-snapshots/swap with hooks.snap b/.forge-snapshots/swap with hooks.snap index 72cc7577c..c6d7340eb 100644 --- a/.forge-snapshots/swap with hooks.snap +++ b/.forge-snapshots/swap with hooks.snap @@ -1 +1 @@ -67712 \ No newline at end of file +67410 \ No newline at end of file diff --git a/.forge-snapshots/swap with native.snap b/.forge-snapshots/swap with native.snap index 9d37b2d38..18790af05 100644 --- a/.forge-snapshots/swap with native.snap +++ b/.forge-snapshots/swap with native.snap @@ -1 +1 @@ -67737 \ No newline at end of file +67435 \ No newline at end of file diff --git a/contracts/libraries/Pool.sol b/contracts/libraries/Pool.sol index 6fd07c1fe..141ab7144 100644 --- a/contracts/libraries/Pool.sol +++ b/contracts/libraries/Pool.sol @@ -432,11 +432,7 @@ library Pool { // compute values to swap to the target tick, price limit, or point where input/output amount is exhausted (state.sqrtPriceX96, step.amountIn, step.amountOut, step.feeAmount) = SwapMath.computeSwapStep( state.sqrtPriceX96, - ( - params.zeroForOne - ? step.sqrtPriceNextX96 < params.sqrtPriceLimitX96 - : step.sqrtPriceNextX96 > params.sqrtPriceLimitX96 - ) ? params.sqrtPriceLimitX96 : step.sqrtPriceNextX96, + SwapMath.getSqrtRatioTarget(params.zeroForOne, step.sqrtPriceNextX96, params.sqrtPriceLimitX96), state.liquidity, state.amountSpecifiedRemaining, params.fee diff --git a/contracts/libraries/SwapMath.sol b/contracts/libraries/SwapMath.sol index 4ca5ab2be..870771ebd 100644 --- a/contracts/libraries/SwapMath.sol +++ b/contracts/libraries/SwapMath.sol @@ -7,6 +7,31 @@ import {SqrtPriceMath} from "./SqrtPriceMath.sol"; /// @title Computes the result of a swap within ticks /// @notice Contains methods for computing the result of a swap within a single tick price range, i.e., a single tick. library SwapMath { + uint24 internal constant MAX_FEE_PIPS = 1e6; + + /// @notice Computes the sqrt price target for the next swap step + /// @param zeroForOne The direction of the swap, true for token0 to token1, false for token1 to token0 + /// @param sqrtPriceNextX96 The Q64.96 sqrt price for the next initialized tick + /// @param sqrtPriceLimitX96 The Q64.96 sqrt price limit. If zero for one, the price cannot be less than this + /// value after the swap. If one for zero, the price cannot be greater than this value after the swap + /// @return sqrtRatioTargetX96 The price target for the next swap step + function getSqrtRatioTarget(bool zeroForOne, uint160 sqrtPriceNextX96, uint160 sqrtPriceLimitX96) + internal + pure + returns (uint160 sqrtRatioTargetX96) + { + assembly { + // a flag to toggle between sqrtPriceNextX96 and sqrtPriceLimitX96 + // when zeroForOne == true, nextOrLimit reduces to sqrtPriceNextX96 > sqrtPriceLimitX96 + // sqrtRatioTargetX96 = max(sqrtPriceNextX96, sqrtPriceLimitX96) + // when zeroForOne == false, nextOrLimit reduces to sqrtPriceNextX96 <= sqrtPriceLimitX96 + // sqrtRatioTargetX96 = min(sqrtPriceNextX96, sqrtPriceLimitX96) + let nextOrLimit := xor(gt(sqrtPriceNextX96, sqrtPriceLimitX96), iszero(zeroForOne)) + let symDiff := xor(sqrtPriceNextX96, sqrtPriceLimitX96) + sqrtRatioTargetX96 := xor(sqrtPriceLimitX96, mul(symDiff, nextOrLimit)) + } + } + /// @notice Computes the result of swapping some amount in, or amount out, given the parameters of the swap /// @dev The fee, plus the amount in, will never exceed the amount remaining if the swap's `amountSpecified` is positive /// @param sqrtRatioCurrentX96 The current sqrt price of the pool @@ -27,62 +52,54 @@ library SwapMath { ) internal pure returns (uint160 sqrtRatioNextX96, uint256 amountIn, uint256 amountOut, uint256 feeAmount) { unchecked { bool zeroForOne = sqrtRatioCurrentX96 >= sqrtRatioTargetX96; - bool exactIn = amountRemaining >= 0; + uint256 feeComplement = MAX_FEE_PIPS - feePips; + bool exactIn; + uint256 amountRemainingAbs; + assembly { + // exactIn = 1 if amountRemaining >= 0 else 0 + exactIn := iszero(slt(amountRemaining, 0)) + // mask = 0 if amountRemaining >= 0 else -1 + let mask := sub(exactIn, 1) + amountRemainingAbs := xor(mask, add(mask, amountRemaining)) + } if (exactIn) { - uint256 amountRemainingLessFee = FullMath.mulDiv(uint256(amountRemaining), 1e6 - feePips, 1e6); + uint256 amountRemainingLessFee = FullMath.mulDiv(amountRemainingAbs, feeComplement, MAX_FEE_PIPS); amountIn = zeroForOne ? SqrtPriceMath.getAmount0Delta(sqrtRatioTargetX96, sqrtRatioCurrentX96, liquidity, true) : SqrtPriceMath.getAmount1Delta(sqrtRatioCurrentX96, sqrtRatioTargetX96, liquidity, true); if (amountRemainingLessFee >= amountIn) { + // `amountIn` is capped by the target price sqrtRatioNextX96 = sqrtRatioTargetX96; + feeAmount = FullMath.mulDivRoundingUp(amountIn, feePips, feeComplement); } else { - sqrtRatioNextX96 = SqrtPriceMath.getNextSqrtPriceFromInput( - sqrtRatioCurrentX96, liquidity, amountRemainingLessFee, zeroForOne - ); + // exhaust the remaining amount + amountIn = amountRemainingLessFee; + sqrtRatioNextX96 = + SqrtPriceMath.getNextSqrtPriceFromInput(sqrtRatioCurrentX96, liquidity, amountIn, zeroForOne); + // we didn't reach the target, so take the remainder of the maximum input as fee + feeAmount = amountRemainingAbs - amountIn; } + amountOut = zeroForOne + ? SqrtPriceMath.getAmount1Delta(sqrtRatioNextX96, sqrtRatioCurrentX96, liquidity, false) + : SqrtPriceMath.getAmount0Delta(sqrtRatioCurrentX96, sqrtRatioNextX96, liquidity, false); } else { amountOut = zeroForOne ? SqrtPriceMath.getAmount1Delta(sqrtRatioTargetX96, sqrtRatioCurrentX96, liquidity, false) : SqrtPriceMath.getAmount0Delta(sqrtRatioCurrentX96, sqrtRatioTargetX96, liquidity, false); - if (uint256(-amountRemaining) >= amountOut) { + if (amountRemainingAbs >= amountOut) { + // `amountOut` is capped by the target price sqrtRatioNextX96 = sqrtRatioTargetX96; } else { - sqrtRatioNextX96 = SqrtPriceMath.getNextSqrtPriceFromOutput( - sqrtRatioCurrentX96, liquidity, uint256(-amountRemaining), zeroForOne - ); + // cap the output amount to not exceed the remaining output amount + amountOut = amountRemainingAbs; + sqrtRatioNextX96 = + SqrtPriceMath.getNextSqrtPriceFromOutput(sqrtRatioCurrentX96, liquidity, amountOut, zeroForOne); } - } - - bool max = sqrtRatioTargetX96 == sqrtRatioNextX96; - - // get the input/output amounts - if (zeroForOne) { - amountIn = max && exactIn - ? amountIn - : SqrtPriceMath.getAmount0Delta(sqrtRatioNextX96, sqrtRatioCurrentX96, liquidity, true); - amountOut = max && !exactIn - ? amountOut - : SqrtPriceMath.getAmount1Delta(sqrtRatioNextX96, sqrtRatioCurrentX96, liquidity, false); - } else { - amountIn = max && exactIn - ? amountIn + amountIn = zeroForOne + ? SqrtPriceMath.getAmount0Delta(sqrtRatioNextX96, sqrtRatioCurrentX96, liquidity, true) : SqrtPriceMath.getAmount1Delta(sqrtRatioCurrentX96, sqrtRatioNextX96, liquidity, true); - amountOut = max && !exactIn - ? amountOut - : SqrtPriceMath.getAmount0Delta(sqrtRatioCurrentX96, sqrtRatioNextX96, liquidity, false); - } - - // cap the output amount to not exceed the remaining output amount - if (!exactIn && amountOut > uint256(-amountRemaining)) { - amountOut = uint256(-amountRemaining); - } - - if (exactIn && sqrtRatioNextX96 != sqrtRatioTargetX96) { - // we didn't reach the target, so take the remainder of the maximum input as fee - feeAmount = uint256(amountRemaining) - amountIn; - } else { - feeAmount = FullMath.mulDivRoundingUp(amountIn, feePips, 1e6 - feePips); + feeAmount = FullMath.mulDivRoundingUp(amountIn, feePips, feeComplement); } } } diff --git a/test/SwapMath.spec.ts b/test/SwapMath.spec.ts index 7eac64de6..b47de02d4 100644 --- a/test/SwapMath.spec.ts +++ b/test/SwapMath.spec.ts @@ -182,8 +182,7 @@ describe('SwapMath', () => { '10', 1872 ) - expect(amountIn).to.eq('0') - expect(feeAmount).to.eq('10') + expect(amountIn.add(feeAmount)).to.eq('10') expect(amountOut).to.eq('0') expect(sqrtQ).to.eq('2413') }) diff --git a/test/__snapshots__/PoolManager.gas.spec.ts.snap b/test/__snapshots__/PoolManager.gas.spec.ts.snap index a879255ff..8e642058a 100644 --- a/test/__snapshots__/PoolManager.gas.spec.ts.snap +++ b/test/__snapshots__/PoolManager.gas.spec.ts.snap @@ -73,63 +73,63 @@ Object { exports[`PoolManager gas tests ERC20 tokens #swapExact0For1 first swap in block moves tick, no initialized crossings 1`] = ` Object { "calldataByteLength": 324, - "gasUsed": 192286, + "gasUsed": 191324, } `; exports[`PoolManager gas tests ERC20 tokens #swapExact0For1 first swap in block with no tick movement 1`] = ` Object { "calldataByteLength": 324, - "gasUsed": 186516, + "gasUsed": 185780, } `; exports[`PoolManager gas tests ERC20 tokens #swapExact0For1 first swap in block, large swap crossing a single initialized tick 1`] = ` Object { "calldataByteLength": 324, - "gasUsed": 211110, + "gasUsed": 209874, } `; exports[`PoolManager gas tests ERC20 tokens #swapExact0For1 first swap in block, large swap crossing several initialized ticks 1`] = ` Object { "calldataByteLength": 324, - "gasUsed": 252792, + "gasUsed": 250808, } `; exports[`PoolManager gas tests ERC20 tokens #swapExact0For1 first swap in block, large swap, no initialized crossings 1`] = ` Object { "calldataByteLength": 324, - "gasUsed": 204023, + "gasUsed": 202537, } `; exports[`PoolManager gas tests ERC20 tokens #swapExact0For1 second swap in block moves tick, no initialized crossings 1`] = ` Object { "calldataByteLength": 324, - "gasUsed": 192286, + "gasUsed": 191324, } `; exports[`PoolManager gas tests ERC20 tokens #swapExact0For1 second swap in block with no tick movement 1`] = ` Object { "calldataByteLength": 324, - "gasUsed": 186605, + "gasUsed": 185868, } `; exports[`PoolManager gas tests ERC20 tokens #swapExact0For1 second swap in block, large swap crossing a single initialized tick 1`] = ` Object { "calldataByteLength": 324, - "gasUsed": 205457, + "gasUsed": 204471, } `; exports[`PoolManager gas tests ERC20 tokens #swapExact0For1 second swap in block, large swap crossing several initialized ticks 1`] = ` Object { "calldataByteLength": 324, - "gasUsed": 247115, + "gasUsed": 245380, } `; @@ -199,62 +199,62 @@ Object { exports[`PoolManager gas tests Native Tokens #swapExact0For1 first swap in block moves tick, no initialized crossings 1`] = ` Object { "calldataByteLength": 324, - "gasUsed": 179641, + "gasUsed": 178680, } `; exports[`PoolManager gas tests Native Tokens #swapExact0For1 first swap in block with no tick movement 1`] = ` Object { "calldataByteLength": 324, - "gasUsed": 173872, + "gasUsed": 173135, } `; exports[`PoolManager gas tests Native Tokens #swapExact0For1 first swap in block, large swap crossing a single initialized tick 1`] = ` Object { "calldataByteLength": 324, - "gasUsed": 198465, + "gasUsed": 197229, } `; exports[`PoolManager gas tests Native Tokens #swapExact0For1 first swap in block, large swap crossing several initialized ticks 1`] = ` Object { "calldataByteLength": 324, - "gasUsed": 240148, + "gasUsed": 238163, } `; exports[`PoolManager gas tests Native Tokens #swapExact0For1 first swap in block, large swap, no initialized crossings 1`] = ` Object { "calldataByteLength": 324, - "gasUsed": 191378, + "gasUsed": 189892, } `; exports[`PoolManager gas tests Native Tokens #swapExact0For1 second swap in block moves tick, no initialized crossings 1`] = ` Object { "calldataByteLength": 324, - "gasUsed": 179641, + "gasUsed": 178680, } `; exports[`PoolManager gas tests Native Tokens #swapExact0For1 second swap in block with no tick movement 1`] = ` Object { "calldataByteLength": 324, - "gasUsed": 173960, + "gasUsed": 173224, } `; exports[`PoolManager gas tests Native Tokens #swapExact0For1 second swap in block, large swap crossing a single initialized tick 1`] = ` Object { "calldataByteLength": 324, - "gasUsed": 192812, + "gasUsed": 191826, } `; exports[`PoolManager gas tests Native Tokens #swapExact0For1 second swap in block, large swap crossing several initialized ticks 1`] = ` Object { "calldataByteLength": 324, - "gasUsed": 234470, + "gasUsed": 232735, } `; diff --git a/test/__snapshots__/PoolManager.spec.ts.snap b/test/__snapshots__/PoolManager.spec.ts.snap index b57b41f63..58116ba40 100644 --- a/test/__snapshots__/PoolManager.spec.ts.snap +++ b/test/__snapshots__/PoolManager.spec.ts.snap @@ -1,3 +1,3 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`PoolManager bytecode size 1`] = `29219`; +exports[`PoolManager bytecode size 1`] = `29006`; diff --git a/test/__snapshots__/SwapMath.spec.ts.snap b/test/__snapshots__/SwapMath.spec.ts.snap index 55a87d526..284b2e460 100644 --- a/test/__snapshots__/SwapMath.spec.ts.snap +++ b/test/__snapshots__/SwapMath.spec.ts.snap @@ -1,17 +1,17 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`SwapMath #computeSwapStep gas swap one for zero exact in capped 1`] = `2221`; +exports[`SwapMath #computeSwapStep gas swap one for zero exact in capped 1`] = `1986`; -exports[`SwapMath #computeSwapStep gas swap one for zero exact in partial 1`] = `3049`; +exports[`SwapMath #computeSwapStep gas swap one for zero exact in partial 1`] = `2212`; -exports[`SwapMath #computeSwapStep gas swap one for zero exact out capped 1`] = `1968`; +exports[`SwapMath #computeSwapStep gas swap one for zero exact out capped 1`] = `1773`; -exports[`SwapMath #computeSwapStep gas swap one for zero exact out partial 1`] = `3049`; +exports[`SwapMath #computeSwapStep gas swap one for zero exact out partial 1`] = `2212`; -exports[`SwapMath #computeSwapStep gas swap zero for one exact in capped 1`] = `2210`; +exports[`SwapMath #computeSwapStep gas swap zero for one exact in capped 1`] = `1954`; -exports[`SwapMath #computeSwapStep gas swap zero for one exact in partial 1`] = `3208`; +exports[`SwapMath #computeSwapStep gas swap zero for one exact in partial 1`] = `2374`; -exports[`SwapMath #computeSwapStep gas swap zero for one exact out capped 1`] = `1957`; +exports[`SwapMath #computeSwapStep gas swap zero for one exact out capped 1`] = `1741`; -exports[`SwapMath #computeSwapStep gas swap zero for one exact out partial 1`] = `3208`; +exports[`SwapMath #computeSwapStep gas swap zero for one exact out partial 1`] = `2374`; From 4aea67d3314080995fb1c06fd9b9ece32b10a607 Mon Sep 17 00:00:00 2001 From: Shuhui Luo <107524008+shuhuiluo@users.noreply.github.com> Date: Thu, 4 Apr 2024 02:29:06 -0400 Subject: [PATCH 02/16] Update `SwapMath` calculations and gas snapshots, change `test_entireInputAmountTakenAsFee` --- .../SwapMath_oneForZero_exactInCapped.snap | 2 +- .../SwapMath_oneForZero_exactInPartial.snap | 2 +- .../SwapMath_oneForZero_exactOutCapped.snap | 2 +- .../SwapMath_oneForZero_exactOutPartial.snap | 2 +- .../SwapMath_zeroForOne_exactInCapped.snap | 2 +- .../SwapMath_zeroForOne_exactInPartial.snap | 2 +- .../SwapMath_zeroForOne_exactOutCapped.snap | 2 +- .../SwapMath_zeroForOne_exactOutPartial.snap | 2 +- .../poolManager bytecode size.snap | 2 +- .forge-snapshots/simple swap with native.snap | 2 +- .forge-snapshots/simple swap.snap | 2 +- ...p against liquidity with native token.snap | 2 +- .forge-snapshots/swap against liquidity.snap | 2 +- .../swap burn 6909 for input.snap | 2 +- .../swap burn native 6909 for input.snap | 2 +- .../swap mint native output as 6909.snap | 2 +- .../swap mint output as 6909.snap | 2 +- .forge-snapshots/swap with dynamic fee.snap | 2 +- .forge-snapshots/swap with hooks.snap | 2 +- .../update dynamic fee in before swap.snap | 2 +- src/libraries/SwapMath.sol | 53 +++++++++---------- test/libraries/SwapMath.t.sol | 6 +-- 22 files changed, 49 insertions(+), 50 deletions(-) diff --git a/.forge-snapshots/SwapMath_oneForZero_exactInCapped.snap b/.forge-snapshots/SwapMath_oneForZero_exactInCapped.snap index 27d48e9a4..cfc3b26d4 100644 --- a/.forge-snapshots/SwapMath_oneForZero_exactInCapped.snap +++ b/.forge-snapshots/SwapMath_oneForZero_exactInCapped.snap @@ -1 +1 @@ -1947 \ No newline at end of file +1731 \ No newline at end of file diff --git a/.forge-snapshots/SwapMath_oneForZero_exactInPartial.snap b/.forge-snapshots/SwapMath_oneForZero_exactInPartial.snap index 9560ba822..6b6243de2 100644 --- a/.forge-snapshots/SwapMath_oneForZero_exactInPartial.snap +++ b/.forge-snapshots/SwapMath_oneForZero_exactInPartial.snap @@ -1 +1 @@ -3238 \ No newline at end of file +2571 \ No newline at end of file diff --git a/.forge-snapshots/SwapMath_oneForZero_exactOutCapped.snap b/.forge-snapshots/SwapMath_oneForZero_exactOutCapped.snap index 758e03adc..fff5ffc8d 100644 --- a/.forge-snapshots/SwapMath_oneForZero_exactOutCapped.snap +++ b/.forge-snapshots/SwapMath_oneForZero_exactOutCapped.snap @@ -1 +1 @@ -2208 \ No newline at end of file +1920 \ No newline at end of file diff --git a/.forge-snapshots/SwapMath_oneForZero_exactOutPartial.snap b/.forge-snapshots/SwapMath_oneForZero_exactOutPartial.snap index 9560ba822..6b6243de2 100644 --- a/.forge-snapshots/SwapMath_oneForZero_exactOutPartial.snap +++ b/.forge-snapshots/SwapMath_oneForZero_exactOutPartial.snap @@ -1 +1 @@ -3238 \ No newline at end of file +2571 \ No newline at end of file diff --git a/.forge-snapshots/SwapMath_zeroForOne_exactInCapped.snap b/.forge-snapshots/SwapMath_zeroForOne_exactInCapped.snap index 12057ad70..eb3da1d12 100644 --- a/.forge-snapshots/SwapMath_zeroForOne_exactInCapped.snap +++ b/.forge-snapshots/SwapMath_zeroForOne_exactInCapped.snap @@ -1 +1 @@ -1937 \ No newline at end of file +1710 \ No newline at end of file diff --git a/.forge-snapshots/SwapMath_zeroForOne_exactInPartial.snap b/.forge-snapshots/SwapMath_zeroForOne_exactInPartial.snap index c173e591f..7dd861da9 100644 --- a/.forge-snapshots/SwapMath_zeroForOne_exactInPartial.snap +++ b/.forge-snapshots/SwapMath_zeroForOne_exactInPartial.snap @@ -1 +1 @@ -2826 \ No newline at end of file +2138 \ No newline at end of file diff --git a/.forge-snapshots/SwapMath_zeroForOne_exactOutCapped.snap b/.forge-snapshots/SwapMath_zeroForOne_exactOutCapped.snap index c802063a0..da9ac3907 100644 --- a/.forge-snapshots/SwapMath_zeroForOne_exactOutCapped.snap +++ b/.forge-snapshots/SwapMath_zeroForOne_exactOutCapped.snap @@ -1 +1 @@ -2198 \ No newline at end of file +1899 \ No newline at end of file diff --git a/.forge-snapshots/SwapMath_zeroForOne_exactOutPartial.snap b/.forge-snapshots/SwapMath_zeroForOne_exactOutPartial.snap index c173e591f..7dd861da9 100644 --- a/.forge-snapshots/SwapMath_zeroForOne_exactOutPartial.snap +++ b/.forge-snapshots/SwapMath_zeroForOne_exactOutPartial.snap @@ -1 +1 @@ -2826 \ No newline at end of file +2138 \ No newline at end of file diff --git a/.forge-snapshots/poolManager bytecode size.snap b/.forge-snapshots/poolManager bytecode size.snap index 39c68e33e..8ce59a7cf 100644 --- a/.forge-snapshots/poolManager bytecode size.snap +++ b/.forge-snapshots/poolManager bytecode size.snap @@ -1 +1 @@ -22974 \ No newline at end of file +22767 \ No newline at end of file diff --git a/.forge-snapshots/simple swap with native.snap b/.forge-snapshots/simple swap with native.snap index 797d10395..4f904d548 100644 --- a/.forge-snapshots/simple swap with native.snap +++ b/.forge-snapshots/simple swap with native.snap @@ -1 +1 @@ -132905 \ No newline at end of file +131631 \ No newline at end of file diff --git a/.forge-snapshots/simple swap.snap b/.forge-snapshots/simple swap.snap index 483955831..fc4e8cf80 100644 --- a/.forge-snapshots/simple swap.snap +++ b/.forge-snapshots/simple swap.snap @@ -1 +1 @@ -146781 \ No newline at end of file +145507 \ No newline at end of file diff --git a/.forge-snapshots/swap against liquidity with native token.snap b/.forge-snapshots/swap against liquidity with native token.snap index 6671e8870..3f3a80a47 100644 --- a/.forge-snapshots/swap against liquidity with native token.snap +++ b/.forge-snapshots/swap against liquidity with native token.snap @@ -1 +1 @@ -72364 \ No newline at end of file +71410 \ No newline at end of file diff --git a/.forge-snapshots/swap against liquidity.snap b/.forge-snapshots/swap against liquidity.snap index c31794dbd..14778f5d9 100644 --- a/.forge-snapshots/swap against liquidity.snap +++ b/.forge-snapshots/swap against liquidity.snap @@ -1 +1 @@ -60367 \ No newline at end of file +59413 \ No newline at end of file diff --git a/.forge-snapshots/swap burn 6909 for input.snap b/.forge-snapshots/swap burn 6909 for input.snap index 4cc58cdca..1164c32bc 100644 --- a/.forge-snapshots/swap burn 6909 for input.snap +++ b/.forge-snapshots/swap burn 6909 for input.snap @@ -1 +1 @@ -80397 \ No newline at end of file +79678 \ No newline at end of file diff --git a/.forge-snapshots/swap burn native 6909 for input.snap b/.forge-snapshots/swap burn native 6909 for input.snap index e67a9a599..ce4392323 100644 --- a/.forge-snapshots/swap burn native 6909 for input.snap +++ b/.forge-snapshots/swap burn native 6909 for input.snap @@ -1 +1 @@ -76394 \ No newline at end of file +75659 \ No newline at end of file diff --git a/.forge-snapshots/swap mint native output as 6909.snap b/.forge-snapshots/swap mint native output as 6909.snap index f504a2867..1b527f4d9 100644 --- a/.forge-snapshots/swap mint native output as 6909.snap +++ b/.forge-snapshots/swap mint native output as 6909.snap @@ -1 +1 @@ -138745 \ No newline at end of file +137818 \ No newline at end of file diff --git a/.forge-snapshots/swap mint output as 6909.snap b/.forge-snapshots/swap mint output as 6909.snap index d2db9e035..5572e3b4f 100644 --- a/.forge-snapshots/swap mint output as 6909.snap +++ b/.forge-snapshots/swap mint output as 6909.snap @@ -1 +1 @@ -155596 \ No newline at end of file +154322 \ No newline at end of file diff --git a/.forge-snapshots/swap with dynamic fee.snap b/.forge-snapshots/swap with dynamic fee.snap index a901423df..dd96c6fb5 100644 --- a/.forge-snapshots/swap with dynamic fee.snap +++ b/.forge-snapshots/swap with dynamic fee.snap @@ -1 +1 @@ -89671 \ No newline at end of file +88397 \ No newline at end of file diff --git a/.forge-snapshots/swap with hooks.snap b/.forge-snapshots/swap with hooks.snap index 29498b964..a468f15c7 100644 --- a/.forge-snapshots/swap with hooks.snap +++ b/.forge-snapshots/swap with hooks.snap @@ -1 +1 @@ -60345 \ No newline at end of file +59391 \ No newline at end of file diff --git a/.forge-snapshots/update dynamic fee in before swap.snap b/.forge-snapshots/update dynamic fee in before swap.snap index d6bca4c74..0b5280823 100644 --- a/.forge-snapshots/update dynamic fee in before swap.snap +++ b/.forge-snapshots/update dynamic fee in before swap.snap @@ -1 +1 @@ -140297 \ No newline at end of file +139023 \ No newline at end of file diff --git a/src/libraries/SwapMath.sol b/src/libraries/SwapMath.sol index f38ee0ed4..b7d3411f7 100644 --- a/src/libraries/SwapMath.sol +++ b/src/libraries/SwapMath.sol @@ -7,7 +7,7 @@ import {SqrtPriceMath} from "./SqrtPriceMath.sol"; /// @title Computes the result of a swap within ticks /// @notice Contains methods for computing the result of a swap within a single tick price range, i.e., a single tick. library SwapMath { - uint24 internal constant MAX_FEE_PIPS = 1e6; + uint256 internal constant MAX_FEE_PIPS = 1e6; /// @notice Computes the sqrt price target for the next swap step /// @param zeroForOne The direction of the swap, true for token0 to token1, false for token1 to token0 @@ -53,17 +53,33 @@ library SwapMath { unchecked { bool zeroForOne = sqrtRatioCurrentX96 >= sqrtRatioTargetX96; uint256 feeComplement = MAX_FEE_PIPS - feePips; - bool exactIn; uint256 amountRemainingAbs; - assembly { - // exactIn = 1 if amountRemaining >= 0 else 0 - exactIn := iszero(slt(amountRemaining, 0)) - // mask = 0 if amountRemaining >= 0 else -1 - let mask := sub(exactIn, 1) - amountRemainingAbs := xor(mask, add(mask, amountRemaining)) - } + bool exactIn = amountRemaining < 0; - if (exactIn) { + if (!exactIn) { + amountOut = zeroForOne + ? SqrtPriceMath.getAmount1Delta(sqrtRatioTargetX96, sqrtRatioCurrentX96, liquidity, false) + : SqrtPriceMath.getAmount0Delta(sqrtRatioCurrentX96, sqrtRatioTargetX96, liquidity, false); + assembly { + amountRemainingAbs := amountRemaining + } + if (amountRemainingAbs >= amountOut) { + // `amountOut` is capped by the target price + sqrtRatioNextX96 = sqrtRatioTargetX96; + } else { + // cap the output amount to not exceed the remaining output amount + amountOut = amountRemainingAbs; + sqrtRatioNextX96 = + SqrtPriceMath.getNextSqrtPriceFromOutput(sqrtRatioCurrentX96, liquidity, amountOut, zeroForOne); + } + amountIn = zeroForOne + ? SqrtPriceMath.getAmount0Delta(sqrtRatioNextX96, sqrtRatioCurrentX96, liquidity, true) + : SqrtPriceMath.getAmount1Delta(sqrtRatioCurrentX96, sqrtRatioNextX96, liquidity, true); + feeAmount = FullMath.mulDivRoundingUp(amountIn, feePips, feeComplement); + } else { + assembly { + amountRemainingAbs := sub(0, amountRemaining) + } uint256 amountRemainingLessFee = FullMath.mulDiv(amountRemainingAbs, feeComplement, MAX_FEE_PIPS); amountIn = zeroForOne ? SqrtPriceMath.getAmount0Delta(sqrtRatioTargetX96, sqrtRatioCurrentX96, liquidity, true) @@ -83,23 +99,6 @@ library SwapMath { amountOut = zeroForOne ? SqrtPriceMath.getAmount1Delta(sqrtRatioNextX96, sqrtRatioCurrentX96, liquidity, false) : SqrtPriceMath.getAmount0Delta(sqrtRatioCurrentX96, sqrtRatioNextX96, liquidity, false); - } else { - amountOut = zeroForOne - ? SqrtPriceMath.getAmount1Delta(sqrtRatioTargetX96, sqrtRatioCurrentX96, liquidity, false) - : SqrtPriceMath.getAmount0Delta(sqrtRatioCurrentX96, sqrtRatioTargetX96, liquidity, false); - if (amountRemainingAbs >= amountOut) { - // `amountOut` is capped by the target price - sqrtRatioNextX96 = sqrtRatioTargetX96; - } else { - // cap the output amount to not exceed the remaining output amount - amountOut = amountRemainingAbs; - sqrtRatioNextX96 = - SqrtPriceMath.getNextSqrtPriceFromOutput(sqrtRatioCurrentX96, liquidity, amountOut, zeroForOne); - } - amountIn = zeroForOne - ? SqrtPriceMath.getAmount0Delta(sqrtRatioNextX96, sqrtRatioCurrentX96, liquidity, true) - : SqrtPriceMath.getAmount1Delta(sqrtRatioCurrentX96, sqrtRatioNextX96, liquidity, true); - feeAmount = FullMath.mulDivRoundingUp(amountIn, feePips, feeComplement); } } } diff --git a/test/libraries/SwapMath.t.sol b/test/libraries/SwapMath.t.sol index 2c17f41f6..c01f427e9 100644 --- a/test/libraries/SwapMath.t.sol +++ b/test/libraries/SwapMath.t.sol @@ -128,12 +128,12 @@ contract SwapMathTest is Test, GasSnapshot { assertEq(sqrtQ, 1); } - function test_entireInputAmountTakenAsFee() public { + function test_notEntireInputAmountTakenAsFee() public { (uint160 sqrtQ, uint256 amountIn, uint256 amountOut, uint256 feeAmount) = SwapMath.computeSwapStep(2413, 79887613182836312, 1985041575832132834610021537970, -10, 1872); - assertEq(amountIn, 0); - assertEq(feeAmount, 10); + assertEq(amountIn, 9); + assertEq(feeAmount, 1); assertEq(amountOut, 0); assertEq(sqrtQ, 2413); } From 2e92f2897f52bcdcaad590605ea5a544381fb77b Mon Sep 17 00:00:00 2001 From: Shuhui Luo <107524008+shuhuiluo@users.noreply.github.com> Date: Tue, 9 Apr 2024 22:28:57 -0400 Subject: [PATCH 03/16] No assembly in `computeSwapStep` Replace inline assembly with native Solidity for `amountRemainingAbs` calculation in `computeSwapStep` function. The previous implementation was not intuitive and easy to read. This change simplifies the code and improves readability while maintaining the exact functionality. --- src/libraries/SwapMath.sol | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/src/libraries/SwapMath.sol b/src/libraries/SwapMath.sol index b7d3411f7..50af77274 100644 --- a/src/libraries/SwapMath.sol +++ b/src/libraries/SwapMath.sol @@ -60,9 +60,7 @@ library SwapMath { amountOut = zeroForOne ? SqrtPriceMath.getAmount1Delta(sqrtRatioTargetX96, sqrtRatioCurrentX96, liquidity, false) : SqrtPriceMath.getAmount0Delta(sqrtRatioCurrentX96, sqrtRatioTargetX96, liquidity, false); - assembly { - amountRemainingAbs := amountRemaining - } + amountRemainingAbs = uint256(amountRemaining); if (amountRemainingAbs >= amountOut) { // `amountOut` is capped by the target price sqrtRatioNextX96 = sqrtRatioTargetX96; @@ -77,9 +75,7 @@ library SwapMath { : SqrtPriceMath.getAmount1Delta(sqrtRatioCurrentX96, sqrtRatioNextX96, liquidity, true); feeAmount = FullMath.mulDivRoundingUp(amountIn, feePips, feeComplement); } else { - assembly { - amountRemainingAbs := sub(0, amountRemaining) - } + amountRemainingAbs = uint256(-amountRemaining); uint256 amountRemainingLessFee = FullMath.mulDiv(amountRemainingAbs, feeComplement, MAX_FEE_PIPS); amountIn = zeroForOne ? SqrtPriceMath.getAmount0Delta(sqrtRatioTargetX96, sqrtRatioCurrentX96, liquidity, true) From 2b9e6533a921d236db4baeae5293bbda23840c78 Mon Sep 17 00:00:00 2001 From: Shuhui Luo <107524008+shuhuiluo@users.noreply.github.com> Date: Wed, 24 Apr 2024 05:29:50 -0400 Subject: [PATCH 04/16] Avoid casting `feePips` multiple times In `SwapMath.sol`, we reduced redundancy by storing the value of `feePips` into `_feePips` and using it throughout the function instead of casting `feePips` multiple times. This refactoring improved efficiency and reduced bytecode size, leading to reduced gas cost for function calls. --- .../SwapMath_oneForZero_exactInCapped.snap | 2 +- .../SwapMath_oneForZero_exactOutCapped.snap | 2 +- .../SwapMath_oneForZero_exactOutPartial.snap | 2 +- .../SwapMath_zeroForOne_exactInCapped.snap | 2 +- .../SwapMath_zeroForOne_exactOutCapped.snap | 2 +- .../SwapMath_zeroForOne_exactOutPartial.snap | 2 +- .forge-snapshots/poolManager bytecode size.snap | 2 +- .forge-snapshots/simple swap with native.snap | 2 +- .forge-snapshots/simple swap.snap | 2 +- .forge-snapshots/swap burn 6909 for input.snap | 2 +- .../swap burn native 6909 for input.snap | 2 +- .forge-snapshots/swap mint output as 6909.snap | 2 +- .../swap skips hook call if hook is caller.snap | 2 +- .forge-snapshots/swap with dynamic fee.snap | 2 +- .../swap with lp fee and protocol fee.snap | 2 +- .../update dynamic fee in before swap.snap | 2 +- src/libraries/SwapMath.sol | 12 +++++++----- 17 files changed, 23 insertions(+), 21 deletions(-) diff --git a/.forge-snapshots/SwapMath_oneForZero_exactInCapped.snap b/.forge-snapshots/SwapMath_oneForZero_exactInCapped.snap index 93f881d11..7411188d9 100644 --- a/.forge-snapshots/SwapMath_oneForZero_exactInCapped.snap +++ b/.forge-snapshots/SwapMath_oneForZero_exactInCapped.snap @@ -1 +1 @@ -1960 \ No newline at end of file +1954 \ No newline at end of file diff --git a/.forge-snapshots/SwapMath_oneForZero_exactOutCapped.snap b/.forge-snapshots/SwapMath_oneForZero_exactOutCapped.snap index cfc3b26d4..a0ac2c52a 100644 --- a/.forge-snapshots/SwapMath_oneForZero_exactOutCapped.snap +++ b/.forge-snapshots/SwapMath_oneForZero_exactOutCapped.snap @@ -1 +1 @@ -1731 \ No newline at end of file +1725 \ No newline at end of file diff --git a/.forge-snapshots/SwapMath_oneForZero_exactOutPartial.snap b/.forge-snapshots/SwapMath_oneForZero_exactOutPartial.snap index 6b6243de2..05dfd639e 100644 --- a/.forge-snapshots/SwapMath_oneForZero_exactOutPartial.snap +++ b/.forge-snapshots/SwapMath_oneForZero_exactOutPartial.snap @@ -1 +1 @@ -2571 \ No newline at end of file +2565 \ No newline at end of file diff --git a/.forge-snapshots/SwapMath_zeroForOne_exactInCapped.snap b/.forge-snapshots/SwapMath_zeroForOne_exactInCapped.snap index 49bf11df7..6c05f6d8d 100644 --- a/.forge-snapshots/SwapMath_zeroForOne_exactInCapped.snap +++ b/.forge-snapshots/SwapMath_zeroForOne_exactInCapped.snap @@ -1 +1 @@ -1939 \ No newline at end of file +1933 \ No newline at end of file diff --git a/.forge-snapshots/SwapMath_zeroForOne_exactOutCapped.snap b/.forge-snapshots/SwapMath_zeroForOne_exactOutCapped.snap index eb3da1d12..dfd4d9fcd 100644 --- a/.forge-snapshots/SwapMath_zeroForOne_exactOutCapped.snap +++ b/.forge-snapshots/SwapMath_zeroForOne_exactOutCapped.snap @@ -1 +1 @@ -1710 \ No newline at end of file +1704 \ No newline at end of file diff --git a/.forge-snapshots/SwapMath_zeroForOne_exactOutPartial.snap b/.forge-snapshots/SwapMath_zeroForOne_exactOutPartial.snap index 7dd861da9..3827a8bde 100644 --- a/.forge-snapshots/SwapMath_zeroForOne_exactOutPartial.snap +++ b/.forge-snapshots/SwapMath_zeroForOne_exactOutPartial.snap @@ -1 +1 @@ -2138 \ No newline at end of file +2132 \ No newline at end of file diff --git a/.forge-snapshots/poolManager bytecode size.snap b/.forge-snapshots/poolManager bytecode size.snap index fc5cc9014..1085aa337 100644 --- a/.forge-snapshots/poolManager bytecode size.snap +++ b/.forge-snapshots/poolManager bytecode size.snap @@ -1 +1 @@ -22503 \ No newline at end of file +22498 \ No newline at end of file diff --git a/.forge-snapshots/simple swap with native.snap b/.forge-snapshots/simple swap with native.snap index afe3d0736..19b81478e 100644 --- a/.forge-snapshots/simple swap with native.snap +++ b/.forge-snapshots/simple swap with native.snap @@ -1 +1 @@ -125606 \ No newline at end of file +125600 \ No newline at end of file diff --git a/.forge-snapshots/simple swap.snap b/.forge-snapshots/simple swap.snap index ff701a108..8fbb41193 100644 --- a/.forge-snapshots/simple swap.snap +++ b/.forge-snapshots/simple swap.snap @@ -1 +1 @@ -136999 \ No newline at end of file +136993 \ No newline at end of file diff --git a/.forge-snapshots/swap burn 6909 for input.snap b/.forge-snapshots/swap burn 6909 for input.snap index f94899a71..7e01d02ff 100644 --- a/.forge-snapshots/swap burn 6909 for input.snap +++ b/.forge-snapshots/swap burn 6909 for input.snap @@ -1 +1 @@ -78736 \ No newline at end of file +78730 \ No newline at end of file diff --git a/.forge-snapshots/swap burn native 6909 for input.snap b/.forge-snapshots/swap burn native 6909 for input.snap index 57bdf2c31..6ab22a225 100644 --- a/.forge-snapshots/swap burn native 6909 for input.snap +++ b/.forge-snapshots/swap burn native 6909 for input.snap @@ -1 +1 @@ -74563 \ No newline at end of file +74557 \ No newline at end of file diff --git a/.forge-snapshots/swap mint output as 6909.snap b/.forge-snapshots/swap mint output as 6909.snap index 32a6eee65..4a77b7870 100644 --- a/.forge-snapshots/swap mint output as 6909.snap +++ b/.forge-snapshots/swap mint output as 6909.snap @@ -1 +1 @@ -151002 \ No newline at end of file +150996 \ No newline at end of file diff --git a/.forge-snapshots/swap skips hook call if hook is caller.snap b/.forge-snapshots/swap skips hook call if hook is caller.snap index 490a548c4..41e1af222 100644 --- a/.forge-snapshots/swap skips hook call if hook is caller.snap +++ b/.forge-snapshots/swap skips hook call if hook is caller.snap @@ -1 +1 @@ -156655 \ No newline at end of file +156649 \ No newline at end of file diff --git a/.forge-snapshots/swap with dynamic fee.snap b/.forge-snapshots/swap with dynamic fee.snap index 8c88c9099..d1410f509 100644 --- a/.forge-snapshots/swap with dynamic fee.snap +++ b/.forge-snapshots/swap with dynamic fee.snap @@ -1 +1 @@ -89489 \ No newline at end of file +89483 \ No newline at end of file diff --git a/.forge-snapshots/swap with lp fee and protocol fee.snap b/.forge-snapshots/swap with lp fee and protocol fee.snap index ec81d2dca..07218a4cb 100644 --- a/.forge-snapshots/swap with lp fee and protocol fee.snap +++ b/.forge-snapshots/swap with lp fee and protocol fee.snap @@ -1 +1 @@ -150000 \ No newline at end of file +149988 \ No newline at end of file diff --git a/.forge-snapshots/update dynamic fee in before swap.snap b/.forge-snapshots/update dynamic fee in before swap.snap index 1ab508330..3efa16abd 100644 --- a/.forge-snapshots/update dynamic fee in before swap.snap +++ b/.forge-snapshots/update dynamic fee in before swap.snap @@ -1 +1 @@ -130516 \ No newline at end of file +130510 \ No newline at end of file diff --git a/src/libraries/SwapMath.sol b/src/libraries/SwapMath.sol index 14e73a769..efdcb6013 100644 --- a/src/libraries/SwapMath.sol +++ b/src/libraries/SwapMath.sol @@ -51,8 +51,8 @@ library SwapMath { uint24 feePips ) internal pure returns (uint160 sqrtRatioNextX96, uint256 amountIn, uint256 amountOut, uint256 feeAmount) { unchecked { + uint256 _feePips = feePips; // cast once and cache bool zeroForOne = sqrtRatioCurrentX96 >= sqrtRatioTargetX96; - uint256 feeComplement = MAX_FEE_PIPS - feePips; uint256 amountRemainingAbs; bool exactIn = amountRemaining < 0; @@ -74,18 +74,20 @@ library SwapMath { ? SqrtPriceMath.getAmount0Delta(sqrtRatioNextX96, sqrtRatioCurrentX96, liquidity, true) : SqrtPriceMath.getAmount1Delta(sqrtRatioCurrentX96, sqrtRatioNextX96, liquidity, true); // `feePips` cannot be `MAX_FEE_PIPS` for exact out - feeAmount = FullMath.mulDivRoundingUp(amountIn, feePips, feeComplement); + feeAmount = FullMath.mulDivRoundingUp(amountIn, _feePips, MAX_FEE_PIPS - _feePips); } else { amountRemainingAbs = uint256(-amountRemaining); - uint256 amountRemainingLessFee = FullMath.mulDiv(amountRemainingAbs, feeComplement, MAX_FEE_PIPS); + uint256 amountRemainingLessFee = + FullMath.mulDiv(amountRemainingAbs, MAX_FEE_PIPS - _feePips, MAX_FEE_PIPS); amountIn = zeroForOne ? SqrtPriceMath.getAmount0Delta(sqrtRatioTargetX96, sqrtRatioCurrentX96, liquidity, true) : SqrtPriceMath.getAmount1Delta(sqrtRatioCurrentX96, sqrtRatioTargetX96, liquidity, true); if (amountRemainingLessFee >= amountIn) { // `amountIn` is capped by the target price sqrtRatioNextX96 = sqrtRatioTargetX96; - feeAmount = - feePips == MAX_FEE_PIPS ? amountIn : FullMath.mulDivRoundingUp(amountIn, feePips, feeComplement); + feeAmount = _feePips == MAX_FEE_PIPS + ? amountIn + : FullMath.mulDivRoundingUp(amountIn, _feePips, MAX_FEE_PIPS - _feePips); } else { // exhaust the remaining amount amountIn = amountRemainingLessFee; From 4ec866dbf6316e0e3ddbe01e82717dd1449e7496 Mon Sep 17 00:00:00 2001 From: Shuhui Luo <107524008+shuhuiluo@users.noreply.github.com> Date: Wed, 24 Apr 2024 05:37:26 -0400 Subject: [PATCH 05/16] Fix natspec --- src/libraries/SwapMath.sol | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libraries/SwapMath.sol b/src/libraries/SwapMath.sol index efdcb6013..d868c37aa 100644 --- a/src/libraries/SwapMath.sol +++ b/src/libraries/SwapMath.sol @@ -10,7 +10,7 @@ library SwapMath { uint256 internal constant MAX_FEE_PIPS = 1e6; /// @notice Computes the sqrt price target for the next swap step - /// @param zeroForOne The direction of the swap, true for token0 to token1, false for token1 to token0 + /// @param zeroForOne The direction of the swap, true for currency0 to currency1, false for currency1 to currency0 /// @param sqrtPriceNextX96 The Q64.96 sqrt price for the next initialized tick /// @param sqrtPriceLimitX96 The Q64.96 sqrt price limit. If zero for one, the price cannot be less than this /// value after the swap. If one for zero, the price cannot be greater than this value after the swap From 1d3c707ed1e310e54a9732ace3bad308eef7adb0 Mon Sep 17 00:00:00 2001 From: Shuhui Luo <107524008+shuhuiluo@users.noreply.github.com> Date: Thu, 16 May 2024 22:51:17 -0400 Subject: [PATCH 06/16] Rename `sqrtRatio` to `sqrtPrice` in SwapMath and Pool libraries --- src/libraries/Pool.sol | 2 +- src/libraries/SwapMath.sol | 54 +++++++++++++++++++------------------- 2 files changed, 28 insertions(+), 28 deletions(-) diff --git a/src/libraries/Pool.sol b/src/libraries/Pool.sol index dcc67090d..d8f4ce872 100644 --- a/src/libraries/Pool.sol +++ b/src/libraries/Pool.sol @@ -369,7 +369,7 @@ library Pool { // compute values to swap to the target tick, price limit, or point where input/output amount is exhausted (state.sqrtPriceX96, step.amountIn, step.amountOut, step.feeAmount) = SwapMath.computeSwapStep( state.sqrtPriceX96, - SwapMath.getSqrtRatioTarget(zeroForOne, step.sqrtPriceNextX96, params.sqrtPriceLimitX96), + SwapMath.getSqrtPriceTarget(zeroForOne, step.sqrtPriceNextX96, params.sqrtPriceLimitX96), state.liquidity, state.amountSpecifiedRemaining, swapFee diff --git a/src/libraries/SwapMath.sol b/src/libraries/SwapMath.sol index d868c37aa..8fe19b385 100644 --- a/src/libraries/SwapMath.sol +++ b/src/libraries/SwapMath.sol @@ -14,65 +14,65 @@ library SwapMath { /// @param sqrtPriceNextX96 The Q64.96 sqrt price for the next initialized tick /// @param sqrtPriceLimitX96 The Q64.96 sqrt price limit. If zero for one, the price cannot be less than this /// value after the swap. If one for zero, the price cannot be greater than this value after the swap - /// @return sqrtRatioTargetX96 The price target for the next swap step - function getSqrtRatioTarget(bool zeroForOne, uint160 sqrtPriceNextX96, uint160 sqrtPriceLimitX96) + /// @return sqrtPriceTargetX96 The price target for the next swap step + function getSqrtPriceTarget(bool zeroForOne, uint160 sqrtPriceNextX96, uint160 sqrtPriceLimitX96) internal pure - returns (uint160 sqrtRatioTargetX96) + returns (uint160 sqrtPriceTargetX96) { assembly { // a flag to toggle between sqrtPriceNextX96 and sqrtPriceLimitX96 // when zeroForOne == true, nextOrLimit reduces to sqrtPriceNextX96 > sqrtPriceLimitX96 - // sqrtRatioTargetX96 = max(sqrtPriceNextX96, sqrtPriceLimitX96) + // sqrtPriceTargetX96 = max(sqrtPriceNextX96, sqrtPriceLimitX96) // when zeroForOne == false, nextOrLimit reduces to sqrtPriceNextX96 <= sqrtPriceLimitX96 - // sqrtRatioTargetX96 = min(sqrtPriceNextX96, sqrtPriceLimitX96) + // sqrtPriceTargetX96 = min(sqrtPriceNextX96, sqrtPriceLimitX96) let nextOrLimit := xor(gt(sqrtPriceNextX96, sqrtPriceLimitX96), iszero(zeroForOne)) let symDiff := xor(sqrtPriceNextX96, sqrtPriceLimitX96) - sqrtRatioTargetX96 := xor(sqrtPriceLimitX96, mul(symDiff, nextOrLimit)) + sqrtPriceTargetX96 := xor(sqrtPriceLimitX96, mul(symDiff, nextOrLimit)) } } /// @notice Computes the result of swapping some amount in, or amount out, given the parameters of the swap /// @dev The fee, plus the amount in, will never exceed the amount remaining if the swap's `amountSpecified` is positive - /// @param sqrtRatioCurrentX96 The current sqrt price of the pool - /// @param sqrtRatioTargetX96 The price that cannot be exceeded, from which the direction of the swap is inferred + /// @param sqrtPriceCurrentX96 The current sqrt price of the pool + /// @param sqrtPriceTargetX96 The price that cannot be exceeded, from which the direction of the swap is inferred /// @param liquidity The usable liquidity /// @param amountRemaining How much input or output amount is remaining to be swapped in/out /// @param feePips The fee taken from the input amount, expressed in hundredths of a bip - /// @return sqrtRatioNextX96 The price after swapping the amount in/out, not to exceed the price target + /// @return sqrtPriceNextX96 The price after swapping the amount in/out, not to exceed the price target /// @return amountIn The amount to be swapped in, of either currency0 or currency1, based on the direction of the swap /// @return amountOut The amount to be received, of either currency0 or currency1, based on the direction of the swap /// @return feeAmount The amount of input that will be taken as a fee function computeSwapStep( - uint160 sqrtRatioCurrentX96, - uint160 sqrtRatioTargetX96, + uint160 sqrtPriceCurrentX96, + uint160 sqrtPriceTargetX96, uint128 liquidity, int256 amountRemaining, uint24 feePips - ) internal pure returns (uint160 sqrtRatioNextX96, uint256 amountIn, uint256 amountOut, uint256 feeAmount) { + ) internal pure returns (uint160 sqrtPriceNextX96, uint256 amountIn, uint256 amountOut, uint256 feeAmount) { unchecked { uint256 _feePips = feePips; // cast once and cache - bool zeroForOne = sqrtRatioCurrentX96 >= sqrtRatioTargetX96; + bool zeroForOne = sqrtPriceCurrentX96 >= sqrtPriceTargetX96; uint256 amountRemainingAbs; bool exactIn = amountRemaining < 0; if (!exactIn) { amountOut = zeroForOne - ? SqrtPriceMath.getAmount1Delta(sqrtRatioTargetX96, sqrtRatioCurrentX96, liquidity, false) - : SqrtPriceMath.getAmount0Delta(sqrtRatioCurrentX96, sqrtRatioTargetX96, liquidity, false); + ? SqrtPriceMath.getAmount1Delta(sqrtPriceTargetX96, sqrtPriceCurrentX96, liquidity, false) + : SqrtPriceMath.getAmount0Delta(sqrtPriceCurrentX96, sqrtPriceTargetX96, liquidity, false); amountRemainingAbs = uint256(amountRemaining); if (amountRemainingAbs >= amountOut) { // `amountOut` is capped by the target price - sqrtRatioNextX96 = sqrtRatioTargetX96; + sqrtPriceNextX96 = sqrtPriceTargetX96; } else { // cap the output amount to not exceed the remaining output amount amountOut = amountRemainingAbs; - sqrtRatioNextX96 = - SqrtPriceMath.getNextSqrtPriceFromOutput(sqrtRatioCurrentX96, liquidity, amountOut, zeroForOne); + sqrtPriceNextX96 = + SqrtPriceMath.getNextSqrtPriceFromOutput(sqrtPriceCurrentX96, liquidity, amountOut, zeroForOne); } amountIn = zeroForOne - ? SqrtPriceMath.getAmount0Delta(sqrtRatioNextX96, sqrtRatioCurrentX96, liquidity, true) - : SqrtPriceMath.getAmount1Delta(sqrtRatioCurrentX96, sqrtRatioNextX96, liquidity, true); + ? SqrtPriceMath.getAmount0Delta(sqrtPriceNextX96, sqrtPriceCurrentX96, liquidity, true) + : SqrtPriceMath.getAmount1Delta(sqrtPriceCurrentX96, sqrtPriceNextX96, liquidity, true); // `feePips` cannot be `MAX_FEE_PIPS` for exact out feeAmount = FullMath.mulDivRoundingUp(amountIn, _feePips, MAX_FEE_PIPS - _feePips); } else { @@ -80,25 +80,25 @@ library SwapMath { uint256 amountRemainingLessFee = FullMath.mulDiv(amountRemainingAbs, MAX_FEE_PIPS - _feePips, MAX_FEE_PIPS); amountIn = zeroForOne - ? SqrtPriceMath.getAmount0Delta(sqrtRatioTargetX96, sqrtRatioCurrentX96, liquidity, true) - : SqrtPriceMath.getAmount1Delta(sqrtRatioCurrentX96, sqrtRatioTargetX96, liquidity, true); + ? SqrtPriceMath.getAmount0Delta(sqrtPriceTargetX96, sqrtPriceCurrentX96, liquidity, true) + : SqrtPriceMath.getAmount1Delta(sqrtPriceCurrentX96, sqrtPriceTargetX96, liquidity, true); if (amountRemainingLessFee >= amountIn) { // `amountIn` is capped by the target price - sqrtRatioNextX96 = sqrtRatioTargetX96; + sqrtPriceNextX96 = sqrtPriceTargetX96; feeAmount = _feePips == MAX_FEE_PIPS ? amountIn : FullMath.mulDivRoundingUp(amountIn, _feePips, MAX_FEE_PIPS - _feePips); } else { // exhaust the remaining amount amountIn = amountRemainingLessFee; - sqrtRatioNextX96 = - SqrtPriceMath.getNextSqrtPriceFromInput(sqrtRatioCurrentX96, liquidity, amountIn, zeroForOne); + sqrtPriceNextX96 = + SqrtPriceMath.getNextSqrtPriceFromInput(sqrtPriceCurrentX96, liquidity, amountIn, zeroForOne); // we didn't reach the target, so take the remainder of the maximum input as fee feeAmount = amountRemainingAbs - amountIn; } amountOut = zeroForOne - ? SqrtPriceMath.getAmount1Delta(sqrtRatioNextX96, sqrtRatioCurrentX96, liquidity, false) - : SqrtPriceMath.getAmount0Delta(sqrtRatioCurrentX96, sqrtRatioNextX96, liquidity, false); + ? SqrtPriceMath.getAmount1Delta(sqrtPriceNextX96, sqrtPriceCurrentX96, liquidity, false) + : SqrtPriceMath.getAmount0Delta(sqrtPriceCurrentX96, sqrtPriceNextX96, liquidity, false); } } } From 2a023c86e78cfa74b71335e80564813dc7a19417 Mon Sep 17 00:00:00 2001 From: Shuhui Luo <107524008+shuhuiluo@users.noreply.github.com> Date: Thu, 16 May 2024 23:01:50 -0400 Subject: [PATCH 07/16] Refactor variable declaration in `SwapMath` The declaration and assignment of `amountRemainingAbs` has been moved inside the relevant if-else blocks in the SwapMath.sol file. This change makes the code more concise and clear by limiting the scope and use of `amountRemainingAbs` to where it is needed. --- .forge-snapshots/SwapMath_oneForZero_exactInCapped.snap | 2 +- .forge-snapshots/SwapMath_oneForZero_exactInPartial.snap | 2 +- .forge-snapshots/SwapMath_oneForZero_exactOutCapped.snap | 2 +- .forge-snapshots/SwapMath_oneForZero_exactOutPartial.snap | 2 +- .forge-snapshots/SwapMath_zeroForOne_exactInCapped.snap | 2 +- .forge-snapshots/SwapMath_zeroForOne_exactInPartial.snap | 2 +- .forge-snapshots/SwapMath_zeroForOne_exactOutCapped.snap | 2 +- .forge-snapshots/SwapMath_zeroForOne_exactOutPartial.snap | 2 +- .forge-snapshots/poolManager bytecode size.snap | 2 +- .forge-snapshots/simple swap with native.snap | 2 +- .forge-snapshots/simple swap.snap | 2 +- .forge-snapshots/swap CA fee on unspecified.snap | 2 +- .../swap against liquidity with native token.snap | 2 +- .forge-snapshots/swap against liquidity.snap | 2 +- .forge-snapshots/swap burn 6909 for input.snap | 2 +- .forge-snapshots/swap burn native 6909 for input.snap | 2 +- .forge-snapshots/swap mint native output as 6909.snap | 2 +- .forge-snapshots/swap mint output as 6909.snap | 2 +- .forge-snapshots/swap skips hook call if hook is caller.snap | 2 +- .forge-snapshots/swap with dynamic fee.snap | 2 +- .forge-snapshots/swap with hooks.snap | 2 +- .forge-snapshots/swap with lp fee and protocol fee.snap | 2 +- .forge-snapshots/update dynamic fee in before swap.snap | 2 +- src/libraries/SwapMath.sol | 5 ++--- 24 files changed, 25 insertions(+), 26 deletions(-) diff --git a/.forge-snapshots/SwapMath_oneForZero_exactInCapped.snap b/.forge-snapshots/SwapMath_oneForZero_exactInCapped.snap index 7411188d9..6d92a178f 100644 --- a/.forge-snapshots/SwapMath_oneForZero_exactInCapped.snap +++ b/.forge-snapshots/SwapMath_oneForZero_exactInCapped.snap @@ -1 +1 @@ -1954 \ No newline at end of file +1953 \ No newline at end of file diff --git a/.forge-snapshots/SwapMath_oneForZero_exactInPartial.snap b/.forge-snapshots/SwapMath_oneForZero_exactInPartial.snap index b9dc6e979..3de003809 100644 --- a/.forge-snapshots/SwapMath_oneForZero_exactInPartial.snap +++ b/.forge-snapshots/SwapMath_oneForZero_exactInPartial.snap @@ -1 +1 @@ -2135 \ No newline at end of file +2134 \ No newline at end of file diff --git a/.forge-snapshots/SwapMath_oneForZero_exactOutCapped.snap b/.forge-snapshots/SwapMath_oneForZero_exactOutCapped.snap index a0ac2c52a..f0e160769 100644 --- a/.forge-snapshots/SwapMath_oneForZero_exactOutCapped.snap +++ b/.forge-snapshots/SwapMath_oneForZero_exactOutCapped.snap @@ -1 +1 @@ -1725 \ No newline at end of file +1717 \ No newline at end of file diff --git a/.forge-snapshots/SwapMath_oneForZero_exactOutPartial.snap b/.forge-snapshots/SwapMath_oneForZero_exactOutPartial.snap index 7a03b74c0..16cc9b98f 100644 --- a/.forge-snapshots/SwapMath_oneForZero_exactOutPartial.snap +++ b/.forge-snapshots/SwapMath_oneForZero_exactOutPartial.snap @@ -1 +1 @@ -2543 \ No newline at end of file +2535 \ No newline at end of file diff --git a/.forge-snapshots/SwapMath_zeroForOne_exactInCapped.snap b/.forge-snapshots/SwapMath_zeroForOne_exactInCapped.snap index 6c05f6d8d..803bfdebf 100644 --- a/.forge-snapshots/SwapMath_zeroForOne_exactInCapped.snap +++ b/.forge-snapshots/SwapMath_zeroForOne_exactInCapped.snap @@ -1 +1 @@ -1933 \ No newline at end of file +1932 \ No newline at end of file diff --git a/.forge-snapshots/SwapMath_zeroForOne_exactInPartial.snap b/.forge-snapshots/SwapMath_zeroForOne_exactInPartial.snap index 1003f2e0b..0748c0f7b 100644 --- a/.forge-snapshots/SwapMath_zeroForOne_exactInPartial.snap +++ b/.forge-snapshots/SwapMath_zeroForOne_exactInPartial.snap @@ -1 +1 @@ -2318 \ No newline at end of file +2317 \ No newline at end of file diff --git a/.forge-snapshots/SwapMath_zeroForOne_exactOutCapped.snap b/.forge-snapshots/SwapMath_zeroForOne_exactOutCapped.snap index dfd4d9fcd..98ced614c 100644 --- a/.forge-snapshots/SwapMath_zeroForOne_exactOutCapped.snap +++ b/.forge-snapshots/SwapMath_zeroForOne_exactOutCapped.snap @@ -1 +1 @@ -1704 \ No newline at end of file +1696 \ No newline at end of file diff --git a/.forge-snapshots/SwapMath_zeroForOne_exactOutPartial.snap b/.forge-snapshots/SwapMath_zeroForOne_exactOutPartial.snap index 3827a8bde..09bc6cfa4 100644 --- a/.forge-snapshots/SwapMath_zeroForOne_exactOutPartial.snap +++ b/.forge-snapshots/SwapMath_zeroForOne_exactOutPartial.snap @@ -1 +1 @@ -2132 \ No newline at end of file +2124 \ No newline at end of file diff --git a/.forge-snapshots/poolManager bytecode size.snap b/.forge-snapshots/poolManager bytecode size.snap index 2cc7a6354..0f9a26130 100644 --- a/.forge-snapshots/poolManager bytecode size.snap +++ b/.forge-snapshots/poolManager bytecode size.snap @@ -1 +1 @@ -21883 \ No newline at end of file +21878 \ No newline at end of file diff --git a/.forge-snapshots/simple swap with native.snap b/.forge-snapshots/simple swap with native.snap index 250e3372f..5480957c8 100644 --- a/.forge-snapshots/simple swap with native.snap +++ b/.forge-snapshots/simple swap with native.snap @@ -1 +1 @@ -115989 \ No newline at end of file +115987 \ No newline at end of file diff --git a/.forge-snapshots/simple swap.snap b/.forge-snapshots/simple swap.snap index 229f08f09..6772976dc 100644 --- a/.forge-snapshots/simple swap.snap +++ b/.forge-snapshots/simple swap.snap @@ -1 +1 @@ -131150 \ No newline at end of file +131148 \ No newline at end of file diff --git a/.forge-snapshots/swap CA fee on unspecified.snap b/.forge-snapshots/swap CA fee on unspecified.snap index 32546f653..36684438b 100644 --- a/.forge-snapshots/swap CA fee on unspecified.snap +++ b/.forge-snapshots/swap CA fee on unspecified.snap @@ -1 +1 @@ -182478 \ No newline at end of file +182476 \ No newline at end of file diff --git a/.forge-snapshots/swap against liquidity with native token.snap b/.forge-snapshots/swap against liquidity with native token.snap index fd3d36230..c17bd51fc 100644 --- a/.forge-snapshots/swap against liquidity with native token.snap +++ b/.forge-snapshots/swap against liquidity with native token.snap @@ -1 +1 @@ -111952 \ No newline at end of file +111951 \ No newline at end of file diff --git a/.forge-snapshots/swap against liquidity.snap b/.forge-snapshots/swap against liquidity.snap index 76f28034e..b60ccc134 100644 --- a/.forge-snapshots/swap against liquidity.snap +++ b/.forge-snapshots/swap against liquidity.snap @@ -1 +1 @@ -123295 \ No newline at end of file +123294 \ No newline at end of file diff --git a/.forge-snapshots/swap burn 6909 for input.snap b/.forge-snapshots/swap burn 6909 for input.snap index d1acfa1cd..fa579ffff 100644 --- a/.forge-snapshots/swap burn 6909 for input.snap +++ b/.forge-snapshots/swap burn 6909 for input.snap @@ -1 +1 @@ -135548 \ No newline at end of file +135540 \ No newline at end of file diff --git a/.forge-snapshots/swap burn native 6909 for input.snap b/.forge-snapshots/swap burn native 6909 for input.snap index 22a31ebea..2bae0f8b5 100644 --- a/.forge-snapshots/swap burn native 6909 for input.snap +++ b/.forge-snapshots/swap burn native 6909 for input.snap @@ -1 +1 @@ -124671 \ No newline at end of file +124663 \ No newline at end of file diff --git a/.forge-snapshots/swap mint native output as 6909.snap b/.forge-snapshots/swap mint native output as 6909.snap index 26907da9c..b886e81e6 100644 --- a/.forge-snapshots/swap mint native output as 6909.snap +++ b/.forge-snapshots/swap mint native output as 6909.snap @@ -1 +1 @@ -146575 \ No newline at end of file +146574 \ No newline at end of file diff --git a/.forge-snapshots/swap mint output as 6909.snap b/.forge-snapshots/swap mint output as 6909.snap index 26d94ea2f..822962fad 100644 --- a/.forge-snapshots/swap mint output as 6909.snap +++ b/.forge-snapshots/swap mint output as 6909.snap @@ -1 +1 @@ -163004 \ No newline at end of file +163002 \ No newline at end of file diff --git a/.forge-snapshots/swap skips hook call if hook is caller.snap b/.forge-snapshots/swap skips hook call if hook is caller.snap index 3151fb232..a54d8448c 100644 --- a/.forge-snapshots/swap skips hook call if hook is caller.snap +++ b/.forge-snapshots/swap skips hook call if hook is caller.snap @@ -1 +1 @@ -220801 \ No newline at end of file +220798 \ No newline at end of file diff --git a/.forge-snapshots/swap with dynamic fee.snap b/.forge-snapshots/swap with dynamic fee.snap index 57f454405..e78639248 100644 --- a/.forge-snapshots/swap with dynamic fee.snap +++ b/.forge-snapshots/swap with dynamic fee.snap @@ -1 +1 @@ -147205 \ No newline at end of file +147203 \ No newline at end of file diff --git a/.forge-snapshots/swap with hooks.snap b/.forge-snapshots/swap with hooks.snap index 2637d9508..eedf142b0 100644 --- a/.forge-snapshots/swap with hooks.snap +++ b/.forge-snapshots/swap with hooks.snap @@ -1 +1 @@ -123307 \ No newline at end of file +123306 \ No newline at end of file diff --git a/.forge-snapshots/swap with lp fee and protocol fee.snap b/.forge-snapshots/swap with lp fee and protocol fee.snap index 05ac16a2d..e9024ce4e 100644 --- a/.forge-snapshots/swap with lp fee and protocol fee.snap +++ b/.forge-snapshots/swap with lp fee and protocol fee.snap @@ -1 +1 @@ -179657 \ No newline at end of file +179641 \ No newline at end of file diff --git a/.forge-snapshots/update dynamic fee in before swap.snap b/.forge-snapshots/update dynamic fee in before swap.snap index 3b62c9807..57543f1c7 100644 --- a/.forge-snapshots/update dynamic fee in before swap.snap +++ b/.forge-snapshots/update dynamic fee in before swap.snap @@ -1 +1 @@ -157691 \ No newline at end of file +157689 \ No newline at end of file diff --git a/src/libraries/SwapMath.sol b/src/libraries/SwapMath.sol index d2702aa1b..f4a2805e8 100644 --- a/src/libraries/SwapMath.sol +++ b/src/libraries/SwapMath.sol @@ -53,14 +53,13 @@ library SwapMath { unchecked { uint256 _feePips = feePips; // cast once and cache bool zeroForOne = sqrtPriceCurrentX96 >= sqrtPriceTargetX96; - uint256 amountRemainingAbs; bool exactIn = amountRemaining < 0; if (!exactIn) { amountOut = zeroForOne ? SqrtPriceMath.getAmount1Delta(sqrtPriceTargetX96, sqrtPriceCurrentX96, liquidity, false) : SqrtPriceMath.getAmount0Delta(sqrtPriceCurrentX96, sqrtPriceTargetX96, liquidity, false); - amountRemainingAbs = uint256(amountRemaining); + uint256 amountRemainingAbs = uint256(amountRemaining); if (amountRemainingAbs >= amountOut) { // `amountOut` is capped by the target price sqrtPriceNextX96 = sqrtPriceTargetX96; @@ -76,7 +75,7 @@ library SwapMath { // `feePips` cannot be `MAX_FEE_PIPS` for exact out feeAmount = FullMath.mulDivRoundingUp(amountIn, _feePips, MAX_FEE_PIPS - _feePips); } else { - amountRemainingAbs = uint256(-amountRemaining); + uint256 amountRemainingAbs = uint256(-amountRemaining); uint256 amountRemainingLessFee = FullMath.mulDiv(amountRemainingAbs, MAX_FEE_PIPS - _feePips, MAX_FEE_PIPS); amountIn = zeroForOne From 2e350cff23f492a57ed3f8415b8a4e9afbfc8be9 Mon Sep 17 00:00:00 2001 From: Shuhui Luo <107524008+shuhuiluo@users.noreply.github.com> Date: Thu, 16 May 2024 23:05:47 -0400 Subject: [PATCH 08/16] Update test function to pure in SwapMath.t.sol --- test/libraries/SwapMath.t.sol | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/libraries/SwapMath.t.sol b/test/libraries/SwapMath.t.sol index b27f7d1df..192e0af0e 100644 --- a/test/libraries/SwapMath.t.sol +++ b/test/libraries/SwapMath.t.sol @@ -128,7 +128,7 @@ contract SwapMathTest is Test, GasSnapshot { assertEq(sqrtQ, 1); } - function test_notEntireInputAmountTakenAsFee() public { + function test_notEntireInputAmountTakenAsFee() public pure { (uint160 sqrtQ, uint256 amountIn, uint256 amountOut, uint256 feeAmount) = SwapMath.computeSwapStep(2413, 79887613182836312, 1985041575832132834610021537970, -10, 1872); From 842bda532f276ece9b7a2a04581c00b2aa16b046 Mon Sep 17 00:00:00 2001 From: Shuhui Luo <107524008+shuhuiluo@users.noreply.github.com> Date: Thu, 16 May 2024 23:35:32 -0400 Subject: [PATCH 09/16] Optimize `getSqrtPriceTarget` --- .forge-snapshots/poolManager bytecode size.snap | 2 +- .forge-snapshots/simple swap with native.snap | 2 +- .forge-snapshots/simple swap.snap | 2 +- .forge-snapshots/swap CA fee on unspecified.snap | 2 +- .../swap against liquidity with native token.snap | 2 +- .forge-snapshots/swap against liquidity.snap | 2 +- .forge-snapshots/swap burn 6909 for input.snap | 2 +- .forge-snapshots/swap burn native 6909 for input.snap | 2 +- .forge-snapshots/swap mint native output as 6909.snap | 2 +- .forge-snapshots/swap mint output as 6909.snap | 2 +- .../swap skips hook call if hook is caller.snap | 2 +- .forge-snapshots/swap with dynamic fee.snap | 2 +- .forge-snapshots/swap with hooks.snap | 2 +- .forge-snapshots/swap with lp fee and protocol fee.snap | 2 +- .forge-snapshots/update dynamic fee in before swap.snap | 2 +- src/libraries/SwapMath.sol | 6 +++--- 16 files changed, 18 insertions(+), 18 deletions(-) diff --git a/.forge-snapshots/poolManager bytecode size.snap b/.forge-snapshots/poolManager bytecode size.snap index 0f9a26130..a25db1515 100644 --- a/.forge-snapshots/poolManager bytecode size.snap +++ b/.forge-snapshots/poolManager bytecode size.snap @@ -1 +1 @@ -21878 \ No newline at end of file +21877 \ No newline at end of file diff --git a/.forge-snapshots/simple swap with native.snap b/.forge-snapshots/simple swap with native.snap index 5480957c8..dcf2b3dca 100644 --- a/.forge-snapshots/simple swap with native.snap +++ b/.forge-snapshots/simple swap with native.snap @@ -1 +1 @@ -115987 \ No newline at end of file +115981 \ No newline at end of file diff --git a/.forge-snapshots/simple swap.snap b/.forge-snapshots/simple swap.snap index 6772976dc..3b1e2098a 100644 --- a/.forge-snapshots/simple swap.snap +++ b/.forge-snapshots/simple swap.snap @@ -1 +1 @@ -131148 \ No newline at end of file +131142 \ No newline at end of file diff --git a/.forge-snapshots/swap CA fee on unspecified.snap b/.forge-snapshots/swap CA fee on unspecified.snap index 36684438b..fba424e3a 100644 --- a/.forge-snapshots/swap CA fee on unspecified.snap +++ b/.forge-snapshots/swap CA fee on unspecified.snap @@ -1 +1 @@ -182476 \ No newline at end of file +182470 \ No newline at end of file diff --git a/.forge-snapshots/swap against liquidity with native token.snap b/.forge-snapshots/swap against liquidity with native token.snap index c17bd51fc..a72b4a203 100644 --- a/.forge-snapshots/swap against liquidity with native token.snap +++ b/.forge-snapshots/swap against liquidity with native token.snap @@ -1 +1 @@ -111951 \ No newline at end of file +111948 \ No newline at end of file diff --git a/.forge-snapshots/swap against liquidity.snap b/.forge-snapshots/swap against liquidity.snap index b60ccc134..19ce7f3e2 100644 --- a/.forge-snapshots/swap against liquidity.snap +++ b/.forge-snapshots/swap against liquidity.snap @@ -1 +1 @@ -123294 \ No newline at end of file +123291 \ No newline at end of file diff --git a/.forge-snapshots/swap burn 6909 for input.snap b/.forge-snapshots/swap burn 6909 for input.snap index fa579ffff..84742bb8d 100644 --- a/.forge-snapshots/swap burn 6909 for input.snap +++ b/.forge-snapshots/swap burn 6909 for input.snap @@ -1 +1 @@ -135540 \ No newline at end of file +135537 \ No newline at end of file diff --git a/.forge-snapshots/swap burn native 6909 for input.snap b/.forge-snapshots/swap burn native 6909 for input.snap index 2bae0f8b5..a5f7c31ed 100644 --- a/.forge-snapshots/swap burn native 6909 for input.snap +++ b/.forge-snapshots/swap burn native 6909 for input.snap @@ -1 +1 @@ -124663 \ No newline at end of file +124660 \ No newline at end of file diff --git a/.forge-snapshots/swap mint native output as 6909.snap b/.forge-snapshots/swap mint native output as 6909.snap index b886e81e6..b1024199b 100644 --- a/.forge-snapshots/swap mint native output as 6909.snap +++ b/.forge-snapshots/swap mint native output as 6909.snap @@ -1 +1 @@ -146574 \ No newline at end of file +146571 \ No newline at end of file diff --git a/.forge-snapshots/swap mint output as 6909.snap b/.forge-snapshots/swap mint output as 6909.snap index 822962fad..679325a29 100644 --- a/.forge-snapshots/swap mint output as 6909.snap +++ b/.forge-snapshots/swap mint output as 6909.snap @@ -1 +1 @@ -163002 \ No newline at end of file +162996 \ No newline at end of file diff --git a/.forge-snapshots/swap skips hook call if hook is caller.snap b/.forge-snapshots/swap skips hook call if hook is caller.snap index a54d8448c..9b09c6289 100644 --- a/.forge-snapshots/swap skips hook call if hook is caller.snap +++ b/.forge-snapshots/swap skips hook call if hook is caller.snap @@ -1 +1 @@ -220798 \ No newline at end of file +220789 \ No newline at end of file diff --git a/.forge-snapshots/swap with dynamic fee.snap b/.forge-snapshots/swap with dynamic fee.snap index e78639248..9f7091417 100644 --- a/.forge-snapshots/swap with dynamic fee.snap +++ b/.forge-snapshots/swap with dynamic fee.snap @@ -1 +1 @@ -147203 \ No newline at end of file +147197 \ No newline at end of file diff --git a/.forge-snapshots/swap with hooks.snap b/.forge-snapshots/swap with hooks.snap index eedf142b0..e406c20b0 100644 --- a/.forge-snapshots/swap with hooks.snap +++ b/.forge-snapshots/swap with hooks.snap @@ -1 +1 @@ -123306 \ No newline at end of file +123303 \ No newline at end of file diff --git a/.forge-snapshots/swap with lp fee and protocol fee.snap b/.forge-snapshots/swap with lp fee and protocol fee.snap index e9024ce4e..b781a27ee 100644 --- a/.forge-snapshots/swap with lp fee and protocol fee.snap +++ b/.forge-snapshots/swap with lp fee and protocol fee.snap @@ -1 +1 @@ -179641 \ No newline at end of file +179635 \ No newline at end of file diff --git a/.forge-snapshots/update dynamic fee in before swap.snap b/.forge-snapshots/update dynamic fee in before swap.snap index 57543f1c7..eada4c68b 100644 --- a/.forge-snapshots/update dynamic fee in before swap.snap +++ b/.forge-snapshots/update dynamic fee in before swap.snap @@ -1 +1 @@ -157689 \ No newline at end of file +157683 \ No newline at end of file diff --git a/src/libraries/SwapMath.sol b/src/libraries/SwapMath.sol index f4a2805e8..752cff678 100644 --- a/src/libraries/SwapMath.sol +++ b/src/libraries/SwapMath.sol @@ -22,11 +22,11 @@ library SwapMath { { assembly { // a flag to toggle between sqrtPriceNextX96 and sqrtPriceLimitX96 - // when zeroForOne == true, nextOrLimit reduces to sqrtPriceNextX96 > sqrtPriceLimitX96 + // when zeroForOne == true, nextOrLimit reduces to sqrtPriceNextX96 >= sqrtPriceLimitX96 // sqrtPriceTargetX96 = max(sqrtPriceNextX96, sqrtPriceLimitX96) - // when zeroForOne == false, nextOrLimit reduces to sqrtPriceNextX96 <= sqrtPriceLimitX96 + // when zeroForOne == false, nextOrLimit reduces to sqrtPriceNextX96 < sqrtPriceLimitX96 // sqrtPriceTargetX96 = min(sqrtPriceNextX96, sqrtPriceLimitX96) - let nextOrLimit := xor(gt(sqrtPriceNextX96, sqrtPriceLimitX96), iszero(zeroForOne)) + let nextOrLimit := xor(lt(sqrtPriceNextX96, sqrtPriceLimitX96), zeroForOne) let symDiff := xor(sqrtPriceNextX96, sqrtPriceLimitX96) sqrtPriceTargetX96 := xor(sqrtPriceLimitX96, mul(symDiff, nextOrLimit)) } From 5a99fe00a2500097015a4191a3d9c4a39cd19e8b Mon Sep 17 00:00:00 2001 From: Shuhui Luo <107524008+shuhuiluo@users.noreply.github.com> Date: Tue, 21 May 2024 22:48:25 -0400 Subject: [PATCH 10/16] Switch if else blocks for ease of review --- .../SwapMath_oneForZero_exactInCapped.snap | 2 +- .../SwapMath_oneForZero_exactInPartial.snap | 2 +- .../SwapMath_oneForZero_exactOutCapped.snap | 2 +- .../SwapMath_oneForZero_exactOutPartial.snap | 2 +- .../SwapMath_zeroForOne_exactInCapped.snap | 2 +- .../SwapMath_zeroForOne_exactInPartial.snap | 2 +- .../SwapMath_zeroForOne_exactOutCapped.snap | 2 +- .../SwapMath_zeroForOne_exactOutPartial.snap | 2 +- .../poolManager bytecode size.snap | 2 +- .forge-snapshots/simple swap with native.snap | 2 +- .forge-snapshots/simple swap.snap | 2 +- .../swap CA fee on unspecified.snap | 2 +- ...p against liquidity with native token.snap | 2 +- .forge-snapshots/swap against liquidity.snap | 2 +- .../swap burn 6909 for input.snap | 2 +- .../swap burn native 6909 for input.snap | 2 +- .../swap mint native output as 6909.snap | 2 +- .../swap mint output as 6909.snap | 2 +- ...wap skips hook call if hook is caller.snap | 2 +- .forge-snapshots/swap with dynamic fee.snap | 2 +- .forge-snapshots/swap with hooks.snap | 2 +- .../swap with lp fee and protocol fee.snap | 2 +- .../swap with return dynamic fee.snap | 2 +- .../update dynamic fee in before swap.snap | 2 +- src/libraries/SwapMath.sol | 40 +++++++++---------- 25 files changed, 44 insertions(+), 44 deletions(-) diff --git a/.forge-snapshots/SwapMath_oneForZero_exactInCapped.snap b/.forge-snapshots/SwapMath_oneForZero_exactInCapped.snap index 203719af2..3a2ac0e3f 100644 --- a/.forge-snapshots/SwapMath_oneForZero_exactInCapped.snap +++ b/.forge-snapshots/SwapMath_oneForZero_exactInCapped.snap @@ -1 +1 @@ -1689 \ No newline at end of file +1701 \ No newline at end of file diff --git a/.forge-snapshots/SwapMath_oneForZero_exactInPartial.snap b/.forge-snapshots/SwapMath_oneForZero_exactInPartial.snap index b12aaf6b7..a13ad25b8 100644 --- a/.forge-snapshots/SwapMath_oneForZero_exactInPartial.snap +++ b/.forge-snapshots/SwapMath_oneForZero_exactInPartial.snap @@ -1 +1 @@ -1870 \ No newline at end of file +1883 \ No newline at end of file diff --git a/.forge-snapshots/SwapMath_oneForZero_exactOutCapped.snap b/.forge-snapshots/SwapMath_oneForZero_exactOutCapped.snap index 4541cc866..7f06f5c97 100644 --- a/.forge-snapshots/SwapMath_oneForZero_exactOutCapped.snap +++ b/.forge-snapshots/SwapMath_oneForZero_exactOutCapped.snap @@ -1 +1 @@ -1453 \ No newline at end of file +1445 \ No newline at end of file diff --git a/.forge-snapshots/SwapMath_oneForZero_exactOutPartial.snap b/.forge-snapshots/SwapMath_oneForZero_exactOutPartial.snap index 673819deb..a8964c48c 100644 --- a/.forge-snapshots/SwapMath_oneForZero_exactOutPartial.snap +++ b/.forge-snapshots/SwapMath_oneForZero_exactOutPartial.snap @@ -1 +1 @@ -2271 \ No newline at end of file +2262 \ No newline at end of file diff --git a/.forge-snapshots/SwapMath_zeroForOne_exactInCapped.snap b/.forge-snapshots/SwapMath_zeroForOne_exactInCapped.snap index a10e1ce09..02fa9676b 100644 --- a/.forge-snapshots/SwapMath_zeroForOne_exactInCapped.snap +++ b/.forge-snapshots/SwapMath_zeroForOne_exactInCapped.snap @@ -1 +1 @@ -1785 \ No newline at end of file +1797 \ No newline at end of file diff --git a/.forge-snapshots/SwapMath_zeroForOne_exactInPartial.snap b/.forge-snapshots/SwapMath_zeroForOne_exactInPartial.snap index a2cb5787f..fc1a81d9a 100644 --- a/.forge-snapshots/SwapMath_zeroForOne_exactInPartial.snap +++ b/.forge-snapshots/SwapMath_zeroForOne_exactInPartial.snap @@ -1 +1 @@ -2170 \ No newline at end of file +2182 \ No newline at end of file diff --git a/.forge-snapshots/SwapMath_zeroForOne_exactOutCapped.snap b/.forge-snapshots/SwapMath_zeroForOne_exactOutCapped.snap index d10f97d90..3ef08c825 100644 --- a/.forge-snapshots/SwapMath_zeroForOne_exactOutCapped.snap +++ b/.forge-snapshots/SwapMath_zeroForOne_exactOutCapped.snap @@ -1 +1 @@ -1549 \ No newline at end of file +1541 \ No newline at end of file diff --git a/.forge-snapshots/SwapMath_zeroForOne_exactOutPartial.snap b/.forge-snapshots/SwapMath_zeroForOne_exactOutPartial.snap index ca9836afa..14d9c9090 100644 --- a/.forge-snapshots/SwapMath_zeroForOne_exactOutPartial.snap +++ b/.forge-snapshots/SwapMath_zeroForOne_exactOutPartial.snap @@ -1 +1 @@ -1977 \ No newline at end of file +1969 \ No newline at end of file diff --git a/.forge-snapshots/poolManager bytecode size.snap b/.forge-snapshots/poolManager bytecode size.snap index 61ab682db..9fa7c5aff 100644 --- a/.forge-snapshots/poolManager bytecode size.snap +++ b/.forge-snapshots/poolManager bytecode size.snap @@ -1 +1 @@ -21185 \ No newline at end of file +21186 \ No newline at end of file diff --git a/.forge-snapshots/simple swap with native.snap b/.forge-snapshots/simple swap with native.snap index a6e6331a1..d8c96f408 100644 --- a/.forge-snapshots/simple swap with native.snap +++ b/.forge-snapshots/simple swap with native.snap @@ -1 +1 @@ -114632 \ No newline at end of file +114669 \ No newline at end of file diff --git a/.forge-snapshots/simple swap.snap b/.forge-snapshots/simple swap.snap index 2595b6a71..665eb8ceb 100644 --- a/.forge-snapshots/simple swap.snap +++ b/.forge-snapshots/simple swap.snap @@ -1 +1 @@ -129793 \ No newline at end of file +129830 \ No newline at end of file diff --git a/.forge-snapshots/swap CA fee on unspecified.snap b/.forge-snapshots/swap CA fee on unspecified.snap index 20b5bfa3d..670b129be 100644 --- a/.forge-snapshots/swap CA fee on unspecified.snap +++ b/.forge-snapshots/swap CA fee on unspecified.snap @@ -1 +1 @@ -180931 \ No newline at end of file +180968 \ No newline at end of file diff --git a/.forge-snapshots/swap against liquidity with native token.snap b/.forge-snapshots/swap against liquidity with native token.snap index 1ac68cc9c..9dcb335d0 100644 --- a/.forge-snapshots/swap against liquidity with native token.snap +++ b/.forge-snapshots/swap against liquidity with native token.snap @@ -1 +1 @@ -111038 \ No newline at end of file +111062 \ No newline at end of file diff --git a/.forge-snapshots/swap against liquidity.snap b/.forge-snapshots/swap against liquidity.snap index e40c33371..c789c63b8 100644 --- a/.forge-snapshots/swap against liquidity.snap +++ b/.forge-snapshots/swap against liquidity.snap @@ -1 +1 @@ -122381 \ No newline at end of file +122405 \ No newline at end of file diff --git a/.forge-snapshots/swap burn 6909 for input.snap b/.forge-snapshots/swap burn 6909 for input.snap index 1dcfbe88d..e782a4614 100644 --- a/.forge-snapshots/swap burn 6909 for input.snap +++ b/.forge-snapshots/swap burn 6909 for input.snap @@ -1 +1 @@ -134449 \ No newline at end of file +134442 \ No newline at end of file diff --git a/.forge-snapshots/swap burn native 6909 for input.snap b/.forge-snapshots/swap burn native 6909 for input.snap index f92b7d52e..5555af176 100644 --- a/.forge-snapshots/swap burn native 6909 for input.snap +++ b/.forge-snapshots/swap burn native 6909 for input.snap @@ -1 +1 @@ -123824 \ No newline at end of file +123806 \ No newline at end of file diff --git a/.forge-snapshots/swap mint native output as 6909.snap b/.forge-snapshots/swap mint native output as 6909.snap index c33c96a34..ecd0fc69e 100644 --- a/.forge-snapshots/swap mint native output as 6909.snap +++ b/.forge-snapshots/swap mint native output as 6909.snap @@ -1 +1 @@ -145551 \ No newline at end of file +145564 \ No newline at end of file diff --git a/.forge-snapshots/swap mint output as 6909.snap b/.forge-snapshots/swap mint output as 6909.snap index 0d8861d53..de0ba9ed9 100644 --- a/.forge-snapshots/swap mint output as 6909.snap +++ b/.forge-snapshots/swap mint output as 6909.snap @@ -1 +1 @@ -161647 \ No newline at end of file +161684 \ No newline at end of file diff --git a/.forge-snapshots/swap skips hook call if hook is caller.snap b/.forge-snapshots/swap skips hook call if hook is caller.snap index 70ddbaab3..77772e46a 100644 --- a/.forge-snapshots/swap skips hook call if hook is caller.snap +++ b/.forge-snapshots/swap skips hook call if hook is caller.snap @@ -1 +1 @@ -218494 \ No newline at end of file +218555 \ No newline at end of file diff --git a/.forge-snapshots/swap with dynamic fee.snap b/.forge-snapshots/swap with dynamic fee.snap index 0cf272d64..86ab0cdfb 100644 --- a/.forge-snapshots/swap with dynamic fee.snap +++ b/.forge-snapshots/swap with dynamic fee.snap @@ -1 +1 @@ -145848 \ No newline at end of file +145885 \ No newline at end of file diff --git a/.forge-snapshots/swap with hooks.snap b/.forge-snapshots/swap with hooks.snap index 3deec0b10..16e68302f 100644 --- a/.forge-snapshots/swap with hooks.snap +++ b/.forge-snapshots/swap with hooks.snap @@ -1 +1 @@ -122393 \ No newline at end of file +122417 \ No newline at end of file diff --git a/.forge-snapshots/swap with lp fee and protocol fee.snap b/.forge-snapshots/swap with lp fee and protocol fee.snap index b87b04d0e..3dde2e7dc 100644 --- a/.forge-snapshots/swap with lp fee and protocol fee.snap +++ b/.forge-snapshots/swap with lp fee and protocol fee.snap @@ -1 +1 @@ -178211 \ No newline at end of file +178186 \ No newline at end of file diff --git a/.forge-snapshots/swap with return dynamic fee.snap b/.forge-snapshots/swap with return dynamic fee.snap index 4f831f45d..7d481faff 100644 --- a/.forge-snapshots/swap with return dynamic fee.snap +++ b/.forge-snapshots/swap with return dynamic fee.snap @@ -1 +1 @@ -153707 \ No newline at end of file +153744 \ No newline at end of file diff --git a/.forge-snapshots/update dynamic fee in before swap.snap b/.forge-snapshots/update dynamic fee in before swap.snap index 2148ae054..7e668f089 100644 --- a/.forge-snapshots/update dynamic fee in before swap.snap +++ b/.forge-snapshots/update dynamic fee in before swap.snap @@ -1 +1 @@ -156310 \ No newline at end of file +156347 \ No newline at end of file diff --git a/src/libraries/SwapMath.sol b/src/libraries/SwapMath.sol index f3daaf9f9..b413f14eb 100644 --- a/src/libraries/SwapMath.sol +++ b/src/libraries/SwapMath.sol @@ -55,26 +55,7 @@ library SwapMath { bool zeroForOne = sqrtPriceCurrentX96 >= sqrtPriceTargetX96; bool exactIn = amountRemaining < 0; - if (!exactIn) { - amountOut = zeroForOne - ? SqrtPriceMath.getAmount1Delta(sqrtPriceTargetX96, sqrtPriceCurrentX96, liquidity, false) - : SqrtPriceMath.getAmount0Delta(sqrtPriceCurrentX96, sqrtPriceTargetX96, liquidity, false); - uint256 amountRemainingAbs = uint256(amountRemaining); - if (amountRemainingAbs >= amountOut) { - // `amountOut` is capped by the target price - sqrtPriceNextX96 = sqrtPriceTargetX96; - } else { - // cap the output amount to not exceed the remaining output amount - amountOut = amountRemainingAbs; - sqrtPriceNextX96 = - SqrtPriceMath.getNextSqrtPriceFromOutput(sqrtPriceCurrentX96, liquidity, amountOut, zeroForOne); - } - amountIn = zeroForOne - ? SqrtPriceMath.getAmount0Delta(sqrtPriceNextX96, sqrtPriceCurrentX96, liquidity, true) - : SqrtPriceMath.getAmount1Delta(sqrtPriceCurrentX96, sqrtPriceNextX96, liquidity, true); - // `feePips` cannot be `MAX_FEE_PIPS` for exact out - feeAmount = FullMath.mulDivRoundingUp(amountIn, _feePips, MAX_FEE_PIPS - _feePips); - } else { + if (exactIn) { uint256 amountRemainingAbs = uint256(-amountRemaining); uint256 amountRemainingLessFee = FullMath.mulDiv(amountRemainingAbs, MAX_FEE_PIPS - _feePips, MAX_FEE_PIPS); @@ -98,6 +79,25 @@ library SwapMath { amountOut = zeroForOne ? SqrtPriceMath.getAmount1Delta(sqrtPriceNextX96, sqrtPriceCurrentX96, liquidity, false) : SqrtPriceMath.getAmount0Delta(sqrtPriceCurrentX96, sqrtPriceNextX96, liquidity, false); + } else { + amountOut = zeroForOne + ? SqrtPriceMath.getAmount1Delta(sqrtPriceTargetX96, sqrtPriceCurrentX96, liquidity, false) + : SqrtPriceMath.getAmount0Delta(sqrtPriceCurrentX96, sqrtPriceTargetX96, liquidity, false); + uint256 amountRemainingAbs = uint256(amountRemaining); + if (amountRemainingAbs >= amountOut) { + // `amountOut` is capped by the target price + sqrtPriceNextX96 = sqrtPriceTargetX96; + } else { + // cap the output amount to not exceed the remaining output amount + amountOut = amountRemainingAbs; + sqrtPriceNextX96 = + SqrtPriceMath.getNextSqrtPriceFromOutput(sqrtPriceCurrentX96, liquidity, amountOut, zeroForOne); + } + amountIn = zeroForOne + ? SqrtPriceMath.getAmount0Delta(sqrtPriceNextX96, sqrtPriceCurrentX96, liquidity, true) + : SqrtPriceMath.getAmount1Delta(sqrtPriceCurrentX96, sqrtPriceNextX96, liquidity, true); + // `feePips` cannot be `MAX_FEE_PIPS` for exact out + feeAmount = FullMath.mulDivRoundingUp(amountIn, _feePips, MAX_FEE_PIPS - _feePips); } } } From 41788159dc05d999d0a3a65b1b946f8dbf3a4c81 Mon Sep 17 00:00:00 2001 From: Shuhui Luo <107524008+shuhuiluo@users.noreply.github.com> Date: Tue, 21 May 2024 23:15:26 -0400 Subject: [PATCH 11/16] Refactor and reduce diffs --- .../SwapMath_oneForZero_exactOutCapped.snap | 2 +- .../SwapMath_oneForZero_exactOutPartial.snap | 2 +- .../SwapMath_zeroForOne_exactOutCapped.snap | 2 +- .../SwapMath_zeroForOne_exactOutPartial.snap | 2 +- .forge-snapshots/poolManager bytecode size.snap | 2 +- .forge-snapshots/swap burn 6909 for input.snap | 2 +- .../swap burn native 6909 for input.snap | 2 +- .../swap with lp fee and protocol fee.snap | 2 +- src/libraries/SwapMath.sol | 15 ++++++++------- 9 files changed, 16 insertions(+), 15 deletions(-) diff --git a/.forge-snapshots/SwapMath_oneForZero_exactOutCapped.snap b/.forge-snapshots/SwapMath_oneForZero_exactOutCapped.snap index 7f06f5c97..eeced4b42 100644 --- a/.forge-snapshots/SwapMath_oneForZero_exactOutCapped.snap +++ b/.forge-snapshots/SwapMath_oneForZero_exactOutCapped.snap @@ -1 +1 @@ -1445 \ No newline at end of file +1440 \ No newline at end of file diff --git a/.forge-snapshots/SwapMath_oneForZero_exactOutPartial.snap b/.forge-snapshots/SwapMath_oneForZero_exactOutPartial.snap index a8964c48c..b982c73c8 100644 --- a/.forge-snapshots/SwapMath_oneForZero_exactOutPartial.snap +++ b/.forge-snapshots/SwapMath_oneForZero_exactOutPartial.snap @@ -1 +1 @@ -2262 \ No newline at end of file +2257 \ No newline at end of file diff --git a/.forge-snapshots/SwapMath_zeroForOne_exactOutCapped.snap b/.forge-snapshots/SwapMath_zeroForOne_exactOutCapped.snap index 3ef08c825..aa8f5c860 100644 --- a/.forge-snapshots/SwapMath_zeroForOne_exactOutCapped.snap +++ b/.forge-snapshots/SwapMath_zeroForOne_exactOutCapped.snap @@ -1 +1 @@ -1541 \ No newline at end of file +1536 \ No newline at end of file diff --git a/.forge-snapshots/SwapMath_zeroForOne_exactOutPartial.snap b/.forge-snapshots/SwapMath_zeroForOne_exactOutPartial.snap index 14d9c9090..465e07681 100644 --- a/.forge-snapshots/SwapMath_zeroForOne_exactOutPartial.snap +++ b/.forge-snapshots/SwapMath_zeroForOne_exactOutPartial.snap @@ -1 +1 @@ -1969 \ No newline at end of file +1964 \ No newline at end of file diff --git a/.forge-snapshots/poolManager bytecode size.snap b/.forge-snapshots/poolManager bytecode size.snap index 9fa7c5aff..f32c7b0c2 100644 --- a/.forge-snapshots/poolManager bytecode size.snap +++ b/.forge-snapshots/poolManager bytecode size.snap @@ -1 +1 @@ -21186 \ No newline at end of file +21184 \ No newline at end of file diff --git a/.forge-snapshots/swap burn 6909 for input.snap b/.forge-snapshots/swap burn 6909 for input.snap index e782a4614..3f047c94b 100644 --- a/.forge-snapshots/swap burn 6909 for input.snap +++ b/.forge-snapshots/swap burn 6909 for input.snap @@ -1 +1 @@ -134442 \ No newline at end of file +134437 \ No newline at end of file diff --git a/.forge-snapshots/swap burn native 6909 for input.snap b/.forge-snapshots/swap burn native 6909 for input.snap index 5555af176..3a68556fa 100644 --- a/.forge-snapshots/swap burn native 6909 for input.snap +++ b/.forge-snapshots/swap burn native 6909 for input.snap @@ -1 +1 @@ -123806 \ No newline at end of file +123801 \ No newline at end of file diff --git a/.forge-snapshots/swap with lp fee and protocol fee.snap b/.forge-snapshots/swap with lp fee and protocol fee.snap index 3dde2e7dc..326841103 100644 --- a/.forge-snapshots/swap with lp fee and protocol fee.snap +++ b/.forge-snapshots/swap with lp fee and protocol fee.snap @@ -1 +1 @@ -178186 \ No newline at end of file +178176 \ No newline at end of file diff --git a/src/libraries/SwapMath.sol b/src/libraries/SwapMath.sol index b413f14eb..7a8291ccc 100644 --- a/src/libraries/SwapMath.sol +++ b/src/libraries/SwapMath.sol @@ -71,8 +71,9 @@ library SwapMath { } else { // exhaust the remaining amount amountIn = amountRemainingLessFee; - sqrtPriceNextX96 = - SqrtPriceMath.getNextSqrtPriceFromInput(sqrtPriceCurrentX96, liquidity, amountIn, zeroForOne); + sqrtPriceNextX96 = SqrtPriceMath.getNextSqrtPriceFromInput( + sqrtPriceCurrentX96, liquidity, amountRemainingLessFee, zeroForOne + ); // we didn't reach the target, so take the remainder of the maximum input as fee feeAmount = amountRemainingAbs - amountIn; } @@ -83,15 +84,15 @@ library SwapMath { amountOut = zeroForOne ? SqrtPriceMath.getAmount1Delta(sqrtPriceTargetX96, sqrtPriceCurrentX96, liquidity, false) : SqrtPriceMath.getAmount0Delta(sqrtPriceCurrentX96, sqrtPriceTargetX96, liquidity, false); - uint256 amountRemainingAbs = uint256(amountRemaining); - if (amountRemainingAbs >= amountOut) { + if (uint256(amountRemaining) >= amountOut) { // `amountOut` is capped by the target price sqrtPriceNextX96 = sqrtPriceTargetX96; } else { // cap the output amount to not exceed the remaining output amount - amountOut = amountRemainingAbs; - sqrtPriceNextX96 = - SqrtPriceMath.getNextSqrtPriceFromOutput(sqrtPriceCurrentX96, liquidity, amountOut, zeroForOne); + amountOut = uint256(amountRemaining); + sqrtPriceNextX96 = SqrtPriceMath.getNextSqrtPriceFromOutput( + sqrtPriceCurrentX96, liquidity, uint256(amountRemaining), zeroForOne + ); } amountIn = zeroForOne ? SqrtPriceMath.getAmount0Delta(sqrtPriceNextX96, sqrtPriceCurrentX96, liquidity, true) From bd41a45cf8eaf57669426c7f2fa366aed9a38b9e Mon Sep 17 00:00:00 2001 From: Shuhui Luo <107524008+shuhuiluo@users.noreply.github.com> Date: Wed, 22 May 2024 01:19:00 -0400 Subject: [PATCH 12/16] Recompute `amountIn` when it's capped by `amountRemaining` instead of the target price for `exactIn` to achieve equivalence with V3 --- .forge-snapshots/SwapMath_oneForZero_exactInPartial.snap | 2 +- .forge-snapshots/SwapMath_zeroForOne_exactInPartial.snap | 2 +- .forge-snapshots/poolManager bytecode size.snap | 2 +- .forge-snapshots/simple swap with native.snap | 2 +- .forge-snapshots/simple swap.snap | 2 +- .forge-snapshots/swap CA fee on unspecified.snap | 2 +- .../swap against liquidity with native token.snap | 2 +- .forge-snapshots/swap against liquidity.snap | 2 +- .forge-snapshots/swap mint native output as 6909.snap | 2 +- .forge-snapshots/swap mint output as 6909.snap | 2 +- .../swap skips hook call if hook is caller.snap | 2 +- .forge-snapshots/swap with dynamic fee.snap | 2 +- .forge-snapshots/swap with hooks.snap | 2 +- .forge-snapshots/swap with return dynamic fee.snap | 2 +- .forge-snapshots/update dynamic fee in before swap.snap | 2 +- src/libraries/SwapMath.sol | 5 +++-- test/libraries/SwapMath.t.sol | 6 +++--- 17 files changed, 21 insertions(+), 20 deletions(-) diff --git a/.forge-snapshots/SwapMath_oneForZero_exactInPartial.snap b/.forge-snapshots/SwapMath_oneForZero_exactInPartial.snap index a13ad25b8..9eca385b3 100644 --- a/.forge-snapshots/SwapMath_oneForZero_exactInPartial.snap +++ b/.forge-snapshots/SwapMath_oneForZero_exactInPartial.snap @@ -1 +1 @@ -1883 \ No newline at end of file +2237 \ No newline at end of file diff --git a/.forge-snapshots/SwapMath_zeroForOne_exactInPartial.snap b/.forge-snapshots/SwapMath_zeroForOne_exactInPartial.snap index fc1a81d9a..5bbf63553 100644 --- a/.forge-snapshots/SwapMath_zeroForOne_exactInPartial.snap +++ b/.forge-snapshots/SwapMath_zeroForOne_exactInPartial.snap @@ -1 +1 @@ -2182 \ No newline at end of file +2781 \ No newline at end of file diff --git a/.forge-snapshots/poolManager bytecode size.snap b/.forge-snapshots/poolManager bytecode size.snap index f32c7b0c2..317a0d416 100644 --- a/.forge-snapshots/poolManager bytecode size.snap +++ b/.forge-snapshots/poolManager bytecode size.snap @@ -1 +1 @@ -21184 \ No newline at end of file +21219 \ No newline at end of file diff --git a/.forge-snapshots/simple swap with native.snap b/.forge-snapshots/simple swap with native.snap index d8c96f408..ae4d12614 100644 --- a/.forge-snapshots/simple swap with native.snap +++ b/.forge-snapshots/simple swap with native.snap @@ -1 +1 @@ -114669 \ No newline at end of file +115268 \ No newline at end of file diff --git a/.forge-snapshots/simple swap.snap b/.forge-snapshots/simple swap.snap index 665eb8ceb..44f2d6cf3 100644 --- a/.forge-snapshots/simple swap.snap +++ b/.forge-snapshots/simple swap.snap @@ -1 +1 @@ -129830 \ No newline at end of file +130429 \ No newline at end of file diff --git a/.forge-snapshots/swap CA fee on unspecified.snap b/.forge-snapshots/swap CA fee on unspecified.snap index 670b129be..ad67d1822 100644 --- a/.forge-snapshots/swap CA fee on unspecified.snap +++ b/.forge-snapshots/swap CA fee on unspecified.snap @@ -1 +1 @@ -180968 \ No newline at end of file +181567 \ No newline at end of file diff --git a/.forge-snapshots/swap against liquidity with native token.snap b/.forge-snapshots/swap against liquidity with native token.snap index 9dcb335d0..9c4558df3 100644 --- a/.forge-snapshots/swap against liquidity with native token.snap +++ b/.forge-snapshots/swap against liquidity with native token.snap @@ -1 +1 @@ -111062 \ No newline at end of file +111691 \ No newline at end of file diff --git a/.forge-snapshots/swap against liquidity.snap b/.forge-snapshots/swap against liquidity.snap index c789c63b8..507a259c4 100644 --- a/.forge-snapshots/swap against liquidity.snap +++ b/.forge-snapshots/swap against liquidity.snap @@ -1 +1 @@ -122405 \ No newline at end of file +123034 \ No newline at end of file diff --git a/.forge-snapshots/swap mint native output as 6909.snap b/.forge-snapshots/swap mint native output as 6909.snap index ecd0fc69e..56744f069 100644 --- a/.forge-snapshots/swap mint native output as 6909.snap +++ b/.forge-snapshots/swap mint native output as 6909.snap @@ -1 +1 @@ -145564 \ No newline at end of file +145918 \ No newline at end of file diff --git a/.forge-snapshots/swap mint output as 6909.snap b/.forge-snapshots/swap mint output as 6909.snap index de0ba9ed9..e5b71baf7 100644 --- a/.forge-snapshots/swap mint output as 6909.snap +++ b/.forge-snapshots/swap mint output as 6909.snap @@ -1 +1 @@ -161684 \ No newline at end of file +162283 \ No newline at end of file diff --git a/.forge-snapshots/swap skips hook call if hook is caller.snap b/.forge-snapshots/swap skips hook call if hook is caller.snap index 77772e46a..5a806c8ba 100644 --- a/.forge-snapshots/swap skips hook call if hook is caller.snap +++ b/.forge-snapshots/swap skips hook call if hook is caller.snap @@ -1 +1 @@ -218555 \ No newline at end of file +219783 \ No newline at end of file diff --git a/.forge-snapshots/swap with dynamic fee.snap b/.forge-snapshots/swap with dynamic fee.snap index 86ab0cdfb..7e48a2479 100644 --- a/.forge-snapshots/swap with dynamic fee.snap +++ b/.forge-snapshots/swap with dynamic fee.snap @@ -1 +1 @@ -145885 \ No newline at end of file +146484 \ No newline at end of file diff --git a/.forge-snapshots/swap with hooks.snap b/.forge-snapshots/swap with hooks.snap index 16e68302f..727f14edf 100644 --- a/.forge-snapshots/swap with hooks.snap +++ b/.forge-snapshots/swap with hooks.snap @@ -1 +1 @@ -122417 \ No newline at end of file +123046 \ No newline at end of file diff --git a/.forge-snapshots/swap with return dynamic fee.snap b/.forge-snapshots/swap with return dynamic fee.snap index 7d481faff..68b7b0581 100644 --- a/.forge-snapshots/swap with return dynamic fee.snap +++ b/.forge-snapshots/swap with return dynamic fee.snap @@ -1 +1 @@ -153744 \ No newline at end of file +154343 \ No newline at end of file diff --git a/.forge-snapshots/update dynamic fee in before swap.snap b/.forge-snapshots/update dynamic fee in before swap.snap index 7e668f089..3661579fa 100644 --- a/.forge-snapshots/update dynamic fee in before swap.snap +++ b/.forge-snapshots/update dynamic fee in before swap.snap @@ -1 +1 @@ -156347 \ No newline at end of file +156946 \ No newline at end of file diff --git a/src/libraries/SwapMath.sol b/src/libraries/SwapMath.sol index 7a8291ccc..4a434f8c5 100644 --- a/src/libraries/SwapMath.sol +++ b/src/libraries/SwapMath.sol @@ -69,11 +69,12 @@ library SwapMath { ? amountIn : FullMath.mulDivRoundingUp(amountIn, _feePips, MAX_FEE_PIPS - _feePips); } else { - // exhaust the remaining amount - amountIn = amountRemainingLessFee; sqrtPriceNextX96 = SqrtPriceMath.getNextSqrtPriceFromInput( sqrtPriceCurrentX96, liquidity, amountRemainingLessFee, zeroForOne ); + amountIn = zeroForOne + ? SqrtPriceMath.getAmount0Delta(sqrtPriceNextX96, sqrtPriceCurrentX96, liquidity, true) + : SqrtPriceMath.getAmount1Delta(sqrtPriceCurrentX96, sqrtPriceNextX96, liquidity, true); // we didn't reach the target, so take the remainder of the maximum input as fee feeAmount = amountRemainingAbs - amountIn; } diff --git a/test/libraries/SwapMath.t.sol b/test/libraries/SwapMath.t.sol index 1477f4dcc..043931869 100644 --- a/test/libraries/SwapMath.t.sol +++ b/test/libraries/SwapMath.t.sol @@ -140,12 +140,12 @@ contract SwapMathTest is Test, GasSnapshot { assertEq(sqrtQ, 1); } - function test_computeSwapStep_notEntireInputAmountTakenAsFee() public pure { + function test_computeSwapStep_entireInputAmountTakenAsFee() public pure { (uint160 sqrtQ, uint256 amountIn, uint256 amountOut, uint256 feeAmount) = SwapMath.computeSwapStep(2413, 79887613182836312, 1985041575832132834610021537970, -10, 1872); - assertEq(amountIn, 9); - assertEq(feeAmount, 1); + assertEq(amountIn, 0); + assertEq(feeAmount, 10); assertEq(amountOut, 0); assertEq(sqrtQ, 2413); } From cde8e3a0a4266f1103bb619dd778d0420413a125 Mon Sep 17 00:00:00 2001 From: Shuhui Luo <107524008+shuhuiluo@users.noreply.github.com> Date: Wed, 22 May 2024 02:00:20 -0400 Subject: [PATCH 13/16] Remove `amountRemainingAbs` --- .forge-snapshots/SwapMath_oneForZero_exactInCapped.snap | 2 +- .forge-snapshots/SwapMath_oneForZero_exactInPartial.snap | 2 +- .forge-snapshots/SwapMath_zeroForOne_exactInCapped.snap | 2 +- .forge-snapshots/SwapMath_zeroForOne_exactInPartial.snap | 2 +- .forge-snapshots/poolManager bytecode size.snap | 2 +- .forge-snapshots/simple swap with native.snap | 2 +- .forge-snapshots/simple swap.snap | 2 +- .forge-snapshots/swap CA fee on unspecified.snap | 2 +- .../swap against liquidity with native token.snap | 2 +- .forge-snapshots/swap against liquidity.snap | 2 +- .forge-snapshots/swap mint native output as 6909.snap | 2 +- .forge-snapshots/swap mint output as 6909.snap | 2 +- .forge-snapshots/swap skips hook call if hook is caller.snap | 2 +- .forge-snapshots/swap with dynamic fee.snap | 2 +- .forge-snapshots/swap with hooks.snap | 2 +- .forge-snapshots/swap with return dynamic fee.snap | 2 +- .forge-snapshots/update dynamic fee in before swap.snap | 2 +- src/libraries/SwapMath.sol | 5 ++--- 18 files changed, 19 insertions(+), 20 deletions(-) diff --git a/.forge-snapshots/SwapMath_oneForZero_exactInCapped.snap b/.forge-snapshots/SwapMath_oneForZero_exactInCapped.snap index 3a2ac0e3f..203719af2 100644 --- a/.forge-snapshots/SwapMath_oneForZero_exactInCapped.snap +++ b/.forge-snapshots/SwapMath_oneForZero_exactInCapped.snap @@ -1 +1 @@ -1701 \ No newline at end of file +1689 \ No newline at end of file diff --git a/.forge-snapshots/SwapMath_oneForZero_exactInPartial.snap b/.forge-snapshots/SwapMath_oneForZero_exactInPartial.snap index 9eca385b3..65024880e 100644 --- a/.forge-snapshots/SwapMath_oneForZero_exactInPartial.snap +++ b/.forge-snapshots/SwapMath_oneForZero_exactInPartial.snap @@ -1 +1 @@ -2237 \ No newline at end of file +2230 \ No newline at end of file diff --git a/.forge-snapshots/SwapMath_zeroForOne_exactInCapped.snap b/.forge-snapshots/SwapMath_zeroForOne_exactInCapped.snap index 02fa9676b..a10e1ce09 100644 --- a/.forge-snapshots/SwapMath_zeroForOne_exactInCapped.snap +++ b/.forge-snapshots/SwapMath_zeroForOne_exactInCapped.snap @@ -1 +1 @@ -1797 \ No newline at end of file +1785 \ No newline at end of file diff --git a/.forge-snapshots/SwapMath_zeroForOne_exactInPartial.snap b/.forge-snapshots/SwapMath_zeroForOne_exactInPartial.snap index 5bbf63553..71c565cd0 100644 --- a/.forge-snapshots/SwapMath_zeroForOne_exactInPartial.snap +++ b/.forge-snapshots/SwapMath_zeroForOne_exactInPartial.snap @@ -1 +1 @@ -2781 \ No newline at end of file +2774 \ No newline at end of file diff --git a/.forge-snapshots/poolManager bytecode size.snap b/.forge-snapshots/poolManager bytecode size.snap index 317a0d416..c3463c282 100644 --- a/.forge-snapshots/poolManager bytecode size.snap +++ b/.forge-snapshots/poolManager bytecode size.snap @@ -1 +1 @@ -21219 \ No newline at end of file +21220 \ No newline at end of file diff --git a/.forge-snapshots/simple swap with native.snap b/.forge-snapshots/simple swap with native.snap index ae4d12614..2993078ca 100644 --- a/.forge-snapshots/simple swap with native.snap +++ b/.forge-snapshots/simple swap with native.snap @@ -1 +1 @@ -115268 \ No newline at end of file +115249 \ No newline at end of file diff --git a/.forge-snapshots/simple swap.snap b/.forge-snapshots/simple swap.snap index 44f2d6cf3..818306dda 100644 --- a/.forge-snapshots/simple swap.snap +++ b/.forge-snapshots/simple swap.snap @@ -1 +1 @@ -130429 \ No newline at end of file +130410 \ No newline at end of file diff --git a/.forge-snapshots/swap CA fee on unspecified.snap b/.forge-snapshots/swap CA fee on unspecified.snap index ad67d1822..563e60a5c 100644 --- a/.forge-snapshots/swap CA fee on unspecified.snap +++ b/.forge-snapshots/swap CA fee on unspecified.snap @@ -1 +1 @@ -181567 \ No newline at end of file +181548 \ No newline at end of file diff --git a/.forge-snapshots/swap against liquidity with native token.snap b/.forge-snapshots/swap against liquidity with native token.snap index 9c4558df3..013174808 100644 --- a/.forge-snapshots/swap against liquidity with native token.snap +++ b/.forge-snapshots/swap against liquidity with native token.snap @@ -1 +1 @@ -111691 \ No newline at end of file +111684 \ No newline at end of file diff --git a/.forge-snapshots/swap against liquidity.snap b/.forge-snapshots/swap against liquidity.snap index 507a259c4..92a8d91d8 100644 --- a/.forge-snapshots/swap against liquidity.snap +++ b/.forge-snapshots/swap against liquidity.snap @@ -1 +1 @@ -123034 \ No newline at end of file +123027 \ No newline at end of file diff --git a/.forge-snapshots/swap mint native output as 6909.snap b/.forge-snapshots/swap mint native output as 6909.snap index 56744f069..518c90533 100644 --- a/.forge-snapshots/swap mint native output as 6909.snap +++ b/.forge-snapshots/swap mint native output as 6909.snap @@ -1 +1 @@ -145918 \ No newline at end of file +145911 \ No newline at end of file diff --git a/.forge-snapshots/swap mint output as 6909.snap b/.forge-snapshots/swap mint output as 6909.snap index e5b71baf7..678c7848a 100644 --- a/.forge-snapshots/swap mint output as 6909.snap +++ b/.forge-snapshots/swap mint output as 6909.snap @@ -1 +1 @@ -162283 \ No newline at end of file +162264 \ No newline at end of file diff --git a/.forge-snapshots/swap skips hook call if hook is caller.snap b/.forge-snapshots/swap skips hook call if hook is caller.snap index 5a806c8ba..77d9a44be 100644 --- a/.forge-snapshots/swap skips hook call if hook is caller.snap +++ b/.forge-snapshots/swap skips hook call if hook is caller.snap @@ -1 +1 @@ -219783 \ No newline at end of file +219757 \ No newline at end of file diff --git a/.forge-snapshots/swap with dynamic fee.snap b/.forge-snapshots/swap with dynamic fee.snap index 7e48a2479..0e75008de 100644 --- a/.forge-snapshots/swap with dynamic fee.snap +++ b/.forge-snapshots/swap with dynamic fee.snap @@ -1 +1 @@ -146484 \ No newline at end of file +146465 \ No newline at end of file diff --git a/.forge-snapshots/swap with hooks.snap b/.forge-snapshots/swap with hooks.snap index 727f14edf..9780a6175 100644 --- a/.forge-snapshots/swap with hooks.snap +++ b/.forge-snapshots/swap with hooks.snap @@ -1 +1 @@ -123046 \ No newline at end of file +123039 \ No newline at end of file diff --git a/.forge-snapshots/swap with return dynamic fee.snap b/.forge-snapshots/swap with return dynamic fee.snap index 68b7b0581..4451d8889 100644 --- a/.forge-snapshots/swap with return dynamic fee.snap +++ b/.forge-snapshots/swap with return dynamic fee.snap @@ -1 +1 @@ -154343 \ No newline at end of file +154324 \ No newline at end of file diff --git a/.forge-snapshots/update dynamic fee in before swap.snap b/.forge-snapshots/update dynamic fee in before swap.snap index 3661579fa..8b3c91750 100644 --- a/.forge-snapshots/update dynamic fee in before swap.snap +++ b/.forge-snapshots/update dynamic fee in before swap.snap @@ -1 +1 @@ -156946 \ No newline at end of file +156927 \ No newline at end of file diff --git a/src/libraries/SwapMath.sol b/src/libraries/SwapMath.sol index 4a434f8c5..ec29a87f1 100644 --- a/src/libraries/SwapMath.sol +++ b/src/libraries/SwapMath.sol @@ -56,9 +56,8 @@ library SwapMath { bool exactIn = amountRemaining < 0; if (exactIn) { - uint256 amountRemainingAbs = uint256(-amountRemaining); uint256 amountRemainingLessFee = - FullMath.mulDiv(amountRemainingAbs, MAX_FEE_PIPS - _feePips, MAX_FEE_PIPS); + FullMath.mulDiv(uint256(-amountRemaining), MAX_FEE_PIPS - _feePips, MAX_FEE_PIPS); amountIn = zeroForOne ? SqrtPriceMath.getAmount0Delta(sqrtPriceTargetX96, sqrtPriceCurrentX96, liquidity, true) : SqrtPriceMath.getAmount1Delta(sqrtPriceCurrentX96, sqrtPriceTargetX96, liquidity, true); @@ -76,7 +75,7 @@ library SwapMath { ? SqrtPriceMath.getAmount0Delta(sqrtPriceNextX96, sqrtPriceCurrentX96, liquidity, true) : SqrtPriceMath.getAmount1Delta(sqrtPriceCurrentX96, sqrtPriceNextX96, liquidity, true); // we didn't reach the target, so take the remainder of the maximum input as fee - feeAmount = amountRemainingAbs - amountIn; + feeAmount = uint256(-amountRemaining) - amountIn; } amountOut = zeroForOne ? SqrtPriceMath.getAmount1Delta(sqrtPriceNextX96, sqrtPriceCurrentX96, liquidity, false) From eb154260865e379769ec60f8b11fc7b194aa22c6 Mon Sep 17 00:00:00 2001 From: Shuhui Luo <107524008+shuhuiluo@users.noreply.github.com> Date: Thu, 23 May 2024 19:52:15 -0400 Subject: [PATCH 14/16] Remove .gas-snapshot --- .gas-snapshot | 572 -------------------------------------------------- 1 file changed, 572 deletions(-) delete mode 100644 .gas-snapshot diff --git a/.gas-snapshot b/.gas-snapshot deleted file mode 100644 index d740e0bcd..000000000 --- a/.gas-snapshot +++ /dev/null @@ -1,572 +0,0 @@ -ERC6909ClaimsTest:testApprove() (gas: 60948) -ERC6909ClaimsTest:testApprove(address,uint256,uint256) (runs: 1000, μ: 56425, ~: 56621) -ERC6909ClaimsTest:testBurn() (gas: 91217) -ERC6909ClaimsTest:testBurn(address,uint256,uint256) (runs: 1000, μ: 77409, ~: 77501) -ERC6909ClaimsTest:testFailMintBalanceOverflow() (gas: 77254) -ERC6909ClaimsTest:testFailTransferBalanceOverflow() (gas: 181818) -ERC6909ClaimsTest:testFailTransferBalanceOverflow(address,address,uint256,uint256) (runs: 1000, μ: 185960, ~: 186072) -ERC6909ClaimsTest:testFailTransferBalanceUnderflow() (gas: 32579) -ERC6909ClaimsTest:testFailTransferBalanceUnderflow(address,address,uint256,uint256) (runs: 1000, μ: 36180, ~: 36202) -ERC6909ClaimsTest:testFailTransferFromBalanceOverflow() (gas: 181841) -ERC6909ClaimsTest:testFailTransferFromBalanceOverflow(address,address,uint256,uint256) (runs: 1000, μ: 187010, ~: 187294) -ERC6909ClaimsTest:testFailTransferFromBalanceUnderflow() (gas: 32622) -ERC6909ClaimsTest:testFailTransferFromBalanceUnderflow(address,address,uint256,uint256) (runs: 1000, μ: 36759, ~: 36855) -ERC6909ClaimsTest:testFailTransferFromNotAuthorized() (gas: 79400) -ERC6909ClaimsTest:testFailTransferFromNotAuthorized(address,address,uint256,uint256) (runs: 1000, μ: 86747, ~: 86855) -ERC6909ClaimsTest:testMint() (gas: 60994) -ERC6909ClaimsTest:testMint(address,uint256,uint256) (runs: 1000, μ: 56510, ~: 56706) -ERC6909ClaimsTest:testSetOperator() (gas: 55387) -ERC6909ClaimsTest:testSetOperator(address,bool) (runs: 1000, μ: 45375, ~: 36020) -ERC6909ClaimsTest:testTransfer() (gas: 115497) -ERC6909ClaimsTest:testTransfer(address,address,uint256,uint256,uint256) (runs: 1000, μ: 114310, ~: 115282) -ERC6909ClaimsTest:testTransferFromAsOperator() (gas: 164867) -ERC6909ClaimsTest:testTransferFromAsOperator(address,address,uint256,uint256,uint256) (runs: 1000, μ: 163836, ~: 164885) -ERC6909ClaimsTest:testTransferFromWithApproval() (gas: 172738) -ERC6909ClaimsTest:testTransferFromWithApproval(address,address,uint256,uint256,uint256) (runs: 1000, μ: 171567, ~: 173096) -ERC6909ClaimsTest:testTransferFromWithInfiniteApproval() (gas: 169887) -ERC6909ClaimsTest:testTransferFromWithInfiniteApproval(address,address,uint256,uint256,uint256) (runs: 1000, μ: 168920, ~: 169934) -ERC6909ClaimsTest:test_burnFrom_revertsWithNoApproval() (gas: 82889) -ERC6909ClaimsTest:test_burnFrom_withApproval(address,uint256,uint256,uint256) (runs: 1000, μ: 137321, ~: 132219) -ExtsloadTest:test_fuzz_extsload(uint256,uint256,bytes) (runs: 1000, μ: 1163358, ~: 1082927) -ExtsloadTest:test_load10_sparse() (gas: 28771) -FullMathTest:test_fuzz_mulDiv(uint256,uint256,uint256) (runs: 1000, μ: 7876, ~: 7676) -FullMathTest:test_fuzz_mulDivRoundingUp(uint256,uint256,uint256) (runs: 1000, μ: 8135, ~: 7940) -FullMathTest:test_fuzz_mulDivRoundingUp_revertsWith0Denominator(uint256,uint256) (runs: 1000, μ: 3282, ~: 3282) -FullMathTest:test_fuzz_mulDiv_revertsWith0Denominator(uint256,uint256) (runs: 1000, μ: 3253, ~: 3253) -FullMathTest:test_invariant_mulDiv(uint256,uint256,uint256) (runs: 1000, μ: 6323, ~: 6074) -FullMathTest:test_invariant_mulDivRounding(uint256,uint256,uint256) (runs: 1000, μ: 4990, ~: 4749) -FullMathTest:test_invariant_mulDivRoundingUp(uint256,uint256,uint256) (runs: 1000, μ: 7737, ~: 7329) -FullMathTest:test_mulDivRoundingUp_revertsIfMulDivOverflows256BitsAfterRoundingUp() (gas: 3622) -FullMathTest:test_mulDivRoundingUp_revertsIfMulDivOverflows256BitsAfterRoundingUpCase2() (gas: 3697) -FullMathTest:test_mulDivRoundingUp_validWithAllMaxInputs() (gas: 3723) -FullMathTest:test_mulDivRoundingUp_validWithNoPhantomOverflow() (gas: 3937) -FullMathTest:test_mulDivRoundingUp_validWithPhantomOverflow() (gas: 3963) -FullMathTest:test_mulDivRoundingUp_validWithPhantomOverflowRepeatingDecimal() (gas: 4163) -FullMathTest:test_mulDiv_phantomOverflowRepeatingDecimal() (gas: 3941) -FullMathTest:test_mulDiv_revertsIfOutputOverflows() (gas: 3184) -FullMathTest:test_mulDiv_revertsOverflowWithAllMaxInputs() (gas: 3304) -FullMathTest:test_mulDiv_revertsWithOverflowingNumeratorAndZeroDenominator() (gas: 3183) -FullMathTest:test_mulDiv_validAllMaxInputs() (gas: 3620) -FullMathTest:test_mulDiv_validWithPhantomOverflow() (gas: 4007) -FullMathTest:test_mulDiv_validWithoutPhantomOverflow() (gas: 3738) -FullMathTest:test_resultOverflows_helper() (gas: 9292) -HooksTest:testIsValidHookAddress_invalid_zeroAddressWithDynamicFee() (gas: 4097) -HooksTest:test_afterAddLiquidity_invalidReturn() (gas: 242061) -HooksTest:test_afterDonate_invalidReturn() (gas: 128253) -HooksTest:test_afterInitialize_invalidReturn() (gas: 138860) -HooksTest:test_afterRemoveLiquidity_invalidReturn() (gas: 419040) -HooksTest:test_afterSwap_invalidReturn() (gas: 179772) -HooksTest:test_beforeAddLiquidity_invalidReturn() (gas: 193622) -HooksTest:test_beforeAfterAddLiquidity_beforeAfterRemoveLiquidity_succeedsWithHook() (gas: 559510) -HooksTest:test_beforeAfterAddLiquidity_calledWithPositiveLiquidityDelta() (gas: 357836) -HooksTest:test_beforeAfterRemoveLiquidity_calledWithPositiveLiquidityDelta() (gas: 531621) -HooksTest:test_beforeAfterRemoveLiquidity_calledWithZeroLiquidityDelta() (gas: 554048) -HooksTest:test_beforeDonate_invalidReturn() (gas: 128252) -HooksTest:test_beforeInitialize_invalidReturn() (gas: 98359) -HooksTest:test_beforeRemoveLiquidity_invalidReturn() (gas: 371025) -HooksTest:test_beforeSwap_invalidReturn() (gas: 131035) -HooksTest:test_callHook_revertsWithBubbleUp() (gas: 147529) -HooksTest:test_callHook_revertsWithInternalErrorHookCallFailed() (gas: 524668) -HooksTest:test_donate_succeedsWithHook() (gas: 281752) -HooksTest:test_fuzz_isValidHookAddress_invalid_returnsDeltaWithoutHookFlag(uint160) (runs: 1000, μ: 9118, ~: 9118) -HooksTest:test_fuzz_validateHookAddress_failsAllHooks(uint160,uint16) (runs: 1000, μ: 9231, ~: 9192) -HooksTest:test_fuzz_validateHookAddress_failsNoHooks(uint160,uint16) (runs: 1000, μ: 9768, ~: 9677) -HooksTest:test_fuzz_validateHookPermissions_afterAddLiquidity(uint160) (runs: 1000, μ: 14030, ~: 14030) -HooksTest:test_fuzz_validateHookPermissions_afterDonate(uint160) (runs: 1000, μ: 13964, ~: 13964) -HooksTest:test_fuzz_validateHookPermissions_afterInitialize(uint160) (runs: 1000, μ: 13963, ~: 13963) -HooksTest:test_fuzz_validateHookPermissions_afterRemoveLiquidity(uint160) (runs: 1000, μ: 14012, ~: 14012) -HooksTest:test_fuzz_validateHookPermissions_afterSwap(uint160) (runs: 1000, μ: 13978, ~: 13978) -HooksTest:test_fuzz_validateHookPermissions_allHooks(uint160) (runs: 1000, μ: 16079, ~: 16079) -HooksTest:test_fuzz_validateHookPermissions_beforeAddLiquidity(uint160) (runs: 1000, μ: 14017, ~: 14017) -HooksTest:test_fuzz_validateHookPermissions_beforeAfterRemoveLiquidity(uint160) (runs: 1000, μ: 13997, ~: 13997) -HooksTest:test_fuzz_validateHookPermissions_beforeAndAfterAddLiquidity(uint160) (runs: 1000, μ: 13984, ~: 13984) -HooksTest:test_fuzz_validateHookPermissions_beforeAndAfterDonate(uint160) (runs: 1000, μ: 13995, ~: 13995) -HooksTest:test_fuzz_validateHookPermissions_beforeAndAfterInitialize(uint160) (runs: 1000, μ: 13997, ~: 13997) -HooksTest:test_fuzz_validateHookPermissions_beforeAndAfterSwap(uint160) (runs: 1000, μ: 14029, ~: 14029) -HooksTest:test_fuzz_validateHookPermissions_beforeDonate(uint160) (runs: 1000, μ: 14023, ~: 14023) -HooksTest:test_fuzz_validateHookPermissions_beforeInitialize(uint160) (runs: 1000, μ: 13968, ~: 13968) -HooksTest:test_fuzz_validateHookPermissions_beforeInitializeAfterAddLiquidity(uint160) (runs: 1000, μ: 13999, ~: 13999) -HooksTest:test_fuzz_validateHookPermissions_beforeRemoveLiquidity(uint160) (runs: 1000, μ: 13985, ~: 13985) -HooksTest:test_fuzz_validateHookPermissions_beforeSwap(uint160) (runs: 1000, μ: 14012, ~: 14012) -HooksTest:test_fuzz_validateHookPermissions_noHooks(uint160) (runs: 1000, μ: 14038, ~: 14038) -HooksTest:test_gas_hookShouldCallBeforeSwap() (gas: 38003) -HooksTest:test_initialize_succeedsWithHook() (gas: 162106) -HooksTest:test_isValidHookAddress_invalid_noFlagsNoDynamicFee() (gas: 7018) -HooksTest:test_isValidHookAddress_valid_anyFlags() (gas: 17610) -HooksTest:test_isValidHookAddress_valid_noFlagsWithDynamicFee() (gas: 5599) -HooksTest:test_isValidHookAddress_zeroAddress_fixedFee() (gas: 4128) -HooksTest:test_swap_succeedsWithHook() (gas: 259423) -LPFeeLibraryTest:test_fuzz_getInitialLPFee(uint24) (runs: 1000, μ: 3445, ~: 3459) -LPFeeLibraryTest:test_fuzz_isDynamicFee(uint24) (runs: 1000, μ: 3292, ~: 3292) -LPFeeLibraryTest:test_fuzz_validate(uint24) (runs: 1000, μ: 929, ~: 417) -LPFeeLibraryTest:test_getInitialLPFee_forDynamicFeeIsZero() (gas: 3168) -LPFeeLibraryTest:test_getInitialLPFee_forStaticFeeIsCorrect() (gas: 3257) -LPFeeLibraryTest:test_getInitialLPFee_revertsWithFeeTooLarge_forStaticFee() (gas: 3189) -LPFeeLibraryTest:test_isDynamicFee_returnsFalse() (gas: 3131) -LPFeeLibraryTest:test_isDynamicFee_returnsTrue() (gas: 3099) -LPFeeLibraryTest:test_isDynamicFee_returnsTrue_forMaxValue() (gas: 3121) -LPFeeLibraryTest:test_validate_doesNotRevert() (gas: 298) -LPFeeLibraryTest:test_validate_doesNotRevertWithMaxFee() (gas: 255) -LPFeeLibraryTest:test_validate_doesNotRevertWithNoFee() (gas: 253) -LPFeeLibraryTest:test_validate_revertsWithFeeTooLarge() (gas: 3129) -LiquidityMathTest:test_addDelta_fuzz(uint128,int128) (runs: 1000, μ: 15257, ~: 15531) -LiquidityMathTest:test_addDelta_sub_int128min_fuzz(uint128) (runs: 1000, μ: 12891, ~: 12952) -LiquidityMathTest:test_addDelta_sub_int128min_throwsForReferenceOnly() (gas: 14819) -LiquidityMathTest:test_addDelta_throwsForOverflow() (gas: 8473) -LiquidityMathTest:test_addDelta_throwsForUnderflow() (gas: 10694) -LockTest:test_lock() (gas: 4421) -LockTest:test_unlockedSlot() (gas: 3187) -ModifyLiquidityTest:test_gas_modifyLiquidity_newPosition() (gas: 323352) -ModifyLiquidityTest:test_gas_modifyLiquidity_updateSamePosition_withSalt() (gas: 474302) -ModifyLiquidityTest:test_modifyLiquidity_samePosition_withSalt_isUpdated() (gas: 495075) -ModifyLiquidityTest:test_modifyLiquidity_samePosition_zeroSalt_isUpdated() (gas: 492731) -ModifyLiquidityTest:test_modifyLiquidity_sameSalt_differentLiquidityRouters_doNotEditSamePosition() (gas: 1929463) -ModifyLiquidityTest:test_modifyLiquidity_sameTicks_withDifferentSalt_isNotUpdated() (gas: 693415) -NestedActions:test_nestedAddLiquidity() (gas: 267514) -NestedActions:test_nestedDonate() (gas: 249712) -NestedActions:test_nestedInitialize() (gas: 157209) -NestedActions:test_nestedRemoveLiquidity() (gas: 276589) -NestedActions:test_nestedSwap() (gas: 246761) -NonZeroDeltaCountTest:test_decrementNonzeroDeltaCount() (gas: 4866) -NonZeroDeltaCountTest:test_fuzz_nonZeroDeltaCount(uint256) (runs: 1000, μ: 234967, ~: 235132) -NonZeroDeltaCountTest:test_incrementNonzeroDeltaCount() (gas: 4008) -NonZeroDeltaCountTest:test_nonZeroDeltaCountSlot() (gas: 3241) -PoolIdTest:test_fuzz_toId((address,address,uint24,int24,address)) (runs: 1000, μ: 4463, ~: 4463) -PoolManagerInitializeTest:test_fuzz_initialize((address,address,uint24,int24,address),uint160) (runs: 1000, μ: 42012, ~: 39763) -PoolManagerInitializeTest:test_initialize_failsIfTickSpaceNeg(uint160) (runs: 1000, μ: 46790, ~: 46581) -PoolManagerInitializeTest:test_initialize_failsIfTickSpaceTooLarge(uint160) (runs: 1000, μ: 47289, ~: 47080) -PoolManagerInitializeTest:test_initialize_failsIfTickSpaceZero(uint160) (runs: 1000, μ: 46379, ~: 46170) -PoolManagerInitializeTest:test_initialize_failsWithIncorrectSelectors() (gas: 1274903) -PoolManagerInitializeTest:test_initialize_fetchFeeWhenController(uint24) (runs: 1000, μ: 155111, ~: 156344) -PoolManagerInitializeTest:test_initialize_forNativeTokens(uint160) (runs: 1000, μ: 86886, ~: 86770) -PoolManagerInitializeTest:test_initialize_gas() (gas: 80672) -PoolManagerInitializeTest:test_initialize_revertsWhenPoolAlreadyInitialized(uint160) (runs: 1000, μ: 117805, ~: 117644) -PoolManagerInitializeTest:test_initialize_revertsWithIdenticalTokens(uint160) (runs: 1000, μ: 48355, ~: 48146) -PoolManagerInitializeTest:test_initialize_revertsWithSameTokenCombo(uint160) (runs: 1000, μ: 53468, ~: 53259) -PoolManagerInitializeTest:test_initialize_succeedsWithCorrectSelectors() (gas: 1217112) -PoolManagerInitializeTest:test_initialize_succeedsWithEmptyHooks(uint160) (runs: 1000, μ: 1130559, ~: 1130393) -PoolManagerInitializeTest:test_initialize_succeedsWithHooks(uint160) (runs: 1000, μ: 742846, ~: 742680) -PoolManagerInitializeTest:test_initialize_succeedsWithMaxTickSpacing(uint160) (runs: 1000, μ: 87535, ~: 87369) -PoolManagerInitializeTest:test_initialize_succeedsWithOutOfBoundsFeeController(uint160) (runs: 1000, μ: 116140, ~: 115974) -PoolManagerInitializeTest:test_initialize_succeedsWithOverflowFeeController(uint160) (runs: 1000, μ: 116150, ~: 115984) -PoolManagerInitializeTest:test_initialize_succeedsWithRevertingFeeController(uint160) (runs: 1000, μ: 115931, ~: 115765) -PoolManagerInitializeTest:test_initialize_succeedsWithWrongReturnSizeFeeController(uint160) (runs: 1000, μ: 116145, ~: 115979) -PoolManagerTest:test_addLiquidity_6909() (gas: 396459) -PoolManagerTest:test_addLiquidity_failsIfLocked() (gas: 46519) -PoolManagerTest:test_addLiquidity_failsIfNotInitialized() (gas: 67864) -PoolManagerTest:test_addLiquidity_failsWithIncorrectSelectors() (gas: 1522662) -PoolManagerTest:test_addLiquidity_gas() (gas: 185058) -PoolManagerTest:test_addLiquidity_secondAdditionSameRange_gas() (gas: 289202) -PoolManagerTest:test_addLiquidity_succeeds() (gas: 167773) -PoolManagerTest:test_addLiquidity_succeedsForNativeTokensIfInitialized(uint160) (runs: 1000, μ: 174928, ~: 174864) -PoolManagerTest:test_addLiquidity_succeedsIfInitialized(uint160) (runs: 1000, μ: 177961, ~: 177897) -PoolManagerTest:test_addLiquidity_succeedsWithCorrectSelectors() (gas: 1501166) -PoolManagerTest:test_addLiquidity_succeedsWithHooksIfInitialized(uint160) (runs: 1000, μ: 979875, ~: 981092) -PoolManagerTest:test_addLiquidity_withFeeTakingHook() (gas: 1291586) -PoolManagerTest:test_addLiquidity_withHooks_gas() (gas: 1426696) -PoolManagerTest:test_addLiquidity_withNative_gas() (gas: 172272) -PoolManagerTest:test_burn_failsIfLocked() (gas: 32812) -PoolManagerTest:test_bytecodeSize() (gas: 11683) -PoolManagerTest:test_collectProtocolFees_ERC20_accumulateFees_exactOutput() (gas: 297948) -PoolManagerTest:test_collectProtocolFees_ERC20_accumulateFees_gas() (gas: 303873) -PoolManagerTest:test_collectProtocolFees_ERC20_returnsAllFeesIf0IsProvidedAsParameter() (gas: 292417) -PoolManagerTest:test_collectProtocolFees_nativeToken_accumulateFees_gas() (gas: 288177) -PoolManagerTest:test_collectProtocolFees_nativeToken_returnsAllFeesIf0IsProvidedAsParameter() (gas: 283350) -PoolManagerTest:test_donate_OneToken_gas() (gas: 126106) -PoolManagerTest:test_donate_failsIfLocked() (gas: 39104) -PoolManagerTest:test_donate_failsIfNoLiquidity(uint160) (runs: 1000, μ: 151445, ~: 151287) -PoolManagerTest:test_donate_failsIfNotInitialized() (gas: 69531) -PoolManagerTest:test_donate_failsWithIncorrectSelectors() (gas: 1700759) -PoolManagerTest:test_donate_succeedsForNativeTokensWhenPoolHasLiquidity() (gas: 165308) -PoolManagerTest:test_donate_succeedsWhenPoolHasLiquidity() (gas: 181938) -PoolManagerTest:test_donate_succeedsWithCorrectSelectors() (gas: 1649605) -PoolManagerTest:test_fuzz_swap_beforeSwapReturnsDelta(int128,int256,bool) (runs: 1000, μ: 3483594, ~: 1481797) -PoolManagerTest:test_getPosition() (gas: 27358) -PoolManagerTest:test_mint_failsIfLocked() (gas: 32846) -PoolManagerTest:test_removeLiquidity_6909() (gas: 374614) -PoolManagerTest:test_removeLiquidity_failsIfLocked() (gas: 46808) -PoolManagerTest:test_removeLiquidity_failsIfNotInitialized() (gas: 68162) -PoolManagerTest:test_removeLiquidity_failsWithIncorrectSelectors() (gas: 1691316) -PoolManagerTest:test_removeLiquidity_gas() (gas: 260656) -PoolManagerTest:test_removeLiquidity_someLiquidityRemains_gas() (gas: 283032) -PoolManagerTest:test_removeLiquidity_succeeds() (gas: 108637) -PoolManagerTest:test_removeLiquidity_succeedsForNativeTokensIfInitialized(uint160) (runs: 1000, μ: 122287, ~: 122223) -PoolManagerTest:test_removeLiquidity_succeedsIfInitialized(uint160) (runs: 1000, μ: 118795, ~: 118731) -PoolManagerTest:test_removeLiquidity_succeedsWithCorrectSelectors() (gas: 1599088) -PoolManagerTest:test_removeLiquidity_succeedsWithHooksIfInitialized(uint160) (runs: 1000, μ: 1065218, ~: 1066434) -PoolManagerTest:test_removeLiquidity_withFeeTakingHook() (gas: 1376208) -PoolManagerTest:test_removeLiquidity_withHooks_gas() (gas: 1541464) -PoolManagerTest:test_removeLiquidity_withNative_gas() (gas: 119632) -PoolManagerTest:test_settle_failsIfLocked() (gas: 32154) -PoolManagerTest:test_settle_revertsSendingNativeWithToken() (gas: 57837) -PoolManagerTest:test_swap_accruesProtocolFees(uint16,uint16,int256) (runs: 1000, μ: 874553, ~: 697606) -PoolManagerTest:test_swap_afterSwapFeeOnUnspecified_exactInput() (gas: 1385730) -PoolManagerTest:test_swap_afterSwapFeeOnUnspecified_exactOutput() (gas: 1379928) -PoolManagerTest:test_swap_againstLiqWithNative_gas() (gas: 285086) -PoolManagerTest:test_swap_againstLiquidity_gas() (gas: 294304) -PoolManagerTest:test_swap_beforeSwapNoOpsSwap_exactInput() (gas: 1073247) -PoolManagerTest:test_swap_beforeSwapNoOpsSwap_exactOutput() (gas: 1067848) -PoolManagerTest:test_swap_burn6909AsInput_gas() (gas: 382693) -PoolManagerTest:test_swap_burnNative6909AsInput_gas() (gas: 346696) -PoolManagerTest:test_swap_failsIfLocked() (gas: 46274) -PoolManagerTest:test_swap_failsIfNotInitialized(uint160) (runs: 1000, μ: 79424, ~: 79220) -PoolManagerTest:test_swap_failsWithIncorrectSelectors() (gas: 1705349) -PoolManagerTest:test_swap_gas() (gas: 155795) -PoolManagerTest:test_swap_mint6909IfNativeOutputNotTaken_gas() (gas: 170969) -PoolManagerTest:test_swap_mint6909IfOutputNotTaken_gas() (gas: 196081) -PoolManagerTest:test_swap_succeeds() (gas: 163775) -PoolManagerTest:test_swap_succeedsIfInitialized() (gas: 186462) -PoolManagerTest:test_swap_succeedsWithCorrectSelectors() (gas: 1668769) -PoolManagerTest:test_swap_succeedsWithHooksIfInitialized() (gas: 1191030) -PoolManagerTest:test_swap_succeedsWithNativeTokensIfInitialized() (gas: 174827) -PoolManagerTest:test_swap_withHooks_gas() (gas: 1741205) -PoolManagerTest:test_swap_withNative_gas() (gas: 147339) -PoolManagerTest:test_swap_withNative_succeeds() (gas: 152146) -PoolManagerTest:test_take_failsIfLocked() (gas: 32801) -PoolManagerTest:test_take_failsWithInvalidTokensThatDoNotReturnTrueOnTransfer() (gas: 1064192) -PoolManagerTest:test_take_failsWithNoLiquidity() (gas: 17087345) -PoolManagerTest:test_take_succeedsWithPoolWithLiquidity() (gas: 91653) -PoolManagerTest:test_take_succeedsWithPoolWithLiquidityWithNativeToken() (gas: 94976) -PoolManagerTest:test_unlock_EmitsCorrectId() (gas: 39125) -PoolManagerTest:test_unlock_cannotBeCalledTwiceByCaller() (gas: 83589) -PoolManagerTest:test_unlock_cannotBeCalledTwiceByDifferentCallers() (gas: 111425) -PoolTest:testModifyLiquidity(uint160,uint24,uint24,(address,int24,int24,int128,int24,bytes32)) (runs: 1000, μ: 27633, ~: 11890) -PoolTest:testPoolInitialize(uint160,uint24,uint24) (runs: 1000, μ: 18085, ~: 5640) -PoolTest:testSwap(uint160,uint24,uint16,uint16,(int24,bool,int256,uint160,uint24)) (runs: 1000, μ: 91966, ~: 18312) -PositionTest:test_fuzz_get(address,int24,int24,bytes32) (runs: 1000, μ: 4234, ~: 4234) -PositionTest:test_fuzz_update(int128,(uint128,uint256,uint256),uint256,uint256) (runs: 1000, μ: 71022, ~: 70527) -ProtocolFeeLibraryTest:test_calculateSwapFee() (gas: 4717) -ProtocolFeeLibraryTest:test_calculateSwapFee_gas() (gas: 37873) -ProtocolFeeLibraryTest:test_fuzz_calculateSwapFee(uint24,uint24) (runs: 1000, μ: 9371, ~: 9536) -ProtocolFeeLibraryTest:test_fuzz_getOneForZeroFee(uint24) (runs: 1000, μ: 3278, ~: 3278) -ProtocolFeeLibraryTest:test_fuzz_getZeroForOneFee(uint24) (runs: 1000, μ: 3387, ~: 3387) -ProtocolFeeLibraryTest:test_fuzz_isValidProtocolFee(uint24) (runs: 1000, μ: 3399, ~: 3405) -ProtocolFeeLibraryTest:test_getOneForZeroFee() (gas: 3324) -ProtocolFeeLibraryTest:test_getZeroForOneFee() (gas: 3265) -ProtocolFeeLibraryTest:test_isValidProtocolFee_fee() (gas: 5777) -ProtocolFeesTest:test_collectProtocolFees_revertsWithInvalidCaller() (gas: 34505) -ProtocolFeesTest:test_collectProtocolFees_succeeds() (gas: 161960) -ProtocolFeesTest:test_fetchProtocolFee_invalidReturnSize() (gas: 282566) -ProtocolFeesTest:test_fetchProtocolFee_outOfBounds() (gas: 278517) -ProtocolFeesTest:test_fetchProtocolFee_overflowFee() (gas: 281449) -ProtocolFeesTest:test_fetchProtocolFee_revert() (gas: 276469) -ProtocolFeesTest:test_fetchProtocolFee_succeeds() (gas: 94374) -ProtocolFeesTest:test_fuzz_collectProtocolFees(address,uint256,uint256) (runs: 1000, μ: 164688, ~: 176670) -ProtocolFeesTest:test_fuzz_setProtocolFee((address,address,uint24,int24,address),uint24) (runs: 1000, μ: 135881, ~: 132720) -ProtocolFeesTest:test_fuzz_updateProtocolFees(uint256,uint256) (runs: 1000, μ: 84898, ~: 84932) -ProtocolFeesTest:test_setProtocolFeeController_revertsWithNotAuthorized() (gas: 39121) -ProtocolFeesTest:test_setProtocolFeeController_succeedsNoRevert() (gas: 63395) -ProtocolFeesTest:test_setProtocolFee_revertsWithInvalidCaller() (gas: 89287) -ProtocolFeesTest:test_setProtocolFee_revertsWithInvalidFee() (gas: 116959) -ProtocolFeesTest:test_setProtocolFee_succeeds_gas() (gas: 148359) -ProtocolFeesTest:test_updateProtocolFees_succeeds() (gas: 84599) -ReservesTest:test_fuzz_get_set(address,uint256) (runs: 1000, μ: 4128, ~: 4128) -ReservesTest:test_getReserves_returns0AfterSet() (gas: 5906) -ReservesTest:test_getReserves_returns_set() (gas: 5873) -ReservesTest:test_getReserves_reverts_withoutSet() (gas: 5448) -ReservesTest:test_reservesOfSlot() (gas: 3186) -ReservesTest:test_set_twice_returns_correct_value() (gas: 6242) -SafeCastTest:test_fuzz_toInt128_fromInt256(int256) (runs: 1000, μ: 3329, ~: 3350) -SafeCastTest:test_fuzz_toInt128_fromUint256(uint256) (runs: 1000, μ: 3277, ~: 3300) -SafeCastTest:test_fuzz_toInt256(uint256) (runs: 1000, μ: 3257, ~: 3259) -SafeCastTest:test_fuzz_toUint128(uint256) (runs: 1000, μ: 3303, ~: 3322) -SafeCastTest:test_fuzz_toUint160(uint256) (runs: 1000, μ: 3287, ~: 3302) -SafeCastTest:test_toInt128_fromInt256() (gas: 4734) -SafeCastTest:test_toInt128_fromUint256() (gas: 4143) -SafeCastTest:test_toInt256() (gas: 4117) -SafeCastTest:test_toUint128() (gas: 4184) -SafeCastTest:test_toUint160() (gas: 4161) -SkipCallsTest:test_afterAddLiquidity_skipIfCalledByHook() (gas: 22871930) -SkipCallsTest:test_afterDonate_skipIfCalledByHook() (gas: 22925054) -SkipCallsTest:test_afterInitialize_skipIfCalledByHook() (gas: 22217203) -SkipCallsTest:test_afterRemoveLiquidity_skipIfCalledByHook() (gas: 23158026) -SkipCallsTest:test_afterSwap_skipIfCalledByHook() (gas: 22961349) -SkipCallsTest:test_beforeAddLiquidity_skipIfCalledByHook() (gas: 22870961) -SkipCallsTest:test_beforeDonate_skipIfCalledByHook() (gas: 22925120) -SkipCallsTest:test_beforeInitialize_skipIfCalledByHook() (gas: 22217009) -SkipCallsTest:test_beforeRemoveLiquidity_skipIfCalledByHook() (gas: 23146835) -SkipCallsTest:test_beforeSwap_skipIfCalledByHook() (gas: 22960832) -SkipCallsTest:test_gas_beforeSwap_skipIfCalledByHook() (gas: 22783598) -SqrtPriceMathTest:test_getAmount0Delta_1Amount1ForPriceOf1To1_21() (gas: 4673) -SqrtPriceMathTest:test_getAmount0Delta_gasCostForAmount0WhereRoundUpIsFalse() (gas: 77817) -SqrtPriceMathTest:test_getAmount0Delta_gasCostForAmount0WhereRoundUpIsTrue() (gas: 77932) -SqrtPriceMathTest:test_getAmount0Delta_returns0IfLiquidityIs0() (gas: 3695) -SqrtPriceMathTest:test_getAmount0Delta_returns0IfPricesAreEqual() (gas: 3715) -SqrtPriceMathTest:test_getAmount0Delta_revertsIfPriceIsZero() (gas: 3222) -SqrtPriceMathTest:test_getAmount0Delta_worksForPricesThatOverflow() (gas: 4877) -SqrtPriceMathTest:test_getAmount1Delta_1Amount1ForPriceOf1To1_21() (gas: 4334) -SqrtPriceMathTest:test_getAmount1Delta_gasCostForAmount1WhereRoundUpIsFalse() (gas: 77706) -SqrtPriceMathTest:test_getAmount1Delta_gasCostForAmount1WhereRoundUpIsTrue() (gas: 77685) -SqrtPriceMathTest:test_getAmount1Delta_returns0IfLiquidityIs0() (gas: 3482) -SqrtPriceMathTest:test_getAmount1Delta_returns0IfPricesAreEqual() (gas: 3456) -SqrtPriceMathTest:test_getNextSqrtPriceFromInput_amountInGreaterThanType_uint96_maxAndZeroForOneEqualsTrue() (gas: 3851) -SqrtPriceMathTest:test_getNextSqrtPriceFromInput_anyInputAmountCannotUnderflowThePrice() (gas: 3861) -SqrtPriceMathTest:test_getNextSqrtPriceFromInput_canReturn1WithEnoughAmountInAndZeroForOneEqualsTrue() (gas: 3775) -SqrtPriceMathTest:test_getNextSqrtPriceFromInput_inputAmountOf0_1Currency0() (gas: 3830) -SqrtPriceMathTest:test_getNextSqrtPriceFromInput_inputAmountOf0_1Currency1() (gas: 3685) -SqrtPriceMathTest:test_getNextSqrtPriceFromInput_returnsInputPriceIfAmountInIsZeroAndZeroForOneEqualsFalse() (gas: 3672) -SqrtPriceMathTest:test_getNextSqrtPriceFromInput_returnsInputPriceIfAmountInIsZeroAndZeroForOneEqualsTrue() (gas: 3361) -SqrtPriceMathTest:test_getNextSqrtPriceFromInput_returnsTheMinimumPriceForMaxInputs() (gas: 4030) -SqrtPriceMathTest:test_getNextSqrtPriceFromInput_revertsIfInputAmountOverflowsThePrice() (gas: 3657) -SqrtPriceMathTest:test_getNextSqrtPriceFromInput_revertsIfLiquidityIsZero() (gas: 3174) -SqrtPriceMathTest:test_getNextSqrtPriceFromInput_revertsIfPriceIsZero() (gas: 3130) -SqrtPriceMathTest:test_getNextSqrtPriceFromInput_zeroForOneEqualsFalseGas() (gas: 77854) -SqrtPriceMathTest:test_getNextSqrtPriceFromInput_zeroForOneEqualsTrueGas() (gas: 78023) -SqrtPriceMathTest:test_getNextSqrtPriceFromOutput_outputAmountOf0_1Currency0() (gas: 3538) -SqrtPriceMathTest:test_getNextSqrtPriceFromOutput_outputAmountOf0_1Currency1() (gas: 3868) -SqrtPriceMathTest:test_getNextSqrtPriceFromOutput_puzzlingEchidnaTest() (gas: 3363) -SqrtPriceMathTest:test_getNextSqrtPriceFromOutput_returnsInputPriceIfAmountInIsZeroAndZeroForOneEqualsFalse() (gas: 3423) -SqrtPriceMathTest:test_getNextSqrtPriceFromOutput_returnsInputPriceIfAmountInIsZeroAndZeroForOneEqualsTrue() (gas: 3534) -SqrtPriceMathTest:test_getNextSqrtPriceFromOutput_revertsIfAmountOutIsImpossibleInOneForZeroDirection() (gas: 3385) -SqrtPriceMathTest:test_getNextSqrtPriceFromOutput_revertsIfAmountOutIsImpossibleInZeroForOneDirection() (gas: 3469) -SqrtPriceMathTest:test_getNextSqrtPriceFromOutput_revertsIfLiquidityIsZero() (gas: 3131) -SqrtPriceMathTest:test_getNextSqrtPriceFromOutput_revertsIfOutputAmountIsExactlyTheVirtualReservesOfCurrency0() (gas: 3363) -SqrtPriceMathTest:test_getNextSqrtPriceFromOutput_revertsIfOutputAmountIsExactlyTheVirtualReservesOfCurrency1() (gas: 3375) -SqrtPriceMathTest:test_getNextSqrtPriceFromOutput_revertsIfOutputAmountIsGreaterThanTheVirtualReservesOfCurrency0() (gas: 3407) -SqrtPriceMathTest:test_getNextSqrtPriceFromOutput_revertsIfOutputAmountIsGreaterThanTheVirtualReservesOfCurrency1() (gas: 3431) -SqrtPriceMathTest:test_getNextSqrtPriceFromOutput_revertsIfPriceIsZero() (gas: 3173) -SqrtPriceMathTest:test_getNextSqrtPriceFromOutput_succeedsIfOutputAmountIsJustLessThanTheVirtualReservesOfCurrency1() (gas: 3572) -SqrtPriceMathTest:test_getNextSqrtPriceFromOutput_zeroForOneEqualsFalseGas() (gas: 78058) -SqrtPriceMathTest:test_getNextSqrtPriceFromOutput_zeroForOneEqualsTrueGas() (gas: 77755) -SqrtPriceMathTest:test_swapComputation_sqrtPTimessqrtQOverflows() (gas: 5473) -StateLibraryTest:test_fuzz_getFeeGrowthInside((int24,int24,int256,bytes32),bool) (runs: 1000, μ: 818858, ~: 806233) -StateLibraryTest:test_fuzz_getLiquidity((int24,int24,int256,bytes32)) (runs: 1000, μ: 289046, ~: 280635) -StateLibraryTest:test_fuzz_getPositionInfo((int24,int24,int256,bytes32),uint256,bool) (runs: 1000, μ: 763621, ~: 759141) -StateLibraryTest:test_fuzz_getPositionLiquidity((int24,int24,int256,bytes32),(int24,int24,int256,bytes32)) (runs: 1000, μ: 523574, ~: 521572) -StateLibraryTest:test_fuzz_getTickBitmap((int24,int24,int256,bytes32)) (runs: 1000, μ: 287519, ~: 279167) -StateLibraryTest:test_fuzz_getTickLiquidity((int24,int24,int256,bytes32)) (runs: 1000, μ: 296383, ~: 288039) -StateLibraryTest:test_fuzz_getTickLiquidity_two_positions((int24,int24,int256,bytes32),(int24,int24,int256,bytes32)) (runs: 1000, μ: 524634, ~: 517212) -StateLibraryTest:test_getFeeGrowthGlobals0() (gas: 479819) -StateLibraryTest:test_getFeeGrowthGlobals1() (gas: 467714) -StateLibraryTest:test_getFeeGrowthInside() (gas: 857330) -StateLibraryTest:test_getLiquidity() (gas: 536295) -StateLibraryTest:test_getPositionInfo() (gas: 602720) -StateLibraryTest:test_getPositionLiquidity() (gas: 323784) -StateLibraryTest:test_getSlot0() (gas: 728415) -StateLibraryTest:test_getTickBitmap() (gas: 326897) -StateLibraryTest:test_getTickFeeGrowthOutside() (gas: 733217) -StateLibraryTest:test_getTickInfo() (gas: 736321) -StateLibraryTest:test_getTickLiquidity() (gas: 326110) -SwapHelperTest:test_swapNativeInput_helper_nonnative_oneForZero_exactInput() (gas: 9880) -SwapHelperTest:test_swapNativeInput_helper_nonnative_oneForZero_exactOutput() (gas: 9877) -SwapHelperTest:test_swapNativeInput_helper_nonnative_zeroForOne_exactInput() (gas: 9911) -SwapHelperTest:test_swapNativeInput_helper_nonnative_zeroForOne_exactOutput() (gas: 9888) -SwapHelperTest:test_swapNativeInput_helper_oneForZero_exactInput() (gas: 159623) -SwapHelperTest:test_swapNativeInput_helper_oneForZero_exactOutput() (gas: 159750) -SwapHelperTest:test_swapNativeInput_helper_zeroForOne_exactInput() (gas: 166267) -SwapHelperTest:test_swapNativeInput_helper_zeroForOne_exactOutput() (gas: 172300) -SwapHelperTest:test_swap_helper_native_oneForZero_exactInput() (gas: 159637) -SwapHelperTest:test_swap_helper_native_oneForZero_exactOutput() (gas: 159751) -SwapHelperTest:test_swap_helper_native_zeroForOne_exactInput() (gas: 166457) -SwapHelperTest:test_swap_helper_native_zeroForOne_exactOutput() (gas: 9931) -SwapHelperTest:test_swap_helper_oneForZero_exactInput() (gas: 171428) -SwapHelperTest:test_swap_helper_oneForZero_exactOutput() (gas: 171532) -SwapHelperTest:test_swap_helper_zeroForOne_exactInput() (gas: 177967) -SwapHelperTest:test_swap_helper_zeroForOne_exactOutput() (gas: 177061) -SwapMathTest:test_computeSwapStep_amountOut_isCappedAtTheDesiredAmountOut() (gas: 6840) -SwapMathTest:test_computeSwapStep_entireInputAmountTakenAsFee() (gas: 6695) -SwapMathTest:test_computeSwapStep_exactAmountIn_oneForZero_thatGetsCappedAtPriceTargetIn() (gas: 7234) -SwapMathTest:test_computeSwapStep_exactAmountIn_oneForZero_thatIsFullySpentIn() (gas: 7947) -SwapMathTest:test_computeSwapStep_exactAmountOut_oneForZero_thatGetsCappedAtPriceTargetIn() (gas: 6852) -SwapMathTest:test_computeSwapStep_exactAmountOut_oneForZero_thatIsFullyReceivedIn() (gas: 7973) -SwapMathTest:test_computeSwapStep_oneForZero_handlesIntermediateInsufficientLiquidityInExactOutputCase() (gas: 6434) -SwapMathTest:test_computeSwapStep_swapOneForZero_exactInCapped() (gas: 79231) -SwapMathTest:test_computeSwapStep_swapOneForZero_exactInPartial() (gas: 79653) -SwapMathTest:test_computeSwapStep_swapOneForZero_exactOutCapped() (gas: 78971) -SwapMathTest:test_computeSwapStep_swapOneForZero_exactOutPartial() (gas: 80074) -SwapMathTest:test_computeSwapStep_swapZeroForOne_exactInCapped() (gas: 79366) -SwapMathTest:test_computeSwapStep_swapZeroForOne_exactInPartial() (gas: 80181) -SwapMathTest:test_computeSwapStep_swapZeroForOne_exactOutCapped() (gas: 79083) -SwapMathTest:test_computeSwapStep_swapZeroForOne_exactOutPartial() (gas: 79744) -SwapMathTest:test_computeSwapStep_targetPriceOf1UsesPartialInputAmount() (gas: 6507) -SwapMathTest:test_computeSwapStep_zeroForOne_handlesIntermediateInsufficientLiquidityInExactOutputCase() (gas: 6321) -SwapMathTest:test_fuzz_computeSwapStep(uint160,uint160,uint128,int256,uint24) (runs: 1000, μ: 9221, ~: 8964) -SwapMathTest:test_fuzz_getSqrtPriceTarget(bool,uint160,uint160) (runs: 1000, μ: 3629, ~: 3629) -SyncTest:test_settle_afterTake_doesNotApplyDelta() (gas: 1123114) -SyncTest:test_settle_balanceInPool_shouldNotApplyDelta() (gas: 66800) -SyncTest:test_settle_noBalanceInPool_shouldNotApplyDelta() (gas: 67078) -SyncTest:test_settle_revertsIfSyncNotCalled() (gas: 45420) -SyncTest:test_settle_withNoStartingBalance() (gas: 337084) -SyncTest:test_settle_withStartingBalance() (gas: 174021) -SyncTest:test_settle_withoutSync_doesNotRevert_takesUserBalance() (gas: 147121) -SyncTest:test_sync_balanceIsNonZero() (gas: 42897) -SyncTest:test_sync_balanceIsZero() (gas: 41154) -TestBalanceDelta:test_add() (gas: 8282) -TestBalanceDelta:test_add_revertsOnOverflow() (gas: 3245) -TestBalanceDelta:test_fuzz_add(int128,int128,int128,int128) (runs: 1000, μ: 4423, ~: 4726) -TestBalanceDelta:test_fuzz_amount0_amount1(int128,int128) (runs: 1000, μ: 3840, ~: 3840) -TestBalanceDelta:test_fuzz_eq(int128,int128,int128,int128) (runs: 1000, μ: 3700, ~: 3700) -TestBalanceDelta:test_fuzz_neq(int128,int128,int128,int128) (runs: 1000, μ: 3710, ~: 3710) -TestBalanceDelta:test_fuzz_sub(int128,int128,int128,int128) (runs: 1000, μ: 4661, ~: 4712) -TestBalanceDelta:test_fuzz_toBalanceDelta(int128,int128) (runs: 1000, μ: 3610, ~: 3610) -TestBalanceDelta:test_sub() (gas: 8761) -TestBalanceDelta:test_sub_revertsOnUnderflow() (gas: 3216) -TestBalanceDelta:test_toBalanceDelta() (gas: 7025) -TestBitMath:test_fuzz_leastSignificantBit(uint256) (runs: 1000, μ: 4212, ~: 4057) -TestBitMath:test_fuzz_mostSignificantBit(uint256) (runs: 1000, μ: 13968, ~: 8955) -TestBitMath:test_invariant_leastSignificantBit(uint256) (runs: 1000, μ: 4774, ~: 4682) -TestBitMath:test_invariant_mostSignificantBit(uint256) (runs: 1000, μ: 4835, ~: 4834) -TestBitMath:test_leastSignificantBit_gas() (gas: 113935) -TestBitMath:test_leastSignificantBit_maxUint256() (gas: 3518) -TestBitMath:test_leastSignificantBit_one() (gas: 3582) -TestBitMath:test_leastSignificantBit_powersOfTwo() (gas: 222214) -TestBitMath:test_leastSignificantBit_revertsWhenZero() (gas: 3124) -TestBitMath:test_leastSignificantBit_two() (gas: 3533) -TestBitMath:test_mostSignificantBit_gas() (gas: 113746) -TestBitMath:test_mostSignificantBit_maxUint256() (gas: 3474) -TestBitMath:test_mostSignificantBit_one() (gas: 3363) -TestBitMath:test_mostSignificantBit_powersOfTwo() (gas: 196720) -TestBitMath:test_mostSignificantBit_revertsWhenZero() (gas: 3145) -TestBitMath:test_mostSignificantBit_two() (gas: 3349) -TestCurrency:test_fromId_0ReturnsNative() (gas: 10676) -TestCurrency:test_fuzz_balanceOfSelf_native(uint256) (runs: 1000, μ: 72624, ~: 72674) -TestCurrency:test_fuzz_balanceOfSelf_token(uint256) (runs: 1000, μ: 73678, ~: 73689) -TestCurrency:test_fuzz_balanceOf_native(uint256) (runs: 1000, μ: 73438, ~: 73488) -TestCurrency:test_fuzz_balanceOf_token(uint256) (runs: 1000, μ: 76194, ~: 76205) -TestCurrency:test_fuzz_equals(address,address) (runs: 1000, μ: 3445, ~: 3445) -TestCurrency:test_fuzz_fromId_returnsUint256AsCurrency(uint256) (runs: 1000, μ: 8624, ~: 8624) -TestCurrency:test_fuzz_fromId_toId_opposites(address) (runs: 1000, μ: 9475, ~: 9475) -TestCurrency:test_fuzz_greaterThan(address,address) (runs: 1000, μ: 3422, ~: 3422) -TestCurrency:test_fuzz_greaterThanOrEqualTo(address,address) (runs: 1000, μ: 3512, ~: 3512) -TestCurrency:test_fuzz_isNative(address) (runs: 1000, μ: 8737, ~: 8737) -TestCurrency:test_fuzz_lessThan(address,address) (runs: 1000, μ: 3444, ~: 3444) -TestCurrency:test_fuzz_toId_returnsCurrencyAsUint256(address) (runs: 1000, μ: 8653, ~: 8653) -TestCurrency:test_fuzz_transfer_native(uint256) (runs: 1000, μ: 66552, ~: 68327) -TestCurrency:test_fuzz_transfer_token(uint256) (runs: 1000, μ: 62485, ~: 75257) -TestCurrency:test_isNative_native_returnsTrue() (gas: 10701) -TestCurrency:test_isNative_token_returnsFalse() (gas: 10739) -TestCurrency:test_toId_nativeReturns0() (gas: 10618) -TestDelegateCall:test_delegateCallFromExternalToPrivateMethodWithModifier_revertsWithDelegateCallNotAllowed() (gas: 10439) -TestDelegateCall:test_delegateCallNoModifier() (gas: 8478) -TestDelegateCall:test_delegateCallWithModifier_revertsWithDelegateCallNotAllowed() (gas: 10414) -TestDelegateCall:test_externalCallToPrivateMethodWithModifer_succeeds() (gas: 5446) -TestDelegateCall:test_gas_noDelegateCall() (gas: 13101) -TestDynamicFees:test_emitsSwapFee() (gas: 259383) -TestDynamicFees:test_fuzz_ProtocolAndLPFee(uint24,uint16,uint16,int256) (runs: 1000, μ: 284613, ~: 278864) -TestDynamicFees:test_initialize_initializesFeeTo0() (gas: 112884) -TestDynamicFees:test_swap_100PercentFee_AmountIn_WithProtocol() (gas: 262213) -TestDynamicFees:test_swap_100PercentLPFee_AmountIn_NoProtocol() (gas: 208376) -TestDynamicFees:test_swap_50PercentLPFee_AmountIn_NoProtocol() (gas: 223050) -TestDynamicFees:test_swap_50PercentLPFee_AmountOut_NoProtocol() (gas: 215942) -TestDynamicFees:test_swap_99PercentFee_AmountOut_WithProtocol() (gas: 283203) -TestDynamicFees:test_swap_revertsWith_InvalidFeeForExactOut_whenFeeIsMax() (gas: 130538) -TestDynamicFees:test_swap_withDynamicFee_gas() (gas: 571522) -TestDynamicFees:test_updateDynamicLPFee_afterInitialize_failsWithTooLargeFee() (gas: 116852) -TestDynamicFees:test_updateDynamicLPFee_afterInitialize_initializesFee() (gas: 122377) -TestDynamicFees:test_updateDynamicLPFee_beforeSwap_failsWithTooLargeFee() (gas: 128149) -TestDynamicFees:test_updateDynamicLPFee_beforeSwap_succeeds_gas() (gas: 227959) -TestDynamicFees:test_updateDynamicLPFee_revertsIfCallerIsntHook() (gas: 38177) -TestDynamicFees:test_updateDynamicLPFee_revertsIfPoolHasStaticFee() (gas: 116739) -TestDynamicReturnFees:test_dynamicReturnSwapFee_initializeZeroSwapFee() (gas: 81257) -TestDynamicReturnFees:test_dynamicReturnSwapFee_notStored() (gas: 586597) -TestDynamicReturnFees:test_dynamicReturnSwapFee_notUsedIfPoolIsStaticFee() (gas: 553375) -TestDynamicReturnFees:test_dynamicReturnSwapFee_revertIfFeeTooLarge() (gas: 125901) -TestDynamicReturnFees:test_fuzz_dynamicReturnSwapFee(uint24) (runs: 1000, μ: 187954, ~: 200731) -TestDynamicReturnFees:test_returnDynamicSwapFee_beforeSwap_succeeds_gas() (gas: 225387) -TestSlot0:test_fuzz_slot0_pack_unpack(uint160,int24,uint24,uint24) (runs: 1000, μ: 6965, ~: 6965) -TestSlot0:test_slot0_constants_masks() (gas: 3522) -TickBitmapTest:test_flipTick_flippingATickThatResultsInDeletingAWord_gas() (gas: 77761) -TickBitmapTest:test_flipTick_flippingFirstTickInWordToInitialized_gas() (gas: 99657) -TickBitmapTest:test_flipTick_flippingSecondTickInWordToInitialized_gas() (gas: 82622) -TickBitmapTest:test_flipTick_flipsOnlyTheSpecifiedTick() (gas: 19040) -TickBitmapTest:test_flipTick_revertsOnlyItself() (gas: 56450) -TickBitmapTest:test_fuzz_compress(int24,int24) (runs: 1000, μ: 9052, ~: 9258) -TickBitmapTest:test_fuzz_flipTick(int24,int24) (runs: 1000, μ: 9777, ~: 9420) -TickBitmapTest:test_fuzz_nextInitializedTickWithinOneWord(int24,bool) (runs: 1000, μ: 105818, ~: 88570) -TickBitmapTest:test_fuzz_nextInitializedTickWithinOneWord_onEmptyBitmap(int24,int24,uint8,bool) (runs: 1000, μ: 36618, ~: 36544) -TickBitmapTest:test_fuzz_position(int24) (runs: 1000, μ: 3906, ~: 3906) -TickBitmapTest:test_isInitialized_isFalseAtFirst() (gas: 5649) -TickBitmapTest:test_isInitialized_isFlippedBackByFlipTick() (gas: 6422) -TickBitmapTest:test_isInitialized_isFlippedByFlipTick() (gas: 8837) -TickBitmapTest:test_isInitialized_isNotChangedByAnotherFlipToADifferentTick() (gas: 8857) -TickBitmapTest:test_isInitialized_isNotChangedByAnotherFlipToADifferentTickOnAnotherWord() (gas: 28775) -TickBitmapTest:test_nextInitializedTickWithinOneWord_lteFalse_doesNotExceedBoundary() (gas: 6007) -TickBitmapTest:test_nextInitializedTickWithinOneWord_lteFalse_forEntireWord_gas() (gas: 79803) -TickBitmapTest:test_nextInitializedTickWithinOneWord_lteFalse_justBelowBoundary_gas() (gas: 79806) -TickBitmapTest:test_nextInitializedTickWithinOneWord_lteFalse_onBoundary_gas() (gas: 79760) -TickBitmapTest:test_nextInitializedTickWithinOneWord_lteFalse_returnsTheNextInitializedTickFromTheNextWord() (gas: 26739) -TickBitmapTest:test_nextInitializedTickWithinOneWord_lteFalse_returnsTheNextWordsInitializedTickIfOnTheRightBoundary() (gas: 6029) -TickBitmapTest:test_nextInitializedTickWithinOneWord_lteFalse_returnsTheNextWordsInitializedTickIfOnTheRightBoundary2() (gas: 6412) -TickBitmapTest:test_nextInitializedTickWithinOneWord_lteFalse_returnsTheTickDirectlyToTheRight() (gas: 6451) -TickBitmapTest:test_nextInitializedTickWithinOneWord_lteFalse_returnsTheTickDirectlyToTheRight2() (gas: 6428) -TickBitmapTest:test_nextInitializedTickWithinOneWord_lteFalse_returnsTickToRightIfAtInitializedTick() (gas: 6472) -TickBitmapTest:test_nextInitializedTickWithinOneWord_lteFalse_returnsTickToRightIfAtInitializedTick2() (gas: 6430) -TickBitmapTest:test_nextInitializedTickWithinOneWord_lteFalse_skipsEntireWord() (gas: 6049) -TickBitmapTest:test_nextInitializedTickWithinOneWord_lteFalse_skipsHalfWord() (gas: 6028) -TickBitmapTest:test_nextInitializedTickWithinOneWord_lteTrue_atTheWordBoundary() (gas: 5993) -TickBitmapTest:test_nextInitializedTickWithinOneWord_lteTrue_boundaryIsInitialized() (gas: 26603) -TickBitmapTest:test_nextInitializedTickWithinOneWord_lteTrue_entireEmptyWord() (gas: 6014) -TickBitmapTest:test_nextInitializedTickWithinOneWord_lteTrue_forEntireWord_gas() (gas: 79768) -TickBitmapTest:test_nextInitializedTickWithinOneWord_lteTrue_halfwayThroughEmptyWord() (gas: 6037) -TickBitmapTest:test_nextInitializedTickWithinOneWord_lteTrue_justBelowBoundary_gas() (gas: 80099) -TickBitmapTest:test_nextInitializedTickWithinOneWord_lteTrue_onBoundary_gas() (gas: 79746) -TickBitmapTest:test_nextInitializedTickWithinOneWord_lteTrue_returnsSameTickIfInitialized() (gas: 6367) -TickBitmapTest:test_nextInitializedTickWithinOneWord_lteTrue_returnsTickDirectlyToTheLeftOfInputTickIfNotInitialized() (gas: 6369) -TickBitmapTest:test_nextInitializedTickWithinOneWord_lteTrue_willNotExceedTheWordBoundary() (gas: 6016) -TickBitmapTest:test_nextInitializedTickWithinOneWord_lteTrue_wordBoundary() (gas: 6042) -TickBitmapTest:test_nextInitializedTickWithinOneWord_lteTrue_wordBoundaryLess1nextInitializedTickInNextWord() (gas: 6285) -TickMathTestTest:test_MAX_TICK_equalsNegativeMIN_TICK() (gas: 9777) -TickMathTestTest:test_MIN_TICK_equalsNegativeMAX_TICK() (gas: 9755) -TickMathTestTest:test_fuzz_getSqrtPriceAtTick_throwsForTooLarge(int24) (runs: 1000, μ: 14194, ~: 14381) -TickMathTestTest:test_fuzz_getTickAtSqrtPrice_throwsForInvalid(uint160,bool) (runs: 1000, μ: 12620, ~: 12758) -TickMathTestTest:test_getSqrtPriceAtTick_gasCost() (gas: 106793) -TickMathTestTest:test_getSqrtPriceAtTick_isGreaterThanJSImplMaxTick() (gas: 9542) -TickMathTestTest:test_getSqrtPriceAtTick_isLessThanJSImplMinTick() (gas: 9403) -TickMathTestTest:test_getSqrtPriceAtTick_isValidMaxTick() (gas: 12603) -TickMathTestTest:test_getSqrtPriceAtTick_isValidMaxTickSubOne() (gas: 9632) -TickMathTestTest:test_getSqrtPriceAtTick_isValidMinTick() (gas: 12257) -TickMathTestTest:test_getSqrtPriceAtTick_isValidMinTickAddOne() (gas: 9540) -TickMathTestTest:test_getSqrtPriceAtTick_matchesJavaScriptImplByOneHundrethOfABip() (gas: 845438) -TickMathTestTest:test_getSqrtPriceAtTick_throwsForInt24Min() (gas: 8474) -TickMathTestTest:test_getSqrtPriceAtTick_throwsForTooHigh() (gas: 8732) -TickMathTestTest:test_getSqrtPriceAtTick_throwsForTooLow() (gas: 8630) -TickMathTestTest:test_getTickAtSqrtPrice_gasCost() (gas: 248841) -TickMathTestTest:test_getTickAtSqrtPrice_isValidMaxSqrtPriceMinusOne() (gas: 10999) -TickMathTestTest:test_getTickAtSqrtPrice_isValidMinSqrtPrice() (gas: 10742) -TickMathTestTest:test_getTickAtSqrtPrice_isValidMinSqrtPricePlusOne() (gas: 10871) -TickMathTestTest:test_getTickAtSqrtPrice_isValidPriceClosestToMaxTick() (gas: 11070) -TickMathTestTest:test_getTickAtSqrtPrice_matchesJavascriptImplWithin1() (gas: 323584) -TickMathTestTest:test_getTickAtSqrtPrice_throwsForTooHigh() (gas: 8487) -TickMathTestTest:test_getTickAtSqrtPrice_throwsForTooLow() (gas: 8639) -TickTest:testTick_clear_deletesAllTheDataInTheTick() (gas: 11937) -TickTest:testTick_cross_flipsTheGrowthVariables() (gas: 71606) -TickTest:testTick_cross_twoFlipsAreNoOp() (gas: 72282) -TickTest:testTick_getFeeGrowthInside_returns0ForTwoUninitializedTicksIfTickIsAbove() (gas: 78893) -TickTest:testTick_getFeeGrowthInside_returns0ForTwoUninitializedTicksIfTickIsBelow() (gas: 78878) -TickTest:testTick_getFeeGrowthInside_returnsAllForTwoUninitializedTicksIfTickIsInside() (gas: 59230) -TickTest:testTick_getFeeGrowthInside_subtractsLowerTickIfAbove() (gas: 101850) -TickTest:testTick_getFeeGrowthInside_subtractsUpperAndLowerTickIfInside() (gas: 144489) -TickTest:testTick_getFeeGrowthInside_subtractsUpperTickIfBelow() (gas: 101927) -TickTest:testTick_getFeeGrowthInside_worksCorrectlyWithOverflowOnInsideTick() (gas: 144658) -TickTest:testTick_tickSpacingToMaxLiquidityPerTick_gasCost60TickSpacing() (gas: 77509) -TickTest:testTick_tickSpacingToMaxLiquidityPerTick_gasCostMaxTickSpacing() (gas: 77509) -TickTest:testTick_tickSpacingToMaxLiquidityPerTick_gasCostMinTickSpacing() (gas: 77511) -TickTest:testTick_tickSpacingToMaxLiquidityPerTick_returnsTheCorrectValueFor2302() (gas: 4818) -TickTest:testTick_tickSpacingToMaxLiquidityPerTick_returnsTheCorrectValueForEntireRange() (gas: 4989) -TickTest:testTick_tickSpacingToMaxLiquidityPerTick_returnsTheCorrectValueForHighFee() (gas: 4796) -TickTest:testTick_tickSpacingToMaxLiquidityPerTick_returnsTheCorrectValueForLowFee() (gas: 4819) -TickTest:testTick_tickSpacingToMaxLiquidityPerTick_returnsTheCorrectValueForMaxTickSpacing() (gas: 4795) -TickTest:testTick_tickSpacingToMaxLiquidityPerTick_returnsTheCorrectValueForMediumFee() (gas: 4817) -TickTest:testTick_tickSpacingToMaxLiquidityPerTick_returnsTheCorrectValueForMinTickSpacing() (gas: 4796) -TickTest:testTick_tickSpacingToParametersInvariants_fuzz(int24) (runs: 1000, μ: 11353, ~: 11496) -TickTest:testTick_update_assumesAllGrowthHappensBelowTicksLteCurrentTick() (gas: 138024) -TickTest:testTick_update_doesNotFlipFromNonzeroToGreaterNonzero() (gas: 39013) -TickTest:testTick_update_doesNotFlipFromNonzeroToLesserZero() (gas: 39062) -TickTest:testTick_update_doesNotSetAnyGrowthFieldsForTicksGtCurrentTick() (gas: 97561) -TickTest:testTick_update_doesNotSetAnyGrowthFieldsIfTickIsAlreadyInitialized() (gas: 139329) -TickTest:testTick_update_flipsFromNonzeroToZero() (gas: 27017) -TickTest:testTick_update_flipsFromZeroToNonzero() (gas: 37778) -TickTest:testTick_update_fuzz(uint128,int128,int128,bool) (runs: 1000, μ: 34414, ~: 9597) -TickTest:testTick_update_liquidityParsing_parsesMaxInt128StoredLiquidityGrossAfterUpdate() (gas: 98800) -TickTest:testTick_update_liquidityParsing_parsesMaxInt128StoredLiquidityGrossBeforeUpdate() (gas: 98671) -TickTest:testTick_update_liquidityParsing_parsesMaxUint128StoredLiquidityGrossAfterUpdate() (gas: 98799) -TickTest:testTick_update_liquidityParsing_parsesMaxUint128StoredLiquidityGrossBeforeUpdate() (gas: 98415) -TickTest:testTick_update_netsTheLiquidityBasedOnUpperFlag() (gas: 42403) -TickTest:testTick_update_revertsOnOverflowLiquidityGross() (gas: 38851) -TickTest:test_getPoolBitmapInfo(int16,uint256) (runs: 1000, μ: 25364, ~: 25484) -TickTest:test_getPoolTickInfo(int24,(uint128,int128,uint256,uint256)) (runs: 1000, μ: 71694, ~: 72212) -UnsafeMathTest:test_divRoundingUp_RoundsUp() (gas: 3214) -UnsafeMathTest:test_divRoundingUp_maxInput() (gas: 3137) -UnsafeMathTest:test_divRoundingUp_zeroDoesNotRevert(uint256) (runs: 1000, μ: 275, ~: 275) -UnsafeMathTest:test_fuzz_divRoundingUp(uint256,uint256) (runs: 1000, μ: 3816, ~: 3822) -UnsafeMathTest:test_invariant_divRoundingUp(uint256,uint256) (runs: 1000, μ: 3824, ~: 3824) \ No newline at end of file From 72be6c552b2ae5e62e631368eaf2f66328004761 Mon Sep 17 00:00:00 2001 From: Shuhui Luo <107524008+shuhuiluo@users.noreply.github.com> Date: Sun, 26 May 2024 16:43:49 -0400 Subject: [PATCH 15/16] Address review comment --- src/libraries/SwapMath.sol | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libraries/SwapMath.sol b/src/libraries/SwapMath.sol index ec29a87f1..8e3321932 100644 --- a/src/libraries/SwapMath.sol +++ b/src/libraries/SwapMath.sol @@ -51,7 +51,7 @@ library SwapMath { uint24 feePips ) internal pure returns (uint160 sqrtPriceNextX96, uint256 amountIn, uint256 amountOut, uint256 feeAmount) { unchecked { - uint256 _feePips = feePips; // cast once and cache + uint256 _feePips = feePips; // upcast once and cache bool zeroForOne = sqrtPriceCurrentX96 >= sqrtPriceTargetX96; bool exactIn = amountRemaining < 0; @@ -91,7 +91,7 @@ library SwapMath { // cap the output amount to not exceed the remaining output amount amountOut = uint256(amountRemaining); sqrtPriceNextX96 = SqrtPriceMath.getNextSqrtPriceFromOutput( - sqrtPriceCurrentX96, liquidity, uint256(amountRemaining), zeroForOne + sqrtPriceCurrentX96, liquidity, amountOut, zeroForOne ); } amountIn = zeroForOne From 1b9d60ec54d3b47a2e319779e9a090bb34554893 Mon Sep 17 00:00:00 2001 From: Shuhui Luo <107524008+shuhuiluo@users.noreply.github.com> Date: Sun, 26 May 2024 16:45:51 -0400 Subject: [PATCH 16/16] fmt --- src/libraries/SwapMath.sol | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/libraries/SwapMath.sol b/src/libraries/SwapMath.sol index 8e3321932..264a02e07 100644 --- a/src/libraries/SwapMath.sol +++ b/src/libraries/SwapMath.sol @@ -90,9 +90,8 @@ library SwapMath { } else { // cap the output amount to not exceed the remaining output amount amountOut = uint256(amountRemaining); - sqrtPriceNextX96 = SqrtPriceMath.getNextSqrtPriceFromOutput( - sqrtPriceCurrentX96, liquidity, amountOut, zeroForOne - ); + sqrtPriceNextX96 = + SqrtPriceMath.getNextSqrtPriceFromOutput(sqrtPriceCurrentX96, liquidity, amountOut, zeroForOne); } amountIn = zeroForOne ? SqrtPriceMath.getAmount0Delta(sqrtPriceNextX96, sqrtPriceCurrentX96, liquidity, true)