From 503d1906b1122ab8b7ce3c74a534b53273767c9e Mon Sep 17 00:00:00 2001 From: saucepoint Date: Tue, 14 Jan 2025 18:51:05 -0500 Subject: [PATCH 1/7] m02 and liquidity tests --- test/ModifyLiquidity.t.sol | 116 +++++++++++++++++++++++++++++++++++++ 1 file changed, 116 insertions(+) diff --git a/test/ModifyLiquidity.t.sol b/test/ModifyLiquidity.t.sol index 007e41658..bab7f5875 100644 --- a/test/ModifyLiquidity.t.sol +++ b/test/ModifyLiquidity.t.sol @@ -19,6 +19,8 @@ import {Fuzzers} from "../src/test/Fuzzers.sol"; import {TickMath} from "src/libraries/TickMath.sol"; import {toBalanceDelta} from "src/types/BalanceDelta.sol"; import {Logger} from "./utils/Logger.sol"; +import {PoolSwapTest} from "../src/test/PoolSwapTest.sol"; +import "forge-std/console2.sol"; contract ModifyLiquidityTest is Test, Logger, Deployers, JavascriptFfi, Fuzzers { using StateLibrary for IPoolManager; @@ -312,4 +314,118 @@ contract ModifyLiquidityTest is Test, Logger, Deployers, JavascriptFfi, Fuzzers modifyLiquidityRouter.modifyLiquidity(simpleKey, LIQ_PARAM_SALT, ZERO_BYTES); vm.snapshotGasLastCall("add liquidity to already existing position with salt"); } + + /// @dev verify that liquidity positions are not impacted by m02 + /// i.e. slot0.tick = -61 and slot0.sqrtPriceX96 = sqrtPriceAtTick(-60) + /// a user cannot adjust slot0.sqrtPriceX96 to withdraw 2 tokens on the range [-120, -60] + /// because a small trade will realign the tick to -60 + function test_modifyLiquidity_m02_tickUpper() public { + assertEq(simpleKey.tickSpacing, 60); + LIQ_PARAM_SALT.liquidityDelta = 10_000e18; // add a lot of liquidity + + // Add to range [-120, 120] + modifyLiquidityRouter.modifyLiquidity(simpleKey, LIQ_PARAM_SALT, ZERO_BYTES); + + // Add to range [-120, -60] + uint256 balance0Before = currency0.balanceOfSelf(); + uint256 balance1Before = currency1.balanceOfSelf(); + LIQ_PARAM_SALT.tickLower = -120; + LIQ_PARAM_SALT.tickUpper = -60; + LIQ_PARAM_SALT.liquidityDelta = 1e18; + modifyLiquidityRouter.modifyLiquidity(simpleKey, LIQ_PARAM_SALT, ZERO_BYTES); + + // paid token1 + assertGt(balance1Before, currency1.balanceOfSelf()); + // did not pay token0 + assertEq(balance0Before, currency0.balanceOfSelf()); + + // push the price to tick = -60 + IPoolManager.SwapParams memory swapParams = IPoolManager.SwapParams({ + zeroForOne: true, + amountSpecified: -1000e18, + sqrtPriceLimitX96: TickMath.getSqrtPriceAtTick(-60) + }); + PoolSwapTest.TestSettings memory testSettings = + PoolSwapTest.TestSettings({takeClaims: false, settleUsingBurn: false}); + swapRouter.swap(simpleKey, swapParams, testSettings, ZERO_BYTES); + + // validate m02: tick and sqrtPriceX96 disagree + (uint160 sqrtPriceX96, int24 tick,,) = manager.getSlot0(simplePoolId); + assertEq(tick, -61); + assertEq(sqrtPriceX96, TickMath.getSqrtPriceAtTick(-60)); + assertEq(TickMath.getTickAtSqrtPrice(sqrtPriceX96), -60); + + // push the price just slightly + swapParams.zeroForOne = false; + swapParams.amountSpecified = -1; + swapParams.sqrtPriceLimitX96 = MAX_PRICE_LIMIT; + swapRouter.swap(simpleKey, swapParams, testSettings, ZERO_BYTES); + + // even with a 1 wei trade, the tick realigns + (sqrtPriceX96, tick,,) = manager.getSlot0(simplePoolId); + assertEq(tick, -60); + assertEq(TickMath.getTickAtSqrtPrice(sqrtPriceX96), -60); + + // withdraw liquidity and receive token1 only + balance0Before = currency0.balanceOfSelf(); + balance1Before = currency1.balanceOfSelf(); + LIQ_PARAM_SALT.liquidityDelta = -1e18; + modifyLiquidityRouter.modifyLiquidity(simpleKey, LIQ_PARAM_SALT, ZERO_BYTES); + + // receive token1 + assertGt(currency1.balanceOfSelf(), balance1Before); + // did not receive token0 + assertEq(balance0Before, currency0.balanceOfSelf()); + } + + /// @dev verify that liquidity positions are not impacted by m02 + /// i.e. slot0.tick = -61 and slot0.sqrtPriceX96 = sqrtPriceAtTick(-60) + /// when withdrawing liquidity on the range [-120, -60], it is not possible to withdraw 2 tokens + function test_modifyLiquidity_m02_tickUpper_2() public { + assertEq(simpleKey.tickSpacing, 60); + LIQ_PARAM_SALT.liquidityDelta = 10_000e18; + + // Add to range [-120, 120] + modifyLiquidityRouter.modifyLiquidity(simpleKey, LIQ_PARAM_SALT, ZERO_BYTES); + + // Add to range [-120, -60] + uint256 balance0Before = currency0.balanceOfSelf(); + uint256 balance1Before = currency1.balanceOfSelf(); + LIQ_PARAM_SALT.tickLower = -120; + LIQ_PARAM_SALT.tickUpper = -60; + LIQ_PARAM_SALT.liquidityDelta = 1e18; + modifyLiquidityRouter.modifyLiquidity(simpleKey, LIQ_PARAM_SALT, ZERO_BYTES); + + // paid token1 + assertGt(balance1Before, currency1.balanceOfSelf()); + // did not pay token0 + assertEq(balance0Before, currency0.balanceOfSelf()); + + // push the price to tick = -60 + IPoolManager.SwapParams memory swapParams = IPoolManager.SwapParams({ + zeroForOne: true, + amountSpecified: -200e18, + sqrtPriceLimitX96: TickMath.getSqrtPriceAtTick(-60) + }); + PoolSwapTest.TestSettings memory testSettings = + PoolSwapTest.TestSettings({takeClaims: false, settleUsingBurn: false}); + swapRouter.swap(simpleKey, swapParams, testSettings, ZERO_BYTES); + + // validate m02: tick and sqrtPriceX96 disagree + (uint160 sqrtPriceX96, int24 tick,,) = manager.getSlot0(simplePoolId); + assertEq(tick, -61); + assertEq(sqrtPriceX96, TickMath.getSqrtPriceAtTick(-60)); + assertEq(TickMath.getTickAtSqrtPrice(sqrtPriceX96), -60); + + // withdraw liquidity and receive token1 only + balance0Before = currency0.balanceOfSelf(); + balance1Before = currency1.balanceOfSelf(); + LIQ_PARAM_SALT.liquidityDelta = -1e18; + modifyLiquidityRouter.modifyLiquidity(simpleKey, LIQ_PARAM_SALT, ZERO_BYTES); + + // receive token1 + assertGt(currency1.balanceOfSelf(), balance1Before); + // did not receive token0 + assertEq(balance0Before, currency0.balanceOfSelf()); + } } From b215f041ead172e88f7212ac5fb3ab2850b70780 Mon Sep 17 00:00:00 2001 From: saucepoint Date: Tue, 14 Jan 2025 18:54:29 -0500 Subject: [PATCH 2/7] remove console --- test/ModifyLiquidity.t.sol | 1 - 1 file changed, 1 deletion(-) diff --git a/test/ModifyLiquidity.t.sol b/test/ModifyLiquidity.t.sol index bab7f5875..716be0a96 100644 --- a/test/ModifyLiquidity.t.sol +++ b/test/ModifyLiquidity.t.sol @@ -20,7 +20,6 @@ import {TickMath} from "src/libraries/TickMath.sol"; import {toBalanceDelta} from "src/types/BalanceDelta.sol"; import {Logger} from "./utils/Logger.sol"; import {PoolSwapTest} from "../src/test/PoolSwapTest.sol"; -import "forge-std/console2.sol"; contract ModifyLiquidityTest is Test, Logger, Deployers, JavascriptFfi, Fuzzers { using StateLibrary for IPoolManager; From fb8769261e6601dc1f99fdba750814bc0c37d28b Mon Sep 17 00:00:00 2001 From: saucepoint Date: Tue, 14 Jan 2025 22:25:52 -0500 Subject: [PATCH 3/7] add test for tickLower --- test/ModifyLiquidity.t.sol | 86 +++++++++++++++++++++++++++++++------- test/utils/Deployers.sol | 6 ++- 2 files changed, 74 insertions(+), 18 deletions(-) diff --git a/test/ModifyLiquidity.t.sol b/test/ModifyLiquidity.t.sol index 716be0a96..1fcb37f7e 100644 --- a/test/ModifyLiquidity.t.sol +++ b/test/ModifyLiquidity.t.sol @@ -20,6 +20,7 @@ import {TickMath} from "src/libraries/TickMath.sol"; import {toBalanceDelta} from "src/types/BalanceDelta.sol"; import {Logger} from "./utils/Logger.sol"; import {PoolSwapTest} from "../src/test/PoolSwapTest.sol"; +import "forge-std/console2.sol"; contract ModifyLiquidityTest is Test, Logger, Deployers, JavascriptFfi, Fuzzers { using StateLibrary for IPoolManager; @@ -314,13 +315,13 @@ contract ModifyLiquidityTest is Test, Logger, Deployers, JavascriptFfi, Fuzzers vm.snapshotGasLastCall("add liquidity to already existing position with salt"); } - /// @dev verify that liquidity positions are not impacted by m02 + /// @dev verify that liquidity positions are not impacted by m02, at the upper tick /// i.e. slot0.tick = -61 and slot0.sqrtPriceX96 = sqrtPriceAtTick(-60) /// a user cannot adjust slot0.sqrtPriceX96 to withdraw 2 tokens on the range [-120, -60] /// because a small trade will realign the tick to -60 function test_modifyLiquidity_m02_tickUpper() public { - assertEq(simpleKey.tickSpacing, 60); - LIQ_PARAM_SALT.liquidityDelta = 10_000e18; // add a lot of liquidity + // fee-less pool to ensure liquidity withdrawals are not impacted by fees + (simpleKey, simplePoolId) = initPool(currency0, currency1, IHooks(address(0)), 0, 60, SQRT_PRICE_1_1); // Add to range [-120, 120] modifyLiquidityRouter.modifyLiquidity(simpleKey, LIQ_PARAM_SALT, ZERO_BYTES); @@ -341,12 +342,10 @@ contract ModifyLiquidityTest is Test, Logger, Deployers, JavascriptFfi, Fuzzers // push the price to tick = -60 IPoolManager.SwapParams memory swapParams = IPoolManager.SwapParams({ zeroForOne: true, - amountSpecified: -1000e18, + amountSpecified: -10_000e18, sqrtPriceLimitX96: TickMath.getSqrtPriceAtTick(-60) }); - PoolSwapTest.TestSettings memory testSettings = - PoolSwapTest.TestSettings({takeClaims: false, settleUsingBurn: false}); - swapRouter.swap(simpleKey, swapParams, testSettings, ZERO_BYTES); + swapRouter.swap(simpleKey, swapParams, SWAP_SETTINGS, ZERO_BYTES); // validate m02: tick and sqrtPriceX96 disagree (uint160 sqrtPriceX96, int24 tick,,) = manager.getSlot0(simplePoolId); @@ -356,9 +355,9 @@ contract ModifyLiquidityTest is Test, Logger, Deployers, JavascriptFfi, Fuzzers // push the price just slightly swapParams.zeroForOne = false; - swapParams.amountSpecified = -1; + swapParams.amountSpecified = -1 wei; swapParams.sqrtPriceLimitX96 = MAX_PRICE_LIMIT; - swapRouter.swap(simpleKey, swapParams, testSettings, ZERO_BYTES); + swapRouter.swap(simpleKey, swapParams, SWAP_SETTINGS, ZERO_BYTES); // even with a 1 wei trade, the tick realigns (sqrtPriceX96, tick,,) = manager.getSlot0(simplePoolId); @@ -377,12 +376,12 @@ contract ModifyLiquidityTest is Test, Logger, Deployers, JavascriptFfi, Fuzzers assertEq(balance0Before, currency0.balanceOfSelf()); } - /// @dev verify that liquidity positions are not impacted by m02 + /// @dev verify that liquidity positions are not impacted by m02, at the upper tick /// i.e. slot0.tick = -61 and slot0.sqrtPriceX96 = sqrtPriceAtTick(-60) /// when withdrawing liquidity on the range [-120, -60], it is not possible to withdraw 2 tokens - function test_modifyLiquidity_m02_tickUpper_2() public { - assertEq(simpleKey.tickSpacing, 60); - LIQ_PARAM_SALT.liquidityDelta = 10_000e18; + function test_modifyLiquidity_m02_tickUpper_withoutSwap() public { + // fee-less pool to ensure liquidity withdrawals are not impacted by fees + (simpleKey, simplePoolId) = initPool(currency0, currency1, IHooks(address(0)), 0, 60, SQRT_PRICE_1_1); // Add to range [-120, 120] modifyLiquidityRouter.modifyLiquidity(simpleKey, LIQ_PARAM_SALT, ZERO_BYTES); @@ -406,9 +405,7 @@ contract ModifyLiquidityTest is Test, Logger, Deployers, JavascriptFfi, Fuzzers amountSpecified: -200e18, sqrtPriceLimitX96: TickMath.getSqrtPriceAtTick(-60) }); - PoolSwapTest.TestSettings memory testSettings = - PoolSwapTest.TestSettings({takeClaims: false, settleUsingBurn: false}); - swapRouter.swap(simpleKey, swapParams, testSettings, ZERO_BYTES); + swapRouter.swap(simpleKey, swapParams, SWAP_SETTINGS, ZERO_BYTES); // validate m02: tick and sqrtPriceX96 disagree (uint160 sqrtPriceX96, int24 tick,,) = manager.getSlot0(simplePoolId); @@ -427,4 +424,61 @@ contract ModifyLiquidityTest is Test, Logger, Deployers, JavascriptFfi, Fuzzers // did not receive token0 assertEq(balance0Before, currency0.balanceOfSelf()); } + + /// @dev verify that liquidity positions are not impacted by m02 on tickLower + /// LP range [60, 120], tick = 59, sqrtPriceX96 = sqrtPriceAtTick(60) + function test_modifyLiquidity_m02_tickLower() public { + // fee-less pool to ensure liquidity withdrawals are not impacted by fees + (simpleKey, simplePoolId) = initPool(currency0, currency1, IHooks(address(0)), 0, 60, SQRT_PRICE_1_1); + + // Add to range [-120, 120] + modifyLiquidityRouter.modifyLiquidity(simpleKey, LIQ_PARAM_SALT, ZERO_BYTES); + + // Add to range [60, 120] + uint256 balance0Before = currency0.balanceOfSelf(); + uint256 balance1Before = currency1.balanceOfSelf(); + LIQ_PARAM_SALT.tickLower = 60; + LIQ_PARAM_SALT.tickUpper = 120; + LIQ_PARAM_SALT.liquidityDelta = 1e18; + modifyLiquidityRouter.modifyLiquidity(simpleKey, LIQ_PARAM_SALT, ZERO_BYTES); + + // paid token0 + assertGt(balance0Before, currency0.balanceOfSelf()); + // did not pay token1 + assertEq(balance1Before, currency1.balanceOfSelf()); + + // push the price to tick = 61 + IPoolManager.SwapParams memory swapParams = IPoolManager.SwapParams({ + zeroForOne: false, + amountSpecified: -20000e18, + sqrtPriceLimitX96: TickMath.getSqrtPriceAtTick(61) + }); + swapRouter.swap(simpleKey, swapParams, SWAP_SETTINGS, ZERO_BYTES); + (uint160 sqrtPriceX96, int24 tick,,) = manager.getSlot0(simplePoolId); + assertEq(tick, 61); + assertEq(sqrtPriceX96, TickMath.getSqrtPriceAtTick(61)); + assertEq(TickMath.getTickAtSqrtPrice(sqrtPriceX96), 61); + + // push the price to tick = 60, but tick is set to 59 because of m02 behavior + swapParams.zeroForOne = true; + swapParams.sqrtPriceLimitX96 = TickMath.getSqrtPriceAtTick(60); + swapRouter.swap(simpleKey, swapParams, SWAP_SETTINGS, ZERO_BYTES); + + // validate m02: tick and sqrtPriceX96 disagree + (sqrtPriceX96, tick,,) = manager.getSlot0(simplePoolId); + assertEq(tick, 59); + assertEq(sqrtPriceX96, TickMath.getSqrtPriceAtTick(60)); + assertEq(TickMath.getTickAtSqrtPrice(sqrtPriceX96), 60); + + // withdraw liquidity and receive token0 only + balance0Before = currency0.balanceOfSelf(); + balance1Before = currency1.balanceOfSelf(); + LIQ_PARAM_SALT.liquidityDelta = -1e18; + modifyLiquidityRouter.modifyLiquidity(simpleKey, LIQ_PARAM_SALT, ZERO_BYTES); + + // receive token0 + assertGt(currency0.balanceOfSelf(), balance0Before); + // did not receive token1 + assertEq(balance1Before, currency1.balanceOfSelf()); + } } diff --git a/test/utils/Deployers.sol b/test/utils/Deployers.sol index 88559148b..6a4fefcb7 100644 --- a/test/utils/Deployers.sol +++ b/test/utils/Deployers.sol @@ -48,6 +48,8 @@ contract Deployers is Test { IPoolManager.ModifyLiquidityParams({tickLower: -120, tickUpper: 120, liquidityDelta: -1e18, salt: 0}); IPoolManager.SwapParams public SWAP_PARAMS = IPoolManager.SwapParams({zeroForOne: true, amountSpecified: -100, sqrtPriceLimitX96: SQRT_PRICE_1_2}); + PoolSwapTest.TestSettings public SWAP_SETTINGS = + PoolSwapTest.TestSettings({takeClaims: false, settleUsingBurn: false}); // Global variables Currency internal currency0; @@ -227,7 +229,7 @@ contract Deployers is Test { amountSpecified: amountSpecified, sqrtPriceLimitX96: zeroForOne ? MIN_PRICE_LIMIT : MAX_PRICE_LIMIT }), - PoolSwapTest.TestSettings({takeClaims: false, settleUsingBurn: false}), + SWAP_SETTINGS, hookData ); } @@ -272,7 +274,7 @@ contract Deployers is Test { amountSpecified: amountSpecified, sqrtPriceLimitX96: zeroForOne ? MIN_PRICE_LIMIT : MAX_PRICE_LIMIT }), - PoolSwapTest.TestSettings({takeClaims: false, settleUsingBurn: false}), + SWAP_SETTINGS, hookData ); } From 455debfa3df25dbd8dc21a131459ddf6bb06ef4c Mon Sep 17 00:00:00 2001 From: saucepoint Date: Tue, 14 Jan 2025 23:05:22 -0500 Subject: [PATCH 4/7] verify m02 --- test/PoolManager.t.sol | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/test/PoolManager.t.sol b/test/PoolManager.t.sol index de050bf60..aa6d734f4 100644 --- a/test/PoolManager.t.sol +++ b/test/PoolManager.t.sol @@ -1198,6 +1198,42 @@ contract PoolManagerTest is Test, Deployers { nestedActionRouter.unlock(abi.encode(_actions)); } + /// @dev verify that m02 behavior only occurs for zeroForOne trades (moving tick towards negative infinity) + /// and only occurs when sqrtPriceLimit is equal to getSqrtPriceAtTick() + function test_slot0_tick_sqrtPrice_m02(bool zeroForOne, int8 tickOffset) public { + PoolId poolId = key.toId(); + (, int24 currentTick,,) = manager.getSlot0(poolId); + assertEq(key.tickSpacing, 60); + assertEq(currentTick, 0); + + // Add full range liquidity + LIQUIDITY_PARAMS.tickLower = TickMath.minUsableTick(key.tickSpacing); + LIQUIDITY_PARAMS.tickUpper = TickMath.maxUsableTick(key.tickSpacing); + modifyLiquidityRouter.modifyLiquidity(key, LIQUIDITY_PARAMS, ZERO_BYTES); + + int24 targetTick = zeroForOne ? -int24(180) : int24(180); + targetTick += int24(tickOffset); // fuzz target tick 180 +/- 128 + IPoolManager.SwapParams memory swapParams = IPoolManager.SwapParams({ + zeroForOne: zeroForOne, + amountSpecified: -100_000_000e18, + sqrtPriceLimitX96: TickMath.getSqrtPriceAtTick(targetTick) + }); + swapRouter.swap(key, swapParams, SWAP_SETTINGS, ZERO_BYTES); + + (uint160 sqrtPriceX96, int24 tick,,) = manager.getSlot0(poolId); + if (zeroForOne && (targetTick % key.tickSpacing == 0)) { + // for zeroForOne trades (moving tick towards negative infinity), if the slot0.sqrtPrice lands exactly + // on a tick, the slot0.tick should be decremented by one + assertEq(tick, targetTick - 1, "M02 behavior"); + assertEq(sqrtPriceX96, TickMath.getSqrtPriceAtTick(targetTick)); + assertEq(targetTick, TickMath.getTickAtSqrtPrice(sqrtPriceX96)); + } else { + assertEq(tick, targetTick); + assertEq(sqrtPriceX96, TickMath.getSqrtPriceAtTick(targetTick)); + assertEq(tick, TickMath.getTickAtSqrtPrice(sqrtPriceX96)); + } + } + // function testExtsloadForPoolPrice() public { // IPoolManager.key = IPoolManager.PoolKey({ // currency0: currency0, From f69488c51fda68afd31abdd9de93eaf968d553ad Mon Sep 17 00:00:00 2001 From: saucepoint Date: Wed, 15 Jan 2025 10:59:29 -0500 Subject: [PATCH 5/7] fix test by initializing ticks with LP positions --- test/PoolManager.t.sol | 31 ++++++++++++++++++++++++------- 1 file changed, 24 insertions(+), 7 deletions(-) diff --git a/test/PoolManager.t.sol b/test/PoolManager.t.sol index aa6d734f4..e84605b64 100644 --- a/test/PoolManager.t.sol +++ b/test/PoolManager.t.sol @@ -1211,27 +1211,44 @@ contract PoolManagerTest is Test, Deployers { LIQUIDITY_PARAMS.tickUpper = TickMath.maxUsableTick(key.tickSpacing); modifyLiquidityRouter.modifyLiquidity(key, LIQUIDITY_PARAMS, ZERO_BYTES); + // Create positions such that [-240, -120, -60, 120, 180, 300] are initialized + LIQUIDITY_PARAMS.tickLower = -240; + LIQUIDITY_PARAMS.tickUpper = -120; + modifyLiquidityRouter.modifyLiquidity(key, LIQUIDITY_PARAMS, ZERO_BYTES); + + LIQUIDITY_PARAMS.tickLower = -60; + LIQUIDITY_PARAMS.tickUpper = 120; + modifyLiquidityRouter.modifyLiquidity(key, LIQUIDITY_PARAMS, ZERO_BYTES); + + LIQUIDITY_PARAMS.tickLower = 180; + LIQUIDITY_PARAMS.tickUpper = 300; + modifyLiquidityRouter.modifyLiquidity(key, LIQUIDITY_PARAMS, ZERO_BYTES); + + // fuzz target tick 180 +/- 128 int24 targetTick = zeroForOne ? -int24(180) : int24(180); - targetTick += int24(tickOffset); // fuzz target tick 180 +/- 128 + targetTick += int24(tickOffset); + + uint160 targetSqrtPrice = TickMath.getSqrtPriceAtTick(targetTick); IPoolManager.SwapParams memory swapParams = IPoolManager.SwapParams({ zeroForOne: zeroForOne, amountSpecified: -100_000_000e18, - sqrtPriceLimitX96: TickMath.getSqrtPriceAtTick(targetTick) + sqrtPriceLimitX96: targetSqrtPrice }); swapRouter.swap(key, swapParams, SWAP_SETTINGS, ZERO_BYTES); (uint160 sqrtPriceX96, int24 tick,,) = manager.getSlot0(poolId); - if (zeroForOne && (targetTick % key.tickSpacing == 0)) { + if (zeroForOne && (targetTick == -240 || targetTick == -120 || targetTick == -60)) { // for zeroForOne trades (moving tick towards negative infinity), if the slot0.sqrtPrice lands exactly // on a tick, the slot0.tick should be decremented by one assertEq(tick, targetTick - 1, "M02 behavior"); - assertEq(sqrtPriceX96, TickMath.getSqrtPriceAtTick(targetTick)); - assertEq(targetTick, TickMath.getTickAtSqrtPrice(sqrtPriceX96)); } else { + // non-M02 behavior where slot0.tick is pushed to the target tick assertEq(tick, targetTick); - assertEq(sqrtPriceX96, TickMath.getSqrtPriceAtTick(targetTick)); - assertEq(tick, TickMath.getTickAtSqrtPrice(sqrtPriceX96)); } + + // price (slot0.sqrtPriceX96) was pushed to the desired price + assertEq(sqrtPriceX96, targetSqrtPrice); + assertEq(targetTick, TickMath.getTickAtSqrtPrice(sqrtPriceX96)); } // function testExtsloadForPoolPrice() public { From 1f420d88041317a13c0d963d955b9c26b8c9ba4a Mon Sep 17 00:00:00 2001 From: saucepoint Date: Wed, 15 Jan 2025 11:26:46 -0500 Subject: [PATCH 6/7] remove console; forge fmt --- test/ModifyLiquidity.t.sol | 1 - test/PoolManager.t.sol | 4 ++-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/test/ModifyLiquidity.t.sol b/test/ModifyLiquidity.t.sol index 1fcb37f7e..8b7ac0cb7 100644 --- a/test/ModifyLiquidity.t.sol +++ b/test/ModifyLiquidity.t.sol @@ -20,7 +20,6 @@ import {TickMath} from "src/libraries/TickMath.sol"; import {toBalanceDelta} from "src/types/BalanceDelta.sol"; import {Logger} from "./utils/Logger.sol"; import {PoolSwapTest} from "../src/test/PoolSwapTest.sol"; -import "forge-std/console2.sol"; contract ModifyLiquidityTest is Test, Logger, Deployers, JavascriptFfi, Fuzzers { using StateLibrary for IPoolManager; diff --git a/test/PoolManager.t.sol b/test/PoolManager.t.sol index e84605b64..aa44585e0 100644 --- a/test/PoolManager.t.sol +++ b/test/PoolManager.t.sol @@ -1205,7 +1205,7 @@ contract PoolManagerTest is Test, Deployers { (, int24 currentTick,,) = manager.getSlot0(poolId); assertEq(key.tickSpacing, 60); assertEq(currentTick, 0); - + // Add full range liquidity LIQUIDITY_PARAMS.tickLower = TickMath.minUsableTick(key.tickSpacing); LIQUIDITY_PARAMS.tickUpper = TickMath.maxUsableTick(key.tickSpacing); @@ -1227,7 +1227,7 @@ contract PoolManagerTest is Test, Deployers { // fuzz target tick 180 +/- 128 int24 targetTick = zeroForOne ? -int24(180) : int24(180); targetTick += int24(tickOffset); - + uint160 targetSqrtPrice = TickMath.getSqrtPriceAtTick(targetTick); IPoolManager.SwapParams memory swapParams = IPoolManager.SwapParams({ zeroForOne: zeroForOne, From f0daf06e01cfda0c67a20ff355cc3bb5127b044e Mon Sep 17 00:00:00 2001 From: saucepoint Date: Wed, 15 Jan 2025 11:31:15 -0500 Subject: [PATCH 7/7] unused import --- test/ModifyLiquidity.t.sol | 1 - 1 file changed, 1 deletion(-) diff --git a/test/ModifyLiquidity.t.sol b/test/ModifyLiquidity.t.sol index 8b7ac0cb7..44e86bff4 100644 --- a/test/ModifyLiquidity.t.sol +++ b/test/ModifyLiquidity.t.sol @@ -19,7 +19,6 @@ import {Fuzzers} from "../src/test/Fuzzers.sol"; import {TickMath} from "src/libraries/TickMath.sol"; import {toBalanceDelta} from "src/types/BalanceDelta.sol"; import {Logger} from "./utils/Logger.sol"; -import {PoolSwapTest} from "../src/test/PoolSwapTest.sol"; contract ModifyLiquidityTest is Test, Logger, Deployers, JavascriptFfi, Fuzzers { using StateLibrary for IPoolManager;