From f92010746b9152ebc817e16a6e46a8e1edd9512c Mon Sep 17 00:00:00 2001 From: gretzke Date: Tue, 26 Nov 2024 01:24:45 +0100 Subject: [PATCH 01/20] add compilation restrictions --- .../BaseActionsRouter_mock10commands.snap | 2 +- ...p_settleFromCaller_takeAllToMsgSender.snap | 2 +- ...eFromCaller_takeAllToSpecifiedAddress.snap | 2 +- ..._settleWithBalance_takeAllToMsgSender.snap | 2 +- ...WithBalance_takeAllToSpecifiedAddress.snap | 2 +- .../PositionManager_burn_empty.snap | 2 +- .../PositionManager_burn_empty_native.snap | 2 +- ...anager_burn_nonEmpty_native_withClose.snap | 2 +- ...ger_burn_nonEmpty_native_withTakePair.snap | 2 +- ...sitionManager_burn_nonEmpty_withClose.snap | 2 +- ...ionManager_burn_nonEmpty_withTakePair.snap | 2 +- .../PositionManager_collect_native.snap | 2 +- .../PositionManager_collect_sameRange.snap | 2 +- .../PositionManager_collect_withClose.snap | 2 +- .../PositionManager_collect_withTakePair.snap | 2 +- ...itionManager_decreaseLiquidity_native.snap | 2 +- ...onManager_decreaseLiquidity_withClose.snap | 2 +- ...anager_decreaseLiquidity_withTakePair.snap | 2 +- .../PositionManager_decrease_burnEmpty.snap | 2 +- ...tionManager_decrease_burnEmpty_native.snap | 2 +- ...nager_decrease_sameRange_allLiquidity.snap | 2 +- .../PositionManager_decrease_take_take.snap | 2 +- ...ger_increaseLiquidity_erc20_withClose.snap | 2 +- ...ncreaseLiquidity_erc20_withSettlePair.snap | 2 +- ...itionManager_increaseLiquidity_native.snap | 2 +- ...crease_autocompoundExactUnclaimedFees.snap | 2 +- ...increase_autocompoundExcessFeesCredit.snap | 2 +- ...ger_increase_autocompound_clearExcess.snap | 2 +- .../PositionManager_mint_native.snap | 2 +- ...anager_mint_nativeWithSweep_withClose.snap | 2 +- ...r_mint_nativeWithSweep_withSettlePair.snap | 2 +- .../PositionManager_mint_onSameTickLower.snap | 2 +- .../PositionManager_mint_onSameTickUpper.snap | 2 +- .../PositionManager_mint_sameRange.snap | 2 +- ...nManager_mint_settleWithBalance_sweep.snap | 2 +- ...anager_mint_warmedPool_differentRange.snap | 2 +- .../PositionManager_mint_withClose.snap | 2 +- .../PositionManager_mint_withSettlePair.snap | 2 +- ...tionManager_multicall_initialize_mint.snap | 2 +- .forge-snapshots/PositionManager_permit.snap | 2 +- ...PositionManager_permit_secondPosition.snap | 2 +- .../PositionManager_permit_twice.snap | 2 +- .../PositionManager_subscribe.snap | 2 +- .../PositionManager_unsubscribe.snap | 2 +- ...utSingle_oneForZero_multiplePositions.snap | 2 +- ...utSingle_zeroForOne_multiplePositions.snap | 2 +- .../Quoter_exactOutputSingle_oneForZero.snap | 2 +- .../Quoter_exactOutputSingle_zeroForOne.snap | 2 +- ...er_quoteExactInput_oneHop_1TickLoaded.snap | 2 +- ...oteExactInput_oneHop_initializedAfter.snap | 2 +- ...ExactInput_oneHop_startingInitialized.snap | 2 +- .../Quoter_quoteExactInput_twoHops.snap | 2 +- ...r_quoteExactOutput_oneHop_1TickLoaded.snap | 2 +- ..._quoteExactOutput_oneHop_2TicksLoaded.snap | 2 +- ...teExactOutput_oneHop_initializedAfter.snap | 2 +- ...xactOutput_oneHop_startingInitialized.snap | 2 +- .../Quoter_quoteExactOutput_twoHops.snap | 2 +- ...tateView_extsload_getFeeGrowthGlobals.snap | 2 +- ...StateView_extsload_getFeeGrowthInside.snap | 2 +- .../StateView_extsload_getLiquidity.snap | 2 +- .../StateView_extsload_getPositionInfo.snap | 2 +- ...ateView_extsload_getPositionLiquidity.snap | 2 +- .../StateView_extsload_getSlot0.snap | 2 +- .../StateView_extsload_getTickBitmap.snap | 2 +- ...View_extsload_getTickFeeGrowthOutside.snap | 2 +- .../StateView_extsload_getTickInfo.snap | 2 +- .../StateView_extsload_getTickLiquidity.snap | 2 +- .forge-snapshots/V4Router_Bytecode.snap | 2 +- .../V4Router_ExactIn1Hop_nativeIn.snap | 2 +- .../V4Router_ExactIn1Hop_nativeOut.snap | 2 +- .../V4Router_ExactIn1Hop_oneForZero.snap | 2 +- .../V4Router_ExactIn1Hop_zeroForOne.snap | 2 +- .forge-snapshots/V4Router_ExactIn2Hops.snap | 2 +- .../V4Router_ExactIn2Hops_nativeIn.snap | 2 +- .forge-snapshots/V4Router_ExactIn3Hops.snap | 2 +- .../V4Router_ExactIn3Hops_nativeIn.snap | 2 +- .../V4Router_ExactInputSingle.snap | 2 +- .../V4Router_ExactInputSingle_nativeIn.snap | 2 +- .../V4Router_ExactInputSingle_nativeOut.snap | 2 +- ...Router_ExactOut1Hop_nativeIn_sweepETH.snap | 2 +- .../V4Router_ExactOut1Hop_nativeOut.snap | 2 +- .../V4Router_ExactOut1Hop_oneForZero.snap | 2 +- .../V4Router_ExactOut1Hop_zeroForOne.snap | 2 +- .forge-snapshots/V4Router_ExactOut2Hops.snap | 2 +- .../V4Router_ExactOut2Hops_nativeIn.snap | 2 +- .forge-snapshots/V4Router_ExactOut3Hops.snap | 2 +- .../V4Router_ExactOut3Hops_nativeIn.snap | 2 +- .../V4Router_ExactOut3Hops_nativeOut.snap | 2 +- .../V4Router_ExactOutputSingle.snap | 2 +- ...r_ExactOutputSingle_nativeIn_sweepETH.snap | 2 +- .../V4Router_ExactOutputSingle_nativeOut.snap | 2 +- .../positionManager bytecode size.snap | 2 +- foundry.toml | 14 +- script/DeployPosm.s.sol | 16 +- script/DeployStateView.s.sol | 4 +- script/DeployV4Quoter.s.sol | 6 +- src/PositionDescriptor.sol | 14 +- src/base/PoolInitializer.sol | 10 +- src/interfaces/IPoolInitializer.sol | 13 + src/interfaces/IPositionDescriptor.sol | 24 ++ src/interfaces/IPositionManager.sol | 21 +- src/interfaces/IV4Quoter.sol | 3 +- test/PositionDescriptor.t.sol | 396 ++++++++++-------- test/StateViewTest.t.sol | 3 +- test/V4Quoter.t.sol | 7 +- test/mocks/MockBadSubscribers.sol | 10 +- test/mocks/MockReenterHook.sol | 11 +- test/mocks/MockSubscriber.sol | 6 +- test/position-managers/Execute.t.sol | 6 +- test/position-managers/FeeCollection.t.sol | 1 - .../position-managers/IncreaseLiquidity.t.sol | 1 - test/position-managers/NativeToken.t.sol | 11 +- test/position-managers/Permit.t.sol | 2 +- .../PositionManager.gas.t.sol | 5 +- .../PositionManager.modifyLiquidities.t.sol | 159 +++---- .../PositionManager.multicall.t.sol | 35 +- .../PositionManager.notifier.t.sol | 61 +-- test/position-managers/PositionManager.t.sol | 30 +- test/shared/Deploy.sol | 55 +++ test/shared/FeeMath.sol | 1 - test/shared/LiquidityOperations.sol | 5 +- test/shared/PosmTestSetup.sol | 12 +- test/shared/RoutingTestHelpers.sol | 1 - 123 files changed, 634 insertions(+), 493 deletions(-) create mode 100644 src/interfaces/IPoolInitializer.sol create mode 100644 test/shared/Deploy.sol diff --git a/.forge-snapshots/BaseActionsRouter_mock10commands.snap b/.forge-snapshots/BaseActionsRouter_mock10commands.snap index 20e1c5f43..4782eb39b 100644 --- a/.forge-snapshots/BaseActionsRouter_mock10commands.snap +++ b/.forge-snapshots/BaseActionsRouter_mock10commands.snap @@ -1 +1 @@ -61332 \ No newline at end of file +63076 \ No newline at end of file diff --git a/.forge-snapshots/Payments_swap_settleFromCaller_takeAllToMsgSender.snap b/.forge-snapshots/Payments_swap_settleFromCaller_takeAllToMsgSender.snap index 770caaf99..94949b13c 100644 --- a/.forge-snapshots/Payments_swap_settleFromCaller_takeAllToMsgSender.snap +++ b/.forge-snapshots/Payments_swap_settleFromCaller_takeAllToMsgSender.snap @@ -1 +1 @@ -132997 \ No newline at end of file +133006 \ No newline at end of file diff --git a/.forge-snapshots/Payments_swap_settleFromCaller_takeAllToSpecifiedAddress.snap b/.forge-snapshots/Payments_swap_settleFromCaller_takeAllToSpecifiedAddress.snap index 3541eaf39..75de88e95 100644 --- a/.forge-snapshots/Payments_swap_settleFromCaller_takeAllToSpecifiedAddress.snap +++ b/.forge-snapshots/Payments_swap_settleFromCaller_takeAllToSpecifiedAddress.snap @@ -1 +1 @@ -134973 \ No newline at end of file +134475 \ No newline at end of file diff --git a/.forge-snapshots/Payments_swap_settleWithBalance_takeAllToMsgSender.snap b/.forge-snapshots/Payments_swap_settleWithBalance_takeAllToMsgSender.snap index e05cffe7d..e0dd700d5 100644 --- a/.forge-snapshots/Payments_swap_settleWithBalance_takeAllToMsgSender.snap +++ b/.forge-snapshots/Payments_swap_settleWithBalance_takeAllToMsgSender.snap @@ -1 +1 @@ -127102 \ No newline at end of file +126957 \ No newline at end of file diff --git a/.forge-snapshots/Payments_swap_settleWithBalance_takeAllToSpecifiedAddress.snap b/.forge-snapshots/Payments_swap_settleWithBalance_takeAllToSpecifiedAddress.snap index 9166a87da..9390c7055 100644 --- a/.forge-snapshots/Payments_swap_settleWithBalance_takeAllToSpecifiedAddress.snap +++ b/.forge-snapshots/Payments_swap_settleWithBalance_takeAllToSpecifiedAddress.snap @@ -1 +1 @@ -127212 \ No newline at end of file +127095 \ No newline at end of file diff --git a/.forge-snapshots/PositionManager_burn_empty.snap b/.forge-snapshots/PositionManager_burn_empty.snap index 88081af81..a807a6daa 100644 --- a/.forge-snapshots/PositionManager_burn_empty.snap +++ b/.forge-snapshots/PositionManager_burn_empty.snap @@ -1 +1 @@ -51576 \ No newline at end of file +50953 \ No newline at end of file diff --git a/.forge-snapshots/PositionManager_burn_empty_native.snap b/.forge-snapshots/PositionManager_burn_empty_native.snap index 88081af81..a807a6daa 100644 --- a/.forge-snapshots/PositionManager_burn_empty_native.snap +++ b/.forge-snapshots/PositionManager_burn_empty_native.snap @@ -1 +1 @@ -51576 \ No newline at end of file +50953 \ No newline at end of file diff --git a/.forge-snapshots/PositionManager_burn_nonEmpty_native_withClose.snap b/.forge-snapshots/PositionManager_burn_nonEmpty_native_withClose.snap index b8ad8f5e7..5d5a90de3 100644 --- a/.forge-snapshots/PositionManager_burn_nonEmpty_native_withClose.snap +++ b/.forge-snapshots/PositionManager_burn_nonEmpty_native_withClose.snap @@ -1 +1 @@ -128316 \ No newline at end of file +127469 \ No newline at end of file diff --git a/.forge-snapshots/PositionManager_burn_nonEmpty_native_withTakePair.snap b/.forge-snapshots/PositionManager_burn_nonEmpty_native_withTakePair.snap index 5f7fe3b44..79a47be6c 100644 --- a/.forge-snapshots/PositionManager_burn_nonEmpty_native_withTakePair.snap +++ b/.forge-snapshots/PositionManager_burn_nonEmpty_native_withTakePair.snap @@ -1 +1 @@ -127696 \ No newline at end of file +126902 \ No newline at end of file diff --git a/.forge-snapshots/PositionManager_burn_nonEmpty_withClose.snap b/.forge-snapshots/PositionManager_burn_nonEmpty_withClose.snap index f821b49cb..f50d601b5 100644 --- a/.forge-snapshots/PositionManager_burn_nonEmpty_withClose.snap +++ b/.forge-snapshots/PositionManager_burn_nonEmpty_withClose.snap @@ -1 +1 @@ -135236 \ No newline at end of file +134375 \ No newline at end of file diff --git a/.forge-snapshots/PositionManager_burn_nonEmpty_withTakePair.snap b/.forge-snapshots/PositionManager_burn_nonEmpty_withTakePair.snap index 46630b5d9..764b6c2bb 100644 --- a/.forge-snapshots/PositionManager_burn_nonEmpty_withTakePair.snap +++ b/.forge-snapshots/PositionManager_burn_nonEmpty_withTakePair.snap @@ -1 +1 @@ -134615 \ No newline at end of file +133808 \ No newline at end of file diff --git a/.forge-snapshots/PositionManager_collect_native.snap b/.forge-snapshots/PositionManager_collect_native.snap index df2c6fcf5..4ed0e2d12 100644 --- a/.forge-snapshots/PositionManager_collect_native.snap +++ b/.forge-snapshots/PositionManager_collect_native.snap @@ -1 +1 @@ -148593 \ No newline at end of file +147532 \ No newline at end of file diff --git a/.forge-snapshots/PositionManager_collect_sameRange.snap b/.forge-snapshots/PositionManager_collect_sameRange.snap index d5f6bc6fb..3887727c3 100644 --- a/.forge-snapshots/PositionManager_collect_sameRange.snap +++ b/.forge-snapshots/PositionManager_collect_sameRange.snap @@ -1 +1 @@ -157242 \ No newline at end of file +156164 \ No newline at end of file diff --git a/.forge-snapshots/PositionManager_collect_withClose.snap b/.forge-snapshots/PositionManager_collect_withClose.snap index d5f6bc6fb..3887727c3 100644 --- a/.forge-snapshots/PositionManager_collect_withClose.snap +++ b/.forge-snapshots/PositionManager_collect_withClose.snap @@ -1 +1 @@ -157242 \ No newline at end of file +156164 \ No newline at end of file diff --git a/.forge-snapshots/PositionManager_collect_withTakePair.snap b/.forge-snapshots/PositionManager_collect_withTakePair.snap index a7d8032c6..878f2f34a 100644 --- a/.forge-snapshots/PositionManager_collect_withTakePair.snap +++ b/.forge-snapshots/PositionManager_collect_withTakePair.snap @@ -1 +1 @@ -156478 \ No newline at end of file +155467 \ No newline at end of file diff --git a/.forge-snapshots/PositionManager_decreaseLiquidity_native.snap b/.forge-snapshots/PositionManager_decreaseLiquidity_native.snap index 15e513a00..d930c56e6 100644 --- a/.forge-snapshots/PositionManager_decreaseLiquidity_native.snap +++ b/.forge-snapshots/PositionManager_decreaseLiquidity_native.snap @@ -1 +1 @@ -114183 \ No newline at end of file +113521 \ No newline at end of file diff --git a/.forge-snapshots/PositionManager_decreaseLiquidity_withClose.snap b/.forge-snapshots/PositionManager_decreaseLiquidity_withClose.snap index b13b88cd8..34ab0546f 100644 --- a/.forge-snapshots/PositionManager_decreaseLiquidity_withClose.snap +++ b/.forge-snapshots/PositionManager_decreaseLiquidity_withClose.snap @@ -1 +1 @@ -122577 \ No newline at end of file +121733 \ No newline at end of file diff --git a/.forge-snapshots/PositionManager_decreaseLiquidity_withTakePair.snap b/.forge-snapshots/PositionManager_decreaseLiquidity_withTakePair.snap index 627de811d..d754277bf 100644 --- a/.forge-snapshots/PositionManager_decreaseLiquidity_withTakePair.snap +++ b/.forge-snapshots/PositionManager_decreaseLiquidity_withTakePair.snap @@ -1 +1 @@ -121813 \ No newline at end of file +121036 \ No newline at end of file diff --git a/.forge-snapshots/PositionManager_decrease_burnEmpty.snap b/.forge-snapshots/PositionManager_decrease_burnEmpty.snap index 28983a330..6dc82b4e9 100644 --- a/.forge-snapshots/PositionManager_decrease_burnEmpty.snap +++ b/.forge-snapshots/PositionManager_decrease_burnEmpty.snap @@ -1 +1 @@ -138195 \ No newline at end of file +137225 \ No newline at end of file diff --git a/.forge-snapshots/PositionManager_decrease_burnEmpty_native.snap b/.forge-snapshots/PositionManager_decrease_burnEmpty_native.snap index 9f6d1c14e..cc1c052a3 100644 --- a/.forge-snapshots/PositionManager_decrease_burnEmpty_native.snap +++ b/.forge-snapshots/PositionManager_decrease_burnEmpty_native.snap @@ -1 +1 @@ -131276 \ No newline at end of file +130320 \ No newline at end of file diff --git a/.forge-snapshots/PositionManager_decrease_sameRange_allLiquidity.snap b/.forge-snapshots/PositionManager_decrease_sameRange_allLiquidity.snap index 397b72af6..1dcfbe88d 100644 --- a/.forge-snapshots/PositionManager_decrease_sameRange_allLiquidity.snap +++ b/.forge-snapshots/PositionManager_decrease_sameRange_allLiquidity.snap @@ -1 +1 @@ -135240 \ No newline at end of file +134449 \ No newline at end of file diff --git a/.forge-snapshots/PositionManager_decrease_take_take.snap b/.forge-snapshots/PositionManager_decrease_take_take.snap index 25671ee7f..7dac0ddfe 100644 --- a/.forge-snapshots/PositionManager_decrease_take_take.snap +++ b/.forge-snapshots/PositionManager_decrease_take_take.snap @@ -1 +1 @@ -123191 \ No newline at end of file +122266 \ No newline at end of file diff --git a/.forge-snapshots/PositionManager_increaseLiquidity_erc20_withClose.snap b/.forge-snapshots/PositionManager_increaseLiquidity_erc20_withClose.snap index e20cbceb5..5be4cdb84 100644 --- a/.forge-snapshots/PositionManager_increaseLiquidity_erc20_withClose.snap +++ b/.forge-snapshots/PositionManager_increaseLiquidity_erc20_withClose.snap @@ -1 +1 @@ -162441 \ No newline at end of file +160356 \ No newline at end of file diff --git a/.forge-snapshots/PositionManager_increaseLiquidity_erc20_withSettlePair.snap b/.forge-snapshots/PositionManager_increaseLiquidity_erc20_withSettlePair.snap index 957d69b9f..b7c87ac4d 100644 --- a/.forge-snapshots/PositionManager_increaseLiquidity_erc20_withSettlePair.snap +++ b/.forge-snapshots/PositionManager_increaseLiquidity_erc20_withSettlePair.snap @@ -1 +1 @@ -161305 \ No newline at end of file +159267 \ No newline at end of file diff --git a/.forge-snapshots/PositionManager_increaseLiquidity_native.snap b/.forge-snapshots/PositionManager_increaseLiquidity_native.snap index c00b69785..0cc7dea3b 100644 --- a/.forge-snapshots/PositionManager_increaseLiquidity_native.snap +++ b/.forge-snapshots/PositionManager_increaseLiquidity_native.snap @@ -1 +1 @@ -145318 \ No newline at end of file +143272 \ No newline at end of file diff --git a/.forge-snapshots/PositionManager_increase_autocompoundExactUnclaimedFees.snap b/.forge-snapshots/PositionManager_increase_autocompoundExactUnclaimedFees.snap index 6ed7545ea..f0d93aa69 100644 --- a/.forge-snapshots/PositionManager_increase_autocompoundExactUnclaimedFees.snap +++ b/.forge-snapshots/PositionManager_increase_autocompoundExactUnclaimedFees.snap @@ -1 +1 @@ -138032 \ No newline at end of file +138103 \ No newline at end of file diff --git a/.forge-snapshots/PositionManager_increase_autocompoundExcessFeesCredit.snap b/.forge-snapshots/PositionManager_increase_autocompoundExcessFeesCredit.snap index e08e83c47..85ababc91 100644 --- a/.forge-snapshots/PositionManager_increase_autocompoundExcessFeesCredit.snap +++ b/.forge-snapshots/PositionManager_increase_autocompoundExcessFeesCredit.snap @@ -1 +1 @@ -180216 \ No newline at end of file +179393 \ No newline at end of file diff --git a/.forge-snapshots/PositionManager_increase_autocompound_clearExcess.snap b/.forge-snapshots/PositionManager_increase_autocompound_clearExcess.snap index 7d47367c2..4f993caf9 100644 --- a/.forge-snapshots/PositionManager_increase_autocompound_clearExcess.snap +++ b/.forge-snapshots/PositionManager_increase_autocompound_clearExcess.snap @@ -1 +1 @@ -150804 \ No newline at end of file +149311 \ No newline at end of file diff --git a/.forge-snapshots/PositionManager_mint_native.snap b/.forge-snapshots/PositionManager_mint_native.snap index ad9b48fff..aa4ab24bb 100644 --- a/.forge-snapshots/PositionManager_mint_native.snap +++ b/.forge-snapshots/PositionManager_mint_native.snap @@ -1 +1 @@ -369623 \ No newline at end of file +367148 \ No newline at end of file diff --git a/.forge-snapshots/PositionManager_mint_nativeWithSweep_withClose.snap b/.forge-snapshots/PositionManager_mint_nativeWithSweep_withClose.snap index 6d4460fb9..aa9ec51a2 100644 --- a/.forge-snapshots/PositionManager_mint_nativeWithSweep_withClose.snap +++ b/.forge-snapshots/PositionManager_mint_nativeWithSweep_withClose.snap @@ -1 +1 @@ -378280 \ No newline at end of file +375715 \ No newline at end of file diff --git a/.forge-snapshots/PositionManager_mint_nativeWithSweep_withSettlePair.snap b/.forge-snapshots/PositionManager_mint_nativeWithSweep_withSettlePair.snap index 351997f8d..ba5376799 100644 --- a/.forge-snapshots/PositionManager_mint_nativeWithSweep_withSettlePair.snap +++ b/.forge-snapshots/PositionManager_mint_nativeWithSweep_withSettlePair.snap @@ -1 +1 @@ -377364 \ No newline at end of file +374910 \ No newline at end of file diff --git a/.forge-snapshots/PositionManager_mint_onSameTickLower.snap b/.forge-snapshots/PositionManager_mint_onSameTickLower.snap index dcb8d5ae5..a7c97bf80 100644 --- a/.forge-snapshots/PositionManager_mint_onSameTickLower.snap +++ b/.forge-snapshots/PositionManager_mint_onSameTickLower.snap @@ -1 +1 @@ -321205 \ No newline at end of file +318932 \ No newline at end of file diff --git a/.forge-snapshots/PositionManager_mint_onSameTickUpper.snap b/.forge-snapshots/PositionManager_mint_onSameTickUpper.snap index 3a7c7c34a..458417a10 100644 --- a/.forge-snapshots/PositionManager_mint_onSameTickUpper.snap +++ b/.forge-snapshots/PositionManager_mint_onSameTickUpper.snap @@ -1 +1 @@ -321875 \ No newline at end of file +319574 \ No newline at end of file diff --git a/.forge-snapshots/PositionManager_mint_sameRange.snap b/.forge-snapshots/PositionManager_mint_sameRange.snap index 7d8a26862..b6526289a 100644 --- a/.forge-snapshots/PositionManager_mint_sameRange.snap +++ b/.forge-snapshots/PositionManager_mint_sameRange.snap @@ -1 +1 @@ -247444 \ No newline at end of file +245156 \ No newline at end of file diff --git a/.forge-snapshots/PositionManager_mint_settleWithBalance_sweep.snap b/.forge-snapshots/PositionManager_mint_settleWithBalance_sweep.snap index 4d62f1da1..3e6618aea 100644 --- a/.forge-snapshots/PositionManager_mint_settleWithBalance_sweep.snap +++ b/.forge-snapshots/PositionManager_mint_settleWithBalance_sweep.snap @@ -1 +1 @@ -423280 \ No newline at end of file +420178 \ No newline at end of file diff --git a/.forge-snapshots/PositionManager_mint_warmedPool_differentRange.snap b/.forge-snapshots/PositionManager_mint_warmedPool_differentRange.snap index fcd47aaf3..94a4af8c3 100644 --- a/.forge-snapshots/PositionManager_mint_warmedPool_differentRange.snap +++ b/.forge-snapshots/PositionManager_mint_warmedPool_differentRange.snap @@ -1 +1 @@ -327236 \ No newline at end of file +324950 \ No newline at end of file diff --git a/.forge-snapshots/PositionManager_mint_withClose.snap b/.forge-snapshots/PositionManager_mint_withClose.snap index 59610f85c..57812b4a9 100644 --- a/.forge-snapshots/PositionManager_mint_withClose.snap +++ b/.forge-snapshots/PositionManager_mint_withClose.snap @@ -1 +1 @@ -423986 \ No newline at end of file +421472 \ No newline at end of file diff --git a/.forge-snapshots/PositionManager_mint_withSettlePair.snap b/.forge-snapshots/PositionManager_mint_withSettlePair.snap index b3a6480c2..00f6a1988 100644 --- a/.forge-snapshots/PositionManager_mint_withSettlePair.snap +++ b/.forge-snapshots/PositionManager_mint_withSettlePair.snap @@ -1 +1 @@ -422936 \ No newline at end of file +420501 \ No newline at end of file diff --git a/.forge-snapshots/PositionManager_multicall_initialize_mint.snap b/.forge-snapshots/PositionManager_multicall_initialize_mint.snap index 19380f4f4..a78f3b0ca 100644 --- a/.forge-snapshots/PositionManager_multicall_initialize_mint.snap +++ b/.forge-snapshots/PositionManager_multicall_initialize_mint.snap @@ -1 +1 @@ -460558 \ No newline at end of file +457709 \ No newline at end of file diff --git a/.forge-snapshots/PositionManager_permit.snap b/.forge-snapshots/PositionManager_permit.snap index 53dd01e77..227e327e4 100644 --- a/.forge-snapshots/PositionManager_permit.snap +++ b/.forge-snapshots/PositionManager_permit.snap @@ -1 +1 @@ -79259 \ No newline at end of file +79076 \ No newline at end of file diff --git a/.forge-snapshots/PositionManager_permit_secondPosition.snap b/.forge-snapshots/PositionManager_permit_secondPosition.snap index ac17c65c1..31ad61876 100644 --- a/.forge-snapshots/PositionManager_permit_secondPosition.snap +++ b/.forge-snapshots/PositionManager_permit_secondPosition.snap @@ -1 +1 @@ -62159 \ No newline at end of file +61976 \ No newline at end of file diff --git a/.forge-snapshots/PositionManager_permit_twice.snap b/.forge-snapshots/PositionManager_permit_twice.snap index 532d2de91..68eb0f5de 100644 --- a/.forge-snapshots/PositionManager_permit_twice.snap +++ b/.forge-snapshots/PositionManager_permit_twice.snap @@ -1 +1 @@ -45035 \ No newline at end of file +44864 \ No newline at end of file diff --git a/.forge-snapshots/PositionManager_subscribe.snap b/.forge-snapshots/PositionManager_subscribe.snap index f6081d8d7..36cff1d2c 100644 --- a/.forge-snapshots/PositionManager_subscribe.snap +++ b/.forge-snapshots/PositionManager_subscribe.snap @@ -1 +1 @@ -88475 \ No newline at end of file +87857 \ No newline at end of file diff --git a/.forge-snapshots/PositionManager_unsubscribe.snap b/.forge-snapshots/PositionManager_unsubscribe.snap index 3651ba8a5..aaec480e7 100644 --- a/.forge-snapshots/PositionManager_unsubscribe.snap +++ b/.forge-snapshots/PositionManager_unsubscribe.snap @@ -1 +1 @@ -63253 \ No newline at end of file +62622 \ No newline at end of file diff --git a/.forge-snapshots/Quoter_exactInputSingle_oneForZero_multiplePositions.snap b/.forge-snapshots/Quoter_exactInputSingle_oneForZero_multiplePositions.snap index cb86556e8..ddd017c32 100644 --- a/.forge-snapshots/Quoter_exactInputSingle_oneForZero_multiplePositions.snap +++ b/.forge-snapshots/Quoter_exactInputSingle_oneForZero_multiplePositions.snap @@ -1 +1 @@ -146317 \ No newline at end of file +145902 \ No newline at end of file diff --git a/.forge-snapshots/Quoter_exactInputSingle_zeroForOne_multiplePositions.snap b/.forge-snapshots/Quoter_exactInputSingle_zeroForOne_multiplePositions.snap index 8cf53dc80..6bfe32457 100644 --- a/.forge-snapshots/Quoter_exactInputSingle_zeroForOne_multiplePositions.snap +++ b/.forge-snapshots/Quoter_exactInputSingle_zeroForOne_multiplePositions.snap @@ -1 +1 @@ -151973 \ No newline at end of file +152117 \ No newline at end of file diff --git a/.forge-snapshots/Quoter_exactOutputSingle_oneForZero.snap b/.forge-snapshots/Quoter_exactOutputSingle_oneForZero.snap index 2f2aa6ed8..0fddaa34a 100644 --- a/.forge-snapshots/Quoter_exactOutputSingle_oneForZero.snap +++ b/.forge-snapshots/Quoter_exactOutputSingle_oneForZero.snap @@ -1 +1 @@ -80048 \ No newline at end of file +79267 \ No newline at end of file diff --git a/.forge-snapshots/Quoter_exactOutputSingle_zeroForOne.snap b/.forge-snapshots/Quoter_exactOutputSingle_zeroForOne.snap index 9606490a7..80c70ad9b 100644 --- a/.forge-snapshots/Quoter_exactOutputSingle_zeroForOne.snap +++ b/.forge-snapshots/Quoter_exactOutputSingle_zeroForOne.snap @@ -1 +1 @@ -84626 \ No newline at end of file +84512 \ No newline at end of file diff --git a/.forge-snapshots/Quoter_quoteExactInput_oneHop_1TickLoaded.snap b/.forge-snapshots/Quoter_quoteExactInput_oneHop_1TickLoaded.snap index 9aebeeca5..535f80cb8 100644 --- a/.forge-snapshots/Quoter_quoteExactInput_oneHop_1TickLoaded.snap +++ b/.forge-snapshots/Quoter_quoteExactInput_oneHop_1TickLoaded.snap @@ -1 +1 @@ -122994 \ No newline at end of file +122728 \ No newline at end of file diff --git a/.forge-snapshots/Quoter_quoteExactInput_oneHop_initializedAfter.snap b/.forge-snapshots/Quoter_quoteExactInput_oneHop_initializedAfter.snap index 1a3ae7138..9e2f18c9f 100644 --- a/.forge-snapshots/Quoter_quoteExactInput_oneHop_initializedAfter.snap +++ b/.forge-snapshots/Quoter_quoteExactInput_oneHop_initializedAfter.snap @@ -1 +1 @@ -147949 \ No newline at end of file +147363 \ No newline at end of file diff --git a/.forge-snapshots/Quoter_quoteExactInput_oneHop_startingInitialized.snap b/.forge-snapshots/Quoter_quoteExactInput_oneHop_startingInitialized.snap index 1ce389ff1..2b5d25c12 100644 --- a/.forge-snapshots/Quoter_quoteExactInput_oneHop_startingInitialized.snap +++ b/.forge-snapshots/Quoter_quoteExactInput_oneHop_startingInitialized.snap @@ -1 +1 @@ -81420 \ No newline at end of file +80638 \ No newline at end of file diff --git a/.forge-snapshots/Quoter_quoteExactInput_twoHops.snap b/.forge-snapshots/Quoter_quoteExactInput_twoHops.snap index 7fe1af46a..4a002eafd 100644 --- a/.forge-snapshots/Quoter_quoteExactInput_twoHops.snap +++ b/.forge-snapshots/Quoter_quoteExactInput_twoHops.snap @@ -1 +1 @@ -205421 \ No newline at end of file +204942 \ No newline at end of file diff --git a/.forge-snapshots/Quoter_quoteExactOutput_oneHop_1TickLoaded.snap b/.forge-snapshots/Quoter_quoteExactOutput_oneHop_1TickLoaded.snap index 6233611de..6d7d1854d 100644 --- a/.forge-snapshots/Quoter_quoteExactOutput_oneHop_1TickLoaded.snap +++ b/.forge-snapshots/Quoter_quoteExactOutput_oneHop_1TickLoaded.snap @@ -1 +1 @@ -122296 \ No newline at end of file +122224 \ No newline at end of file diff --git a/.forge-snapshots/Quoter_quoteExactOutput_oneHop_2TicksLoaded.snap b/.forge-snapshots/Quoter_quoteExactOutput_oneHop_2TicksLoaded.snap index ee524ce0d..141d1a3ed 100644 --- a/.forge-snapshots/Quoter_quoteExactOutput_oneHop_2TicksLoaded.snap +++ b/.forge-snapshots/Quoter_quoteExactOutput_oneHop_2TicksLoaded.snap @@ -1 +1 @@ -152648 \ No newline at end of file +152879 \ No newline at end of file diff --git a/.forge-snapshots/Quoter_quoteExactOutput_oneHop_initializedAfter.snap b/.forge-snapshots/Quoter_quoteExactOutput_oneHop_initializedAfter.snap index f965907ac..ce1e06318 100644 --- a/.forge-snapshots/Quoter_quoteExactOutput_oneHop_initializedAfter.snap +++ b/.forge-snapshots/Quoter_quoteExactOutput_oneHop_initializedAfter.snap @@ -1 +1 @@ -122364 \ No newline at end of file +122251 \ No newline at end of file diff --git a/.forge-snapshots/Quoter_quoteExactOutput_oneHop_startingInitialized.snap b/.forge-snapshots/Quoter_quoteExactOutput_oneHop_startingInitialized.snap index f813bc4bc..44946b692 100644 --- a/.forge-snapshots/Quoter_quoteExactOutput_oneHop_startingInitialized.snap +++ b/.forge-snapshots/Quoter_quoteExactOutput_oneHop_startingInitialized.snap @@ -1 +1 @@ -98875 \ No newline at end of file +98545 \ No newline at end of file diff --git a/.forge-snapshots/Quoter_quoteExactOutput_twoHops.snap b/.forge-snapshots/Quoter_quoteExactOutput_twoHops.snap index 584ea1427..15336cc2d 100644 --- a/.forge-snapshots/Quoter_quoteExactOutput_twoHops.snap +++ b/.forge-snapshots/Quoter_quoteExactOutput_twoHops.snap @@ -1 +1 @@ -204897 \ No newline at end of file +204670 \ No newline at end of file diff --git a/.forge-snapshots/StateView_extsload_getFeeGrowthGlobals.snap b/.forge-snapshots/StateView_extsload_getFeeGrowthGlobals.snap index a9e72c33a..9fbf3f867 100644 --- a/.forge-snapshots/StateView_extsload_getFeeGrowthGlobals.snap +++ b/.forge-snapshots/StateView_extsload_getFeeGrowthGlobals.snap @@ -1 +1 @@ -2367 \ No newline at end of file +2203 \ No newline at end of file diff --git a/.forge-snapshots/StateView_extsload_getFeeGrowthInside.snap b/.forge-snapshots/StateView_extsload_getFeeGrowthInside.snap index b1b49287a..aa0e22057 100644 --- a/.forge-snapshots/StateView_extsload_getFeeGrowthInside.snap +++ b/.forge-snapshots/StateView_extsload_getFeeGrowthInside.snap @@ -1 +1 @@ -8444 \ No newline at end of file +7875 \ No newline at end of file diff --git a/.forge-snapshots/StateView_extsload_getLiquidity.snap b/.forge-snapshots/StateView_extsload_getLiquidity.snap index ab57eb1e7..ba3b675bf 100644 --- a/.forge-snapshots/StateView_extsload_getLiquidity.snap +++ b/.forge-snapshots/StateView_extsload_getLiquidity.snap @@ -1 +1 @@ -1480 \ No newline at end of file +1439 \ No newline at end of file diff --git a/.forge-snapshots/StateView_extsload_getPositionInfo.snap b/.forge-snapshots/StateView_extsload_getPositionInfo.snap index 0a1ca398f..cd5ecabca 100644 --- a/.forge-snapshots/StateView_extsload_getPositionInfo.snap +++ b/.forge-snapshots/StateView_extsload_getPositionInfo.snap @@ -1 +1 @@ -2973 \ No newline at end of file +2761 \ No newline at end of file diff --git a/.forge-snapshots/StateView_extsload_getPositionLiquidity.snap b/.forge-snapshots/StateView_extsload_getPositionLiquidity.snap index 8d6430831..936c5e3ce 100644 --- a/.forge-snapshots/StateView_extsload_getPositionLiquidity.snap +++ b/.forge-snapshots/StateView_extsload_getPositionLiquidity.snap @@ -1 +1 @@ -1750 \ No newline at end of file +1691 \ No newline at end of file diff --git a/.forge-snapshots/StateView_extsload_getSlot0.snap b/.forge-snapshots/StateView_extsload_getSlot0.snap index 466fe4026..6634f710e 100644 --- a/.forge-snapshots/StateView_extsload_getSlot0.snap +++ b/.forge-snapshots/StateView_extsload_getSlot0.snap @@ -1 +1 @@ -1548 \ No newline at end of file +1486 \ No newline at end of file diff --git a/.forge-snapshots/StateView_extsload_getTickBitmap.snap b/.forge-snapshots/StateView_extsload_getTickBitmap.snap index 0e8ebf59f..619ab3004 100644 --- a/.forge-snapshots/StateView_extsload_getTickBitmap.snap +++ b/.forge-snapshots/StateView_extsload_getTickBitmap.snap @@ -1 +1 @@ -1476 \ No newline at end of file +1432 \ No newline at end of file diff --git a/.forge-snapshots/StateView_extsload_getTickFeeGrowthOutside.snap b/.forge-snapshots/StateView_extsload_getTickFeeGrowthOutside.snap index 7c43ea017..8bf8757c4 100644 --- a/.forge-snapshots/StateView_extsload_getTickFeeGrowthOutside.snap +++ b/.forge-snapshots/StateView_extsload_getTickFeeGrowthOutside.snap @@ -1 +1 @@ -2672 \ No newline at end of file +2490 \ No newline at end of file diff --git a/.forge-snapshots/StateView_extsload_getTickInfo.snap b/.forge-snapshots/StateView_extsload_getTickInfo.snap index 3582118cc..4c7ec1ebc 100644 --- a/.forge-snapshots/StateView_extsload_getTickInfo.snap +++ b/.forge-snapshots/StateView_extsload_getTickInfo.snap @@ -1 +1 @@ -2896 \ No newline at end of file +2693 \ No newline at end of file diff --git a/.forge-snapshots/StateView_extsload_getTickLiquidity.snap b/.forge-snapshots/StateView_extsload_getTickLiquidity.snap index 0504b068d..f2b2a17d5 100644 --- a/.forge-snapshots/StateView_extsload_getTickLiquidity.snap +++ b/.forge-snapshots/StateView_extsload_getTickLiquidity.snap @@ -1 +1 @@ -1748 \ No newline at end of file +1686 \ No newline at end of file diff --git a/.forge-snapshots/V4Router_Bytecode.snap b/.forge-snapshots/V4Router_Bytecode.snap index ec718f71f..9c2bbe002 100644 --- a/.forge-snapshots/V4Router_Bytecode.snap +++ b/.forge-snapshots/V4Router_Bytecode.snap @@ -1 +1 @@ -5137 \ No newline at end of file +8975 \ No newline at end of file diff --git a/.forge-snapshots/V4Router_ExactIn1Hop_nativeIn.snap b/.forge-snapshots/V4Router_ExactIn1Hop_nativeIn.snap index 56a7e65e8..e188f56da 100644 --- a/.forge-snapshots/V4Router_ExactIn1Hop_nativeIn.snap +++ b/.forge-snapshots/V4Router_ExactIn1Hop_nativeIn.snap @@ -1 +1 @@ -121819 \ No newline at end of file +121653 \ No newline at end of file diff --git a/.forge-snapshots/V4Router_ExactIn1Hop_nativeOut.snap b/.forge-snapshots/V4Router_ExactIn1Hop_nativeOut.snap index cbfeb1a9c..e7e76c10c 100644 --- a/.forge-snapshots/V4Router_ExactIn1Hop_nativeOut.snap +++ b/.forge-snapshots/V4Router_ExactIn1Hop_nativeOut.snap @@ -1 +1 @@ -120826 \ No newline at end of file +120119 \ No newline at end of file diff --git a/.forge-snapshots/V4Router_ExactIn1Hop_oneForZero.snap b/.forge-snapshots/V4Router_ExactIn1Hop_oneForZero.snap index 6bf2eef7d..527b24a3a 100644 --- a/.forge-snapshots/V4Router_ExactIn1Hop_oneForZero.snap +++ b/.forge-snapshots/V4Router_ExactIn1Hop_oneForZero.snap @@ -1 +1 @@ -129715 \ No newline at end of file +128991 \ No newline at end of file diff --git a/.forge-snapshots/V4Router_ExactIn1Hop_zeroForOne.snap b/.forge-snapshots/V4Router_ExactIn1Hop_zeroForOne.snap index 891422a70..1fcdfdb7b 100644 --- a/.forge-snapshots/V4Router_ExactIn1Hop_zeroForOne.snap +++ b/.forge-snapshots/V4Router_ExactIn1Hop_zeroForOne.snap @@ -1 +1 @@ -135623 \ No newline at end of file +135517 \ No newline at end of file diff --git a/.forge-snapshots/V4Router_ExactIn2Hops.snap b/.forge-snapshots/V4Router_ExactIn2Hops.snap index a7bc469ae..022fe02b0 100644 --- a/.forge-snapshots/V4Router_ExactIn2Hops.snap +++ b/.forge-snapshots/V4Router_ExactIn2Hops.snap @@ -1 +1 @@ -191979 \ No newline at end of file +192843 \ No newline at end of file diff --git a/.forge-snapshots/V4Router_ExactIn2Hops_nativeIn.snap b/.forge-snapshots/V4Router_ExactIn2Hops_nativeIn.snap index ef0bcd5fe..6f68c80eb 100644 --- a/.forge-snapshots/V4Router_ExactIn2Hops_nativeIn.snap +++ b/.forge-snapshots/V4Router_ExactIn2Hops_nativeIn.snap @@ -1 +1 @@ -178175 \ No newline at end of file +178979 \ No newline at end of file diff --git a/.forge-snapshots/V4Router_ExactIn3Hops.snap b/.forge-snapshots/V4Router_ExactIn3Hops.snap index 89acd064f..72c812f8c 100644 --- a/.forge-snapshots/V4Router_ExactIn3Hops.snap +++ b/.forge-snapshots/V4Router_ExactIn3Hops.snap @@ -1 +1 @@ -248385 \ No newline at end of file +250218 \ No newline at end of file diff --git a/.forge-snapshots/V4Router_ExactIn3Hops_nativeIn.snap b/.forge-snapshots/V4Router_ExactIn3Hops_nativeIn.snap index a93abe955..fea73fd7e 100644 --- a/.forge-snapshots/V4Router_ExactIn3Hops_nativeIn.snap +++ b/.forge-snapshots/V4Router_ExactIn3Hops_nativeIn.snap @@ -1 +1 @@ -234581 \ No newline at end of file +236354 \ No newline at end of file diff --git a/.forge-snapshots/V4Router_ExactInputSingle.snap b/.forge-snapshots/V4Router_ExactInputSingle.snap index 24fe6dec9..e8d120418 100644 --- a/.forge-snapshots/V4Router_ExactInputSingle.snap +++ b/.forge-snapshots/V4Router_ExactInputSingle.snap @@ -1 +1 @@ -134546 \ No newline at end of file +134001 \ No newline at end of file diff --git a/.forge-snapshots/V4Router_ExactInputSingle_nativeIn.snap b/.forge-snapshots/V4Router_ExactInputSingle_nativeIn.snap index 7f06d7f09..182d8da2a 100644 --- a/.forge-snapshots/V4Router_ExactInputSingle_nativeIn.snap +++ b/.forge-snapshots/V4Router_ExactInputSingle_nativeIn.snap @@ -1 +1 @@ -120742 \ No newline at end of file +120137 \ No newline at end of file diff --git a/.forge-snapshots/V4Router_ExactInputSingle_nativeOut.snap b/.forge-snapshots/V4Router_ExactInputSingle_nativeOut.snap index 4e26e8532..9bb44eced 100644 --- a/.forge-snapshots/V4Router_ExactInputSingle_nativeOut.snap +++ b/.forge-snapshots/V4Router_ExactInputSingle_nativeOut.snap @@ -1 +1 @@ -119714 \ No newline at end of file +118581 \ No newline at end of file diff --git a/.forge-snapshots/V4Router_ExactOut1Hop_nativeIn_sweepETH.snap b/.forge-snapshots/V4Router_ExactOut1Hop_nativeIn_sweepETH.snap index 1fdaa9cd4..82db8f7b1 100644 --- a/.forge-snapshots/V4Router_ExactOut1Hop_nativeIn_sweepETH.snap +++ b/.forge-snapshots/V4Router_ExactOut1Hop_nativeIn_sweepETH.snap @@ -1 +1 @@ -128078 \ No newline at end of file +127940 \ No newline at end of file diff --git a/.forge-snapshots/V4Router_ExactOut1Hop_nativeOut.snap b/.forge-snapshots/V4Router_ExactOut1Hop_nativeOut.snap index 5680b0271..96c04d44d 100644 --- a/.forge-snapshots/V4Router_ExactOut1Hop_nativeOut.snap +++ b/.forge-snapshots/V4Router_ExactOut1Hop_nativeOut.snap @@ -1 +1 @@ -121895 \ No newline at end of file +121329 \ No newline at end of file diff --git a/.forge-snapshots/V4Router_ExactOut1Hop_oneForZero.snap b/.forge-snapshots/V4Router_ExactOut1Hop_oneForZero.snap index 85542b79f..59010c68f 100644 --- a/.forge-snapshots/V4Router_ExactOut1Hop_oneForZero.snap +++ b/.forge-snapshots/V4Router_ExactOut1Hop_oneForZero.snap @@ -1 +1 @@ -130784 \ No newline at end of file +130201 \ No newline at end of file diff --git a/.forge-snapshots/V4Router_ExactOut1Hop_zeroForOne.snap b/.forge-snapshots/V4Router_ExactOut1Hop_zeroForOne.snap index a883e8809..7e653318c 100644 --- a/.forge-snapshots/V4Router_ExactOut1Hop_zeroForOne.snap +++ b/.forge-snapshots/V4Router_ExactOut1Hop_zeroForOne.snap @@ -1 +1 @@ -134905 \ No newline at end of file +134858 \ No newline at end of file diff --git a/.forge-snapshots/V4Router_ExactOut2Hops.snap b/.forge-snapshots/V4Router_ExactOut2Hops.snap index eb9099cb8..bc92fcdbe 100644 --- a/.forge-snapshots/V4Router_ExactOut2Hops.snap +++ b/.forge-snapshots/V4Router_ExactOut2Hops.snap @@ -1 +1 @@ -190319 \ No newline at end of file +191291 \ No newline at end of file diff --git a/.forge-snapshots/V4Router_ExactOut2Hops_nativeIn.snap b/.forge-snapshots/V4Router_ExactOut2Hops_nativeIn.snap index c2de3e9b9..6c96d9097 100644 --- a/.forge-snapshots/V4Router_ExactOut2Hops_nativeIn.snap +++ b/.forge-snapshots/V4Router_ExactOut2Hops_nativeIn.snap @@ -1 +1 @@ -183492 \ No newline at end of file +184373 \ No newline at end of file diff --git a/.forge-snapshots/V4Router_ExactOut3Hops.snap b/.forge-snapshots/V4Router_ExactOut3Hops.snap index ddf200aa9..32a25024e 100644 --- a/.forge-snapshots/V4Router_ExactOut3Hops.snap +++ b/.forge-snapshots/V4Router_ExactOut3Hops.snap @@ -1 +1 @@ -245811 \ No newline at end of file +247788 \ No newline at end of file diff --git a/.forge-snapshots/V4Router_ExactOut3Hops_nativeIn.snap b/.forge-snapshots/V4Router_ExactOut3Hops_nativeIn.snap index 583269aea..42f6448d7 100644 --- a/.forge-snapshots/V4Router_ExactOut3Hops_nativeIn.snap +++ b/.forge-snapshots/V4Router_ExactOut3Hops_nativeIn.snap @@ -1 +1 @@ -238984 \ No newline at end of file +240870 \ No newline at end of file diff --git a/.forge-snapshots/V4Router_ExactOut3Hops_nativeOut.snap b/.forge-snapshots/V4Router_ExactOut3Hops_nativeOut.snap index 0ff3d5c82..acd8db05d 100644 --- a/.forge-snapshots/V4Router_ExactOut3Hops_nativeOut.snap +++ b/.forge-snapshots/V4Router_ExactOut3Hops_nativeOut.snap @@ -1 +1 @@ -224567 \ No newline at end of file +224943 \ No newline at end of file diff --git a/.forge-snapshots/V4Router_ExactOutputSingle.snap b/.forge-snapshots/V4Router_ExactOutputSingle.snap index d44e2734a..410b941d2 100644 --- a/.forge-snapshots/V4Router_ExactOutputSingle.snap +++ b/.forge-snapshots/V4Router_ExactOutputSingle.snap @@ -1 +1 @@ -133809 \ No newline at end of file +133337 \ No newline at end of file diff --git a/.forge-snapshots/V4Router_ExactOutputSingle_nativeIn_sweepETH.snap b/.forge-snapshots/V4Router_ExactOutputSingle_nativeIn_sweepETH.snap index fc1ac5689..cfd3c90d9 100644 --- a/.forge-snapshots/V4Router_ExactOutputSingle_nativeIn_sweepETH.snap +++ b/.forge-snapshots/V4Router_ExactOutputSingle_nativeIn_sweepETH.snap @@ -1 +1 @@ -126982 \ No newline at end of file +126419 \ No newline at end of file diff --git a/.forge-snapshots/V4Router_ExactOutputSingle_nativeOut.snap b/.forge-snapshots/V4Router_ExactOutputSingle_nativeOut.snap index dacad49f6..362e3fea2 100644 --- a/.forge-snapshots/V4Router_ExactOutputSingle_nativeOut.snap +++ b/.forge-snapshots/V4Router_ExactOutputSingle_nativeOut.snap @@ -1 +1 @@ -120876 \ No newline at end of file +119821 \ No newline at end of file diff --git a/.forge-snapshots/positionManager bytecode size.snap b/.forge-snapshots/positionManager bytecode size.snap index 6f29cf461..ec585573f 100644 --- a/.forge-snapshots/positionManager bytecode size.snap +++ b/.forge-snapshots/positionManager bytecode size.snap @@ -1 +1 @@ -19068 \ No newline at end of file +26931 \ No newline at end of file diff --git a/foundry.toml b/foundry.toml index 30dff3ef4..78967d2ce 100644 --- a/foundry.toml +++ b/foundry.toml @@ -1,15 +1,25 @@ [profile.default] out = 'foundry-out' solc_version = '0.8.26' -optimizer_runs = 1 +optimizer_runs = 44444444 via_ir = true ffi = true -fs_permissions = [{ access = "read-write", path = ".forge-snapshots/"}] +fs_permissions = [{ access = "read-write", path = ".forge-snapshots/" }, { access = "read", path = "foundry-out/" }] evm_version = "cancun" gas_limit = "3000000000" fuzz_runs = 10_000 bytecode_hash = "none" +additional_compiler_profiles = [ + { name = "descriptor", via_ir = true, optimizer_runs = 1 }, + { name = "test", via_ir = false } +] + +compilation_restrictions = [ + { paths = "src/PositionDescriptor.sol", optimizer_runs = 1 }, + { paths = "test/**", via_ir = false } +] + [profile.debug] via_ir = false optimizer_runs = 200 diff --git a/script/DeployPosm.s.sol b/script/DeployPosm.s.sol index b87fbea0f..e9300630b 100644 --- a/script/DeployPosm.s.sol +++ b/script/DeployPosm.s.sol @@ -6,10 +6,8 @@ import "forge-std/Script.sol"; import {IPoolManager} from "@uniswap/v4-core/src/interfaces/IPoolManager.sol"; import {StateView} from "../src/lens/StateView.sol"; -import {PositionManager} from "../src/PositionManager.sol"; import {IAllowanceTransfer} from "permit2/src/interfaces/IAllowanceTransfer.sol"; -import {IPositionDescriptor} from "../src/interfaces/IPositionDescriptor.sol"; -import {PositionDescriptor} from "../src/PositionDescriptor.sol"; +import {Deploy, IPositionDescriptor, IPositionManager} from "../test/shared/Deploy.sol"; import {IWETH9} from "../src/interfaces/external/IWETH9.sol"; contract DeployPosmTest is Script { @@ -21,18 +19,14 @@ contract DeployPosmTest is Script { uint256 unsubscribeGasLimit, address wrappedNative, string memory nativeCurrencyLabel - ) public returns (PositionDescriptor positionDescriptor, PositionManager posm) { + ) public returns (IPositionDescriptor positionDescriptor, IPositionManager posm) { vm.startBroadcast(); - positionDescriptor = new PositionDescriptor(IPoolManager(poolManager), wrappedNative, nativeCurrencyLabel); + positionDescriptor = Deploy.positionDescriptor(poolManager, wrappedNative, nativeCurrencyLabel); console2.log("PositionDescriptor", address(positionDescriptor)); - posm = new PositionManager{salt: hex"03"}( - IPoolManager(poolManager), - IAllowanceTransfer(permit2), - unsubscribeGasLimit, - IPositionDescriptor(address(positionDescriptor)), - IWETH9(wrappedNative) + posm = Deploy.positionManager( + poolManager, permit2, unsubscribeGasLimit, address(positionDescriptor), wrappedNative, hex"03" ); console2.log("PositionManager", address(posm)); diff --git a/script/DeployStateView.s.sol b/script/DeployStateView.s.sol index 9584099d2..77f400000 100644 --- a/script/DeployStateView.s.sol +++ b/script/DeployStateView.s.sol @@ -5,7 +5,7 @@ import "forge-std/console2.sol"; import "forge-std/Script.sol"; import {IPoolManager} from "@uniswap/v4-core/src/interfaces/IPoolManager.sol"; -import {StateView} from "../src/lens/StateView.sol"; +import {Deploy, StateView} from "../test/shared/Deploy.sol"; contract DeployStateView is Script { function setUp() public {} @@ -14,7 +14,7 @@ contract DeployStateView is Script { vm.startBroadcast(); // forge script --broadcast --sig 'run(address)' --rpc-url --private-key --verify script/DeployStateView.s.sol:DeployStateView - state = new StateView(IPoolManager(poolManager)); + state = Deploy.stateView(poolManager); console2.log("StateView", address(state)); console2.log("PoolManager", address(state.poolManager())); diff --git a/script/DeployV4Quoter.s.sol b/script/DeployV4Quoter.s.sol index 7cc61d5f9..fbd37c33c 100644 --- a/script/DeployV4Quoter.s.sol +++ b/script/DeployV4Quoter.s.sol @@ -5,16 +5,16 @@ import "forge-std/console2.sol"; import "forge-std/Script.sol"; import {IPoolManager} from "@uniswap/v4-core/src/interfaces/IPoolManager.sol"; -import {V4Quoter} from "../src/lens/V4Quoter.sol"; +import {Deploy, IV4Quoter} from "../test/shared/Deploy.sol"; contract DeployV4Quoter is Script { function setUp() public {} - function run(address poolManager) public returns (V4Quoter state) { + function run(address poolManager) public returns (IV4Quoter state) { vm.startBroadcast(); // forge script --broadcast --sig 'run(address)' --rpc-url --private-key --verify script/DeployV4Quoter.s.sol:DeployV4Quoter - state = new V4Quoter(IPoolManager(poolManager)); + state = Deploy.v4Quoter(poolManager); console2.log("V4Quoter", address(state)); console2.log("PoolManager", address(state.poolManager())); diff --git a/src/PositionDescriptor.sol b/src/PositionDescriptor.sol index 34910d538..5184d07ae 100644 --- a/src/PositionDescriptor.sol +++ b/src/PositionDescriptor.sol @@ -21,8 +21,6 @@ contract PositionDescriptor is IPositionDescriptor { using CurrencyLibrary for Currency; using PositionInfoLibrary for PositionInfo; - error InvalidTokenId(uint256 tokenId); - // mainnet addresses address private constant DAI = 0x6B175474E89094C44Da98b954EedeAC495271d0F; address private constant USDC = 0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48; @@ -87,18 +85,12 @@ contract PositionDescriptor is IPositionDescriptor { ); } - /// @notice Returns true if currency0 has higher priority than currency1 - /// @param currency0 The first currency address - /// @param currency1 The second currency address - /// @return flipRatio True if currency0 has higher priority than currency1 - function flipRatio(address currency0, address currency1) public view returns (bool) { + /// @inheritdoc IPositionDescriptor + function flipRatio(address currency0, address currency1) public view override returns (bool) { return currencyRatioPriority(currency0) > currencyRatioPriority(currency1); } - /// @notice Returns the priority of a currency. - /// For certain currencies on mainnet, the smaller the currency, the higher the priority - /// @param currency The currency address - /// @return priority The priority of the currency + /// @inheritdoc IPositionDescriptor function currencyRatioPriority(address currency) public view returns (int256) { // Currencies in order of priority on mainnet: USDC, USDT, DAI, (ETH, WETH), TBTC, WBTC // wrapped native is different address on different chains. passed in constructor diff --git a/src/base/PoolInitializer.sol b/src/base/PoolInitializer.sol index fea603402..5212afc68 100644 --- a/src/base/PoolInitializer.sol +++ b/src/base/PoolInitializer.sol @@ -2,18 +2,14 @@ pragma solidity ^0.8.0; import {ImmutableState} from "./ImmutableState.sol"; - import {PoolKey} from "@uniswap/v4-core/src/types/PoolKey.sol"; +import {IPoolInitializer} from "../interfaces/IPoolInitializer.sol"; /// @title Pool Initializer /// @notice Initializes a Uniswap v4 Pool /// @dev Enables create pool + mint liquidity in a single transaction with multicall -abstract contract PoolInitializer is ImmutableState { - /// @notice Initialize a Uniswap v4 Pool - /// @dev If the pool is already initialized, this function will not revert and just return type(int24).max - /// @param key the PoolKey of the pool to initialize - /// @param sqrtPriceX96 the initial sqrtPriceX96 of the pool - /// @return tick The current tick of the pool +abstract contract PoolInitializer is ImmutableState, IPoolInitializer { + /// @inheritdoc IPoolInitializer function initializePool(PoolKey calldata key, uint160 sqrtPriceX96) external payable returns (int24) { try poolManager.initialize(key, sqrtPriceX96) returns (int24 tick) { return tick; diff --git a/src/interfaces/IPoolInitializer.sol b/src/interfaces/IPoolInitializer.sol new file mode 100644 index 000000000..ee3e6163d --- /dev/null +++ b/src/interfaces/IPoolInitializer.sol @@ -0,0 +1,13 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; + +import {PoolKey} from "@uniswap/v4-core/src/types/PoolKey.sol"; + +interface IPoolInitializer { + /// @notice Initialize a Uniswap v4 Pool + /// @dev If the pool is already initialized, this function will not revert and just return type(int24).max + /// @param key the PoolKey of the pool to initialize + /// @param sqrtPriceX96 the initial sqrtPriceX96 of the pool + /// @return tick The current tick of the pool + function initializePool(PoolKey calldata key, uint160 sqrtPriceX96) external payable returns (int24); +} diff --git a/src/interfaces/IPositionDescriptor.sol b/src/interfaces/IPositionDescriptor.sol index a1736ceab..a6ed2a9a4 100644 --- a/src/interfaces/IPositionDescriptor.sol +++ b/src/interfaces/IPositionDescriptor.sol @@ -2,13 +2,37 @@ pragma solidity ^0.8.24; import "./IPositionManager.sol"; +import {IPoolManager} from "@uniswap/v4-core/src/interfaces/IPoolManager.sol"; /// @title Describes position NFT tokens via URI interface IPositionDescriptor { + error InvalidTokenId(uint256 tokenId); + /// @notice Produces the URI describing a particular token ID /// @dev Note this URI may be a data: URI with the JSON contents directly inlined /// @param positionManager The position manager for which to describe the token /// @param tokenId The ID of the token for which to produce a description, which may not be valid /// @return The URI of the ERC721-compliant metadata function tokenURI(IPositionManager positionManager, uint256 tokenId) external view returns (string memory); + + /// @notice Returns true if currency0 has higher priority than currency1 + /// @param currency0 The first currency address + /// @param currency1 The second currency address + /// @return flipRatio True if currency0 has higher priority than currency1 + function flipRatio(address currency0, address currency1) external view returns (bool); + + /// @notice Returns the priority of a currency. + /// For certain currencies on mainnet, the smaller the currency, the higher the priority + /// @param currency The currency address + /// @return priority The priority of the currency + function currencyRatioPriority(address currency) external view returns (int256); + + /// @return The wrapped native token for this descriptor + function wrappedNative() external view returns (address); + + /// @return The native currency label for this descriptor + function nativeCurrencyLabel() external view returns (string memory); + + /// @return The pool manager for this descriptor + function poolManager() external view returns (IPoolManager); } diff --git a/src/interfaces/IPositionManager.sol b/src/interfaces/IPositionManager.sol index 86df7bbf9..c6ea8263c 100644 --- a/src/interfaces/IPositionManager.sol +++ b/src/interfaces/IPositionManager.sol @@ -6,10 +6,21 @@ import {PositionInfo} from "../libraries/PositionInfoLibrary.sol"; import {INotifier} from "./INotifier.sol"; import {IImmutableState} from "./IImmutableState.sol"; - +import {IERC721Permit_v4} from "./IERC721Permit_v4.sol"; +import {IEIP712_v4} from "./IEIP712_v4.sol"; +import {IMulticall_v4} from "./IMulticall_v4.sol"; +import {IPoolInitializer} from "./IPoolInitializer.sol"; /// @title IPositionManager /// @notice Interface for the PositionManager contract -interface IPositionManager is INotifier, IImmutableState { + +interface IPositionManager is + INotifier, + IImmutableState, + IERC721Permit_v4, + IEIP712_v4, + IMulticall_v4, + IPoolInitializer +{ /// @notice Thrown when the caller is not approved to modify a position error NotApproved(address caller); /// @notice Thrown when the block.timestamp exceeds the user-provided deadline @@ -40,7 +51,11 @@ interface IPositionManager is INotifier, IImmutableState { function getPositionLiquidity(uint256 tokenId) external view returns (uint128 liquidity); /// @param tokenId the ERC721 tokenId - /// @return PositionInfo a uint256 packed value holding information about the position including the range (tickLower, tickUpper) /// @return poolKey the pool key of the position + /// @return PositionInfo a uint256 packed value holding information about the position including the range (tickLower, tickUpper) function getPoolAndPositionInfo(uint256 tokenId) external view returns (PoolKey memory, PositionInfo); + + /// @param tokenId the ERC721 tokenId + /// @return a uint256 packed value holding information about the position including the range (tickLower, tickUpper) + function positionInfo(uint256 tokenId) external view returns (PositionInfo); } diff --git a/src/interfaces/IV4Quoter.sol b/src/interfaces/IV4Quoter.sol index f502a4f44..d51ddb3ca 100644 --- a/src/interfaces/IV4Quoter.sol +++ b/src/interfaces/IV4Quoter.sol @@ -4,13 +4,14 @@ pragma solidity ^0.8.0; import {PoolKey} from "@uniswap/v4-core/src/types/PoolKey.sol"; import {Currency} from "@uniswap/v4-core/src/types/Currency.sol"; import {PathKey} from "../libraries/PathKey.sol"; +import {IImmutableState} from "./IImmutableState.sol"; /// @title V4 Quoter Interface /// @notice Supports quoting the delta amounts for exact input or exact output swaps. /// @notice For each pool also tells you the sqrt price of the pool after the swap. /// @dev These functions are not marked view because they rely on calling non-view functions and reverting /// to compute the result. They are also not gas efficient and should not be called on-chain. -interface IV4Quoter { +interface IV4Quoter is IImmutableState { struct QuoteExactSingleParams { PoolKey poolKey; bool zeroForOne; diff --git a/test/PositionDescriptor.t.sol b/test/PositionDescriptor.t.sol index 4b326814c..a4c0e6e37 100644 --- a/test/PositionDescriptor.t.sol +++ b/test/PositionDescriptor.t.sol @@ -2,7 +2,7 @@ pragma solidity ^0.8.24; import "forge-std/Test.sol"; -import {PositionDescriptor} from "../src/PositionDescriptor.sol"; +import {IPositionDescriptor} from "../src/interfaces/IPositionDescriptor.sol"; import {CurrencyRatioSortOrder} from "../src/libraries/CurrencyRatioSortOrder.sol"; import {IHooks} from "@uniswap/v4-core/src/interfaces/IHooks.sol"; import {LiquidityAmounts} from "@uniswap/v4-core/test/utils/LiquidityAmounts.sol"; @@ -88,149 +88,164 @@ contract PositionDescriptorTest is Test, PosmTestSetup, GasSnapshot { function test_tokenURI_succeeds() public { int24 tickLower = int24(key.tickSpacing); int24 tickUpper = int24(key.tickSpacing * 2); - uint256 amount0Desired = 100e18; - uint256 amount1Desired = 100e18; - uint256 liquidityToAdd = LiquidityAmounts.getLiquidityForAmounts( - SQRT_PRICE_1_1, - TickMath.getSqrtPriceAtTick(tickLower), - TickMath.getSqrtPriceAtTick(tickUpper), - amount0Desired, - amount1Desired - ); - - PositionConfig memory config = PositionConfig({poolKey: key, tickLower: tickLower, tickUpper: tickUpper}); uint256 tokenId = lpm.nextTokenId(); - mint(config, liquidityToAdd, ActionConstants.MSG_SENDER, ZERO_BYTES); - - // The prefix length is calculated by converting the string to bytes and finding its length - uint256 prefixLength = bytes("data:application/json;base64,").length; - - string memory uri = positionDescriptor.tokenURI(lpm, tokenId); - // Convert the uri to bytes - bytes memory uriBytes = bytes(uri); - - // Slice the uri to get only the base64-encoded part - bytes memory base64Part = new bytes(uriBytes.length - prefixLength); - - for (uint256 i = 0; i < base64Part.length; i++) { - base64Part[i] = uriBytes[i + prefixLength]; + Token memory token; + { + uint256 amount0Desired = 100e18; + uint256 amount1Desired = 100e18; + uint256 liquidityToAdd = LiquidityAmounts.getLiquidityForAmounts( + SQRT_PRICE_1_1, + TickMath.getSqrtPriceAtTick(tickLower), + TickMath.getSqrtPriceAtTick(tickUpper), + amount0Desired, + amount1Desired + ); + + PositionConfig memory config = PositionConfig({poolKey: key, tickLower: tickLower, tickUpper: tickUpper}); + mint(config, liquidityToAdd, ActionConstants.MSG_SENDER, ZERO_BYTES); + + // The prefix length is calculated by converting the string to bytes and finding its length + uint256 prefixLength = bytes("data:application/json;base64,").length; + + string memory uri = positionDescriptor.tokenURI(lpm, tokenId); + // Convert the uri to bytes + bytes memory uriBytes = bytes(uri); + + // Slice the uri to get only the base64-encoded part + bytes memory base64Part = new bytes(uriBytes.length - prefixLength); + + for (uint256 i = 0; i < base64Part.length; i++) { + base64Part[i] = uriBytes[i + prefixLength]; + } + + // Decode the base64-encoded part + bytes memory decoded = Base64.decode(string(base64Part)); + string memory json = string(decoded); + + // decode json + bytes memory data = vm.parseJson(json); + token = abi.decode(data, (Token)); } - // Decode the base64-encoded part - bytes memory decoded = Base64.decode(string(base64Part)); - string memory json = string(decoded); - - // decode json - bytes memory data = vm.parseJson(json); - Token memory token = abi.decode(data, (Token)); - // quote is currency1, base is currency0 assertFalse(positionDescriptor.flipRatio(Currency.unwrap(key.currency0), Currency.unwrap(key.currency1))); string memory symbol0 = SafeCurrencyMetadata.currencySymbol(Currency.unwrap(currency0), nativeCurrencyLabel); string memory symbol1 = SafeCurrencyMetadata.currencySymbol(Currency.unwrap(currency1), nativeCurrencyLabel); - string memory managerAddress = toHexString(address(manager)); - string memory currency0Address = toHexString(Currency.unwrap(currency0)); - string memory currency1Address = toHexString(Currency.unwrap(currency1)); - string memory id = uintToString(tokenId); - string memory hookAddress = address(key.hooks) == address(0) - ? "No Hook" - : string(abi.encodePacked("0x", toHexString(address(key.hooks)))); string memory fee = Descriptor.feeToPercentString(key.fee); - string memory tickToDecimal0 = Descriptor.tickToDecimalString( - tickLower, - key.tickSpacing, - SafeCurrencyMetadata.currencyDecimals(Currency.unwrap(currency0)), - SafeCurrencyMetadata.currencyDecimals(Currency.unwrap(currency1)), - false - ); - string memory tickToDecimal1 = Descriptor.tickToDecimalString( - tickUpper, - key.tickSpacing, - SafeCurrencyMetadata.currencyDecimals(Currency.unwrap(currency0)), - SafeCurrencyMetadata.currencyDecimals(Currency.unwrap(currency1)), - false - ); - - assertEq( - token.name, - string( - abi.encodePacked( - "Uniswap - ", fee, " - ", symbol1, "/", symbol0, " - ", tickToDecimal0, "<>", tickToDecimal1 + { + string memory tickToDecimal0 = Descriptor.tickToDecimalString( + tickLower, + key.tickSpacing, + SafeCurrencyMetadata.currencyDecimals(Currency.unwrap(currency0)), + SafeCurrencyMetadata.currencyDecimals(Currency.unwrap(currency1)), + false + ); + string memory tickToDecimal1 = Descriptor.tickToDecimalString( + tickUpper, + key.tickSpacing, + SafeCurrencyMetadata.currencyDecimals(Currency.unwrap(currency0)), + SafeCurrencyMetadata.currencyDecimals(Currency.unwrap(currency1)), + false + ); + + assertEq( + token.name, + string( + abi.encodePacked( + "Uniswap - ", fee, " - ", symbol1, "/", symbol0, " - ", tickToDecimal0, "<>", tickToDecimal1 + ) ) - ) - ); - assertEq( - token.description, - string( - abi.encodePacked( - unicode"This NFT represents a liquidity position in a Uniswap v4 ", - symbol1, - "-", - symbol0, - " pool. The owner of this NFT can modify or redeem the position.\n\nPool Manager Address: ", - managerAddress, - "\n", - symbol1, - " Address: ", - currency1Address, - "\n", - symbol0, - " Address: ", - currency0Address, - "\nHook Address: ", - hookAddress, - "\nFee Tier: ", - fee, - "\nToken ID: ", - id, - "\n\n", - unicode"⚠️ DISCLAIMER: Due diligence is imperative when assessing this NFT. Make sure currency addresses match the expected currencies, as currency symbols may be imitated." + ); + } + { + string memory managerAddress = toHexString(address(manager)); + string memory currency0Address = toHexString(Currency.unwrap(currency0)); + string memory currency1Address = toHexString(Currency.unwrap(currency1)); + string memory id = uintToString(tokenId); + string memory hookAddress = address(key.hooks) == address(0) + ? "No Hook" + : string(abi.encodePacked("0x", toHexString(address(key.hooks)))); + + assertEq( + token.description, + string( + abi.encodePacked( + abi.encodePacked( + unicode"This NFT represents a liquidity position in a Uniswap v4 ", + symbol1, + "-", + symbol0, + " pool. The owner of this NFT can modify or redeem the position.\n\nPool Manager Address: ", + managerAddress, + "\n", + symbol1, + " Address: ", + currency1Address + ), + abi.encodePacked( + "\n", + symbol0, + " Address: ", + currency0Address, + "\nHook Address: ", + hookAddress, + "\nFee Tier: ", + fee, + "\nToken ID: ", + id, + "\n\n", + unicode"⚠️ DISCLAIMER: Due diligence is imperative when assessing this NFT. Make sure currency addresses match the expected currencies, as currency symbols may be imitated." + ) + ) ) - ) - ); + ); + } } function test_native_tokenURI_succeeds() public { (nativeKey,) = initPool(CurrencyLibrary.ADDRESS_ZERO, currency1, IHooks(address(0)), 3000, SQRT_PRICE_1_1); int24 tickLower = int24(nativeKey.tickSpacing); int24 tickUpper = int24(nativeKey.tickSpacing * 2); - uint256 amount0Desired = 100e18; - uint256 amount1Desired = 100e18; - uint256 liquidityToAdd = LiquidityAmounts.getLiquidityForAmounts( - SQRT_PRICE_1_1, - TickMath.getSqrtPriceAtTick(tickLower), - TickMath.getSqrtPriceAtTick(tickUpper), - amount0Desired, - amount1Desired - ); - - PositionConfig memory config = PositionConfig({poolKey: nativeKey, tickLower: tickLower, tickUpper: tickUpper}); + Token memory token; uint256 tokenId = lpm.nextTokenId(); - mintWithNative(SQRT_PRICE_1_1, config, liquidityToAdd, ActionConstants.MSG_SENDER, ZERO_BYTES); - - // The prefix length is calculated by converting the string to bytes and finding its length - uint256 prefixLength = bytes("data:application/json;base64,").length; - - string memory uri = positionDescriptor.tokenURI(lpm, tokenId); - // Convert the uri to bytes - bytes memory uriBytes = bytes(uri); - - // Slice the uri to get only the base64-encoded part - bytes memory base64Part = new bytes(uriBytes.length - prefixLength); - - for (uint256 i = 0; i < base64Part.length; i++) { - base64Part[i] = uriBytes[i + prefixLength]; + { + uint256 amount0Desired = 100e18; + uint256 amount1Desired = 100e18; + uint256 liquidityToAdd = LiquidityAmounts.getLiquidityForAmounts( + SQRT_PRICE_1_1, + TickMath.getSqrtPriceAtTick(tickLower), + TickMath.getSqrtPriceAtTick(tickUpper), + amount0Desired, + amount1Desired + ); + + PositionConfig memory config = + PositionConfig({poolKey: nativeKey, tickLower: tickLower, tickUpper: tickUpper}); + mintWithNative(SQRT_PRICE_1_1, config, liquidityToAdd, ActionConstants.MSG_SENDER, ZERO_BYTES); + // The prefix length is calculated by converting the string to bytes and finding its length + uint256 prefixLength = bytes("data:application/json;base64,").length; + + string memory uri = positionDescriptor.tokenURI(lpm, tokenId); + // Convert the uri to bytes + bytes memory uriBytes = bytes(uri); + + // Slice the uri to get only the base64-encoded part + bytes memory base64Part = new bytes(uriBytes.length - prefixLength); + + for (uint256 i = 0; i < base64Part.length; i++) { + base64Part[i] = uriBytes[i + prefixLength]; + } + + // Decode the base64-encoded part + bytes memory decoded = Base64.decode(string(base64Part)); + string memory json = string(decoded); + + // decode json + bytes memory data = vm.parseJson(json); + token = abi.decode(data, (Token)); } - // Decode the base64-encoded part - bytes memory decoded = Base64.decode(string(base64Part)); - string memory json = string(decoded); - - // decode json - bytes memory data = vm.parseJson(json); - Token memory token = abi.decode(data, (Token)); - // quote is currency1, base is currency0 assertFalse( positionDescriptor.flipRatio(Currency.unwrap(nativeKey.currency0), Currency.unwrap(nativeKey.currency1)) @@ -240,70 +255,79 @@ contract PositionDescriptorTest is Test, PosmTestSetup, GasSnapshot { SafeCurrencyMetadata.currencySymbol(Currency.unwrap(nativeKey.currency0), nativeCurrencyLabel); string memory symbol1 = SafeCurrencyMetadata.currencySymbol(Currency.unwrap(nativeKey.currency1), nativeCurrencyLabel); - string memory managerAddress = toHexString(address(manager)); - string memory currency0Address = Currency.unwrap(nativeKey.currency0) == address(0) - ? "Native" - : toHexString(Currency.unwrap(nativeKey.currency0)); - string memory currency1Address = Currency.unwrap(nativeKey.currency1) == address(0) - ? "Native" - : toHexString(Currency.unwrap(nativeKey.currency1)); - string memory id = uintToString(tokenId); - string memory hookAddress = address(nativeKey.hooks) == address(0) - ? "No Hook" - : string(abi.encodePacked("0x", toHexString(address(nativeKey.hooks)))); string memory fee = Descriptor.feeToPercentString(nativeKey.fee); - string memory tickToDecimal0 = Descriptor.tickToDecimalString( - tickLower, - nativeKey.tickSpacing, - SafeCurrencyMetadata.currencyDecimals(Currency.unwrap(currency0)), - SafeCurrencyMetadata.currencyDecimals(Currency.unwrap(currency1)), - false - ); - string memory tickToDecimal1 = Descriptor.tickToDecimalString( - tickUpper, - nativeKey.tickSpacing, - SafeCurrencyMetadata.currencyDecimals(Currency.unwrap(currency0)), - SafeCurrencyMetadata.currencyDecimals(Currency.unwrap(currency1)), - false - ); - - assertEq( - token.name, - string( - abi.encodePacked( - "Uniswap - ", fee, " - ", symbol1, "/", symbol0, " - ", tickToDecimal0, "<>", tickToDecimal1 + { + string memory tickToDecimal0 = Descriptor.tickToDecimalString( + tickLower, + nativeKey.tickSpacing, + SafeCurrencyMetadata.currencyDecimals(Currency.unwrap(currency0)), + SafeCurrencyMetadata.currencyDecimals(Currency.unwrap(currency1)), + false + ); + string memory tickToDecimal1 = Descriptor.tickToDecimalString( + tickUpper, + nativeKey.tickSpacing, + SafeCurrencyMetadata.currencyDecimals(Currency.unwrap(currency0)), + SafeCurrencyMetadata.currencyDecimals(Currency.unwrap(currency1)), + false + ); + + assertEq( + token.name, + string( + abi.encodePacked( + "Uniswap - ", fee, " - ", symbol1, "/", symbol0, " - ", tickToDecimal0, "<>", tickToDecimal1 + ) ) - ) - ); - assertEq( - token.description, - string( - abi.encodePacked( - unicode"This NFT represents a liquidity position in a Uniswap v4 ", - symbol1, - "-", - symbol0, - " pool. The owner of this NFT can modify or redeem the position.\n\nPool Manager Address: ", - managerAddress, - "\n", - symbol1, - " Address: ", - currency1Address, - "\n", - symbol0, - " Address: ", - currency0Address, - "\nHook Address: ", - hookAddress, - "\nFee Tier: ", - fee, - "\nToken ID: ", - id, - "\n\n", - unicode"⚠️ DISCLAIMER: Due diligence is imperative when assessing this NFT. Make sure currency addresses match the expected currencies, as currency symbols may be imitated." + ); + } + { + string memory managerAddress = toHexString(address(manager)); + string memory currency0Address = Currency.unwrap(nativeKey.currency0) == address(0) + ? "Native" + : toHexString(Currency.unwrap(nativeKey.currency0)); + string memory currency1Address = Currency.unwrap(nativeKey.currency1) == address(0) + ? "Native" + : toHexString(Currency.unwrap(nativeKey.currency1)); + string memory id = uintToString(tokenId); + string memory hookAddress = address(nativeKey.hooks) == address(0) + ? "No Hook" + : string(abi.encodePacked("0x", toHexString(address(nativeKey.hooks)))); + + assertEq( + token.description, + string( + abi.encodePacked( + abi.encodePacked( + unicode"This NFT represents a liquidity position in a Uniswap v4 ", + symbol1, + "-", + symbol0, + " pool. The owner of this NFT can modify or redeem the position.\n\nPool Manager Address: ", + managerAddress, + "\n", + symbol1, + " Address: ", + currency1Address, + "\n", + symbol0 + ), + abi.encodePacked( + " Address: ", + currency0Address, + "\nHook Address: ", + hookAddress, + "\nFee Tier: ", + fee, + "\nToken ID: ", + id, + "\n\n", + unicode"⚠️ DISCLAIMER: Due diligence is imperative when assessing this NFT. Make sure currency addresses match the expected currencies, as currency symbols may be imitated." + ) + ) ) - ) - ); + ); + } } function test_tokenURI_revertsWithInvalidTokenId() public { @@ -323,7 +347,7 @@ contract PositionDescriptorTest is Test, PosmTestSetup, GasSnapshot { uint256 tokenId = lpm.nextTokenId(); mint(config, liquidityToAdd, ActionConstants.MSG_SENDER, ZERO_BYTES); - vm.expectRevert(abi.encodeWithSelector(PositionDescriptor.InvalidTokenId.selector, tokenId + 1)); + vm.expectRevert(abi.encodeWithSelector(IPositionDescriptor.InvalidTokenId.selector, tokenId + 1)); positionDescriptor.tokenURI(lpm, tokenId + 1); } diff --git a/test/StateViewTest.t.sol b/test/StateViewTest.t.sol index c243f12fa..9feb9332c 100644 --- a/test/StateViewTest.t.sol +++ b/test/StateViewTest.t.sol @@ -19,6 +19,7 @@ import {FixedPoint128} from "@uniswap/v4-core/src/libraries/FixedPoint128.sol"; import {Deployers} from "@uniswap/v4-core/test/utils/Deployers.sol"; import {Fuzzers} from "@uniswap/v4-core/src/test/Fuzzers.sol"; import {Position} from "@uniswap/v4-core/src/libraries/Position.sol"; +import {Deploy} from "./shared/Deploy.sol"; import {StateView} from "../src/lens/StateView.sol"; @@ -40,7 +41,7 @@ contract StateViewTest is Test, Deployers, Fuzzers, GasSnapshot { poolId = key.toId(); manager.initialize(key, SQRT_PRICE_1_1); - state = new StateView(manager); + state = Deploy.stateView(address(manager)); } function test_getSlot0() public { diff --git a/test/V4Quoter.t.sol b/test/V4Quoter.t.sol index fc91ce47a..5deaacf11 100644 --- a/test/V4Quoter.t.sol +++ b/test/V4Quoter.t.sol @@ -4,8 +4,7 @@ pragma solidity ^0.8.20; import {Test} from "forge-std/Test.sol"; import {PathKey} from "../src/libraries/PathKey.sol"; -import {IV4Quoter} from "../src/interfaces/IV4Quoter.sol"; -import {V4Quoter} from "../src/lens/V4Quoter.sol"; +import {Deploy, IV4Quoter} from "../test/shared/Deploy.sol"; import {BaseV4Quoter} from "../src/base/BaseV4Quoter.sol"; import {GasSnapshot} from "forge-gas-snapshot/GasSnapshot.sol"; @@ -40,7 +39,7 @@ contract QuoterTest is Test, Deployers, GasSnapshot { uint256 internal constant CONTROLLER_GAS_LIMIT = 500000; - V4Quoter quoter; + IV4Quoter quoter; PoolModifyLiquidityTest positionManager; @@ -56,7 +55,7 @@ contract QuoterTest is Test, Deployers, GasSnapshot { function setUp() public { deployFreshManagerAndRouters(); - quoter = new V4Quoter(IPoolManager(manager)); + quoter = Deploy.v4Quoter(address(manager)); positionManager = new PoolModifyLiquidityTest(manager); // salts are chosen so that address(token0) < address(token1) && address(token1) < address(token2) diff --git a/test/mocks/MockBadSubscribers.sol b/test/mocks/MockBadSubscribers.sol index d9c99cbbe..525687e0b 100644 --- a/test/mocks/MockBadSubscribers.sol +++ b/test/mocks/MockBadSubscribers.sol @@ -2,13 +2,13 @@ pragma solidity ^0.8.20; import {ISubscriber} from "../../src/interfaces/ISubscriber.sol"; -import {PositionManager} from "../../src/PositionManager.sol"; +import {IPositionManager} from "../../src/interfaces/IPositionManager.sol"; import {BalanceDelta} from "@uniswap/v4-core/src/types/BalanceDelta.sol"; import {PositionInfo} from "../../src/libraries/PositionInfoLibrary.sol"; /// @notice A subscriber contract that returns values from the subscriber entrypoints contract MockReturnDataSubscriber is ISubscriber { - PositionManager posm; + IPositionManager posm; uint256 public notifySubscribeCount; uint256 public notifyUnsubscribeCount; @@ -20,7 +20,7 @@ contract MockReturnDataSubscriber is ISubscriber { uint256 memPtr; - constructor(PositionManager _posm) { + constructor(IPositionManager _posm) { posm = _posm; } @@ -61,13 +61,13 @@ contract MockReturnDataSubscriber is ISubscriber { /// @notice A subscriber contract that returns values from the subscriber entrypoints contract MockRevertSubscriber is ISubscriber { - PositionManager posm; + IPositionManager posm; error NotAuthorizedNotifer(address sender); error TestRevert(string); - constructor(PositionManager _posm) { + constructor(IPositionManager _posm) { posm = _posm; } diff --git a/test/mocks/MockReenterHook.sol b/test/mocks/MockReenterHook.sol index e6d6f2db5..527475c94 100644 --- a/test/mocks/MockReenterHook.sol +++ b/test/mocks/MockReenterHook.sol @@ -5,10 +5,11 @@ import {IPoolManager} from "@uniswap/v4-core/src/interfaces/IPoolManager.sol"; import {PoolKey} from "@uniswap/v4-core/src/types/PoolKey.sol"; import {Hooks} from "@uniswap/v4-core/src/libraries/Hooks.sol"; import {BaseTestHooks} from "@uniswap/v4-core/src/test/BaseTestHooks.sol"; -import {PositionManager} from "../../src/PositionManager.sol"; +import {IPositionManager} from "../../src/interfaces/IPositionManager.sol"; +import {IERC721} from "forge-std/interfaces/IERC721.sol"; contract MockReenterHook is BaseTestHooks { - PositionManager posm; + IPositionManager posm; function beforeAddLiquidity( address, @@ -21,8 +22,8 @@ contract MockReenterHook is BaseTestHooks { } (bytes4 selector, address owner, uint256 tokenId) = abi.decode(functionSelector, (bytes4, address, uint256)); - if (selector == posm.transferFrom.selector) { - posm.transferFrom(owner, address(this), tokenId); + if (selector == IERC721(address(posm)).transferFrom.selector) { + IERC721(address(posm)).transferFrom(owner, address(this), tokenId); } else if (selector == posm.subscribe.selector) { posm.subscribe(tokenId, address(this), ""); } else if (selector == posm.unsubscribe.selector) { @@ -31,7 +32,7 @@ contract MockReenterHook is BaseTestHooks { return this.beforeAddLiquidity.selector; } - function setPosm(PositionManager _posm) external { + function setPosm(IPositionManager _posm) external { posm = _posm; } } diff --git a/test/mocks/MockSubscriber.sol b/test/mocks/MockSubscriber.sol index 64a167abb..c38cb6469 100644 --- a/test/mocks/MockSubscriber.sol +++ b/test/mocks/MockSubscriber.sol @@ -2,13 +2,13 @@ pragma solidity ^0.8.20; import {ISubscriber} from "../../src/interfaces/ISubscriber.sol"; -import {PositionManager} from "../../src/PositionManager.sol"; +import {IPositionManager} from "../../src/interfaces/IPositionManager.sol"; import {BalanceDelta} from "@uniswap/v4-core/src/types/BalanceDelta.sol"; import {PositionInfo} from "../../src/libraries/PositionInfoLibrary.sol"; /// @notice A subscriber contract that ingests updates from the v4 position manager contract MockSubscriber is ISubscriber { - PositionManager posm; + IPositionManager posm; uint256 public notifySubscribeCount; uint256 public notifyUnsubscribeCount; @@ -23,7 +23,7 @@ contract MockSubscriber is ISubscriber { error NotImplemented(); - constructor(PositionManager _posm) { + constructor(IPositionManager _posm) { posm = _posm; } diff --git a/test/position-managers/Execute.t.sol b/test/position-managers/Execute.t.sol index dd99d86b1..f9eea6a2f 100644 --- a/test/position-managers/Execute.t.sol +++ b/test/position-managers/Execute.t.sol @@ -16,9 +16,9 @@ import {LiquidityAmounts} from "@uniswap/v4-core/test/utils/LiquidityAmounts.sol import {Position} from "@uniswap/v4-core/src/libraries/Position.sol"; import {IERC20} from "forge-std/interfaces/IERC20.sol"; +import {IERC721} from "forge-std/interfaces/IERC721.sol"; import {IPositionManager} from "../../src/interfaces/IPositionManager.sol"; -import {PositionManager} from "../../src/PositionManager.sol"; import {PositionConfig} from "../shared/PositionConfig.sol"; import {ActionConstants} from "../../src/libraries/ActionConstants.sol"; import {Actions} from "../../src/libraries/Actions.sol"; @@ -232,7 +232,7 @@ contract ExecuteTest is Test, PosmTestSetup, LiquidityFuzzers { // old position was burned vm.expectRevert(); - lpm.ownerOf(tokenId); + IERC721(address(lpm)).ownerOf(tokenId); { // old position has no liquidity @@ -241,7 +241,7 @@ contract ExecuteTest is Test, PosmTestSetup, LiquidityFuzzers { // new token was minted uint256 newTokenId = lpm.nextTokenId() - 1; - assertEq(lpm.ownerOf(newTokenId), address(this)); + assertEq(IERC721(address(lpm)).ownerOf(newTokenId), address(this)); // new token has expected liquidity diff --git a/test/position-managers/FeeCollection.t.sol b/test/position-managers/FeeCollection.t.sol index c25085365..169763010 100644 --- a/test/position-managers/FeeCollection.t.sol +++ b/test/position-managers/FeeCollection.t.sol @@ -13,7 +13,6 @@ import {FixedPointMathLib} from "solmate/src/utils/FixedPointMathLib.sol"; import {IERC20} from "forge-std/interfaces/IERC20.sol"; -import {PositionManager} from "../../src/PositionManager.sol"; import {PositionConfig} from "../shared/PositionConfig.sol"; import {LiquidityFuzzers} from "../shared/fuzz/LiquidityFuzzers.sol"; diff --git a/test/position-managers/IncreaseLiquidity.t.sol b/test/position-managers/IncreaseLiquidity.t.sol index a0264d2b1..bfda58e79 100644 --- a/test/position-managers/IncreaseLiquidity.t.sol +++ b/test/position-managers/IncreaseLiquidity.t.sol @@ -19,7 +19,6 @@ import {SafeCast} from "@uniswap/v4-core/src/libraries/SafeCast.sol"; import {IERC20} from "forge-std/interfaces/IERC20.sol"; -import {PositionManager} from "../../src/PositionManager.sol"; import {DeltaResolver} from "../../src/base/DeltaResolver.sol"; import {PositionConfig} from "../shared/PositionConfig.sol"; import {SlippageCheck} from "../../src/libraries/SlippageCheck.sol"; diff --git a/test/position-managers/NativeToken.t.sol b/test/position-managers/NativeToken.t.sol index c79f74dea..2d7ef94e0 100644 --- a/test/position-managers/NativeToken.t.sol +++ b/test/position-managers/NativeToken.t.sol @@ -20,12 +20,11 @@ import {SafeCast} from "@uniswap/v4-core/src/libraries/SafeCast.sol"; import {Position} from "@uniswap/v4-core/src/libraries/Position.sol"; import {IERC20} from "forge-std/interfaces/IERC20.sol"; +import {IERC721} from "forge-std/interfaces/IERC721.sol"; import {ERC721} from "@openzeppelin/contracts/token/ERC721/ERC721.sol"; -import {IERC721} from "@openzeppelin/contracts/interfaces/IERC721.sol"; import {IPositionManager} from "../../src/interfaces/IPositionManager.sol"; import {Actions} from "../../src/libraries/Actions.sol"; -import {PositionManager} from "../../src/PositionManager.sol"; import {ActionConstants} from "../../src/libraries/ActionConstants.sol"; import {MockSubscriber} from "../mocks/MockSubscriber.sol"; @@ -250,7 +249,7 @@ contract PositionManagerTest is Test, PosmTestSetup, LiquidityFuzzers { // OZ 721 will revert if the token does not exist vm.expectRevert(); - lpm.ownerOf(1); + IERC721(address(lpm)).ownerOf(1); // no tokens were lost, TODO: fuzzer showing off by 1 sometimes assertApproxEqAbs(currency0.balanceOfSelf(), balance0Start, 1 wei); @@ -308,7 +307,7 @@ contract PositionManagerTest is Test, PosmTestSetup, LiquidityFuzzers { // OZ 721 will revert if the token does not exist vm.expectRevert(); - lpm.ownerOf(1); + IERC721(address(lpm)).ownerOf(1); // no tokens were lost, TODO: fuzzer showing off by 1 sometimes assertApproxEqAbs(currency0.balanceOfSelf(), balance0Start, 1 wei); @@ -356,7 +355,7 @@ contract PositionManagerTest is Test, PosmTestSetup, LiquidityFuzzers { // OZ 721 will revert if the token does not exist vm.expectRevert(); - lpm.ownerOf(1); + IERC721(address(lpm)).ownerOf(1); // no tokens were lost, TODO: fuzzer showing off by 1 sometimes assertApproxEqAbs(currency0.balanceOfSelf(), balance0Start, 1 wei); @@ -409,7 +408,7 @@ contract PositionManagerTest is Test, PosmTestSetup, LiquidityFuzzers { // OZ 721 will revert if the token does not exist vm.expectRevert(); - lpm.ownerOf(1); + IERC721(address(lpm)).ownerOf(1); // no tokens were lost, TODO: fuzzer showing off by 1 sometimes assertApproxEqAbs(currency0.balanceOfSelf(), balance0Start, 1 wei); diff --git a/test/position-managers/Permit.t.sol b/test/position-managers/Permit.t.sol index 0ce9a5b9a..2bddf39d4 100644 --- a/test/position-managers/Permit.t.sol +++ b/test/position-managers/Permit.t.sol @@ -226,7 +226,7 @@ contract PermitTest is Test, PosmTestSetup { // alice revokes the nonce vm.prank(alice); - lpm.revokeNonce(nonce); + UnorderedNonce(address(lpm)).revokeNonce(nonce); // alice gives bob spender permissions bytes32 digest = getDigest(bob, tokenIdAlice, nonce, block.timestamp + 1); diff --git a/test/position-managers/PositionManager.gas.t.sol b/test/position-managers/PositionManager.gas.t.sol index bf27604f9..fd7502136 100644 --- a/test/position-managers/PositionManager.gas.t.sol +++ b/test/position-managers/PositionManager.gas.t.sol @@ -16,9 +16,8 @@ import {StateLibrary} from "@uniswap/v4-core/src/libraries/StateLibrary.sol"; import {IERC20} from "forge-std/interfaces/IERC20.sol"; -import {IPositionManager} from "../../src/interfaces/IPositionManager.sol"; +import {IPositionManager, IPoolInitializer} from "../../src/interfaces/IPositionManager.sol"; import {Actions} from "../../src/libraries/Actions.sol"; -import {PositionManager} from "../../src/PositionManager.sol"; import {PositionConfig} from "../shared/PositionConfig.sol"; import {IMulticall_v4} from "../../src/interfaces/IMulticall_v4.sol"; import {Planner, Plan} from "../shared/Planner.sol"; @@ -397,7 +396,7 @@ contract PosMGasTest is Test, PosmTestSetup, GasSnapshot { // Use multicall to initialize a pool and mint liquidity bytes[] memory calls = new bytes[](2); - calls[0] = abi.encodeWithSelector(lpm.initializePool.selector, key, SQRT_PRICE_1_1); + calls[0] = abi.encodeWithSelector(IPoolInitializer.initializePool.selector, key, SQRT_PRICE_1_1); config = PositionConfig({ poolKey: key, diff --git a/test/position-managers/PositionManager.modifyLiquidities.t.sol b/test/position-managers/PositionManager.modifyLiquidities.t.sol index 664758616..de8fac20d 100644 --- a/test/position-managers/PositionManager.modifyLiquidities.t.sol +++ b/test/position-managers/PositionManager.modifyLiquidities.t.sol @@ -3,6 +3,7 @@ pragma solidity ^0.8.24; import "forge-std/Test.sol"; import {IERC20} from "forge-std/interfaces/IERC20.sol"; +import {IERC721} from "forge-std/interfaces/IERC721.sol"; import {CustomRevert} from "@uniswap/v4-core/src/libraries/CustomRevert.sol"; import {PoolManager} from "@uniswap/v4-core/src/PoolManager.sol"; @@ -26,7 +27,6 @@ import {IPositionManager} from "../../src/interfaces/IPositionManager.sol"; import {IMulticall_v4} from "../../src/interfaces/IMulticall_v4.sol"; import {ReentrancyLock} from "../../src/base/ReentrancyLock.sol"; import {Actions} from "../../src/libraries/Actions.sol"; -import {PositionManager} from "../../src/PositionManager.sol"; import {PositionConfig} from "../shared/PositionConfig.sol"; import {BipsLibrary} from "../../src/libraries/BipsLibrary.sol"; @@ -123,8 +123,8 @@ contract PositionManagerModifyLiquiditiesTest is Test, PosmTestSetup, LiquidityF liquidity = lpm.getPositionLiquidity(hookTokenId); assertEq(liquidity, newLiquidity); - assertEq(lpm.ownerOf(tokenId), address(this)); // original position owned by this contract - assertEq(lpm.ownerOf(hookTokenId), address(hookModifyLiquidities)); // hook position owned by hook + assertEq(IERC721(address(lpm)).ownerOf(tokenId), address(this)); // original position owned by this contract + assertEq(IERC721(address(lpm)).ownerOf(hookTokenId), address(hookModifyLiquidities)); // hook position owned by hook } /// @dev hook must be approved to increase liquidity @@ -134,7 +134,7 @@ contract PositionManagerModifyLiquiditiesTest is Test, PosmTestSetup, LiquidityF mint(config, initialLiquidity, address(this), ZERO_BYTES); // approve the hook for increasing liquidity - lpm.approve(address(hookModifyLiquidities), tokenId); + IERC721(address(lpm)).approve(address(hookModifyLiquidities), tokenId); // hook increases liquidity in beforeSwap via hookData uint256 newLiquidity = 10e18; @@ -154,7 +154,7 @@ contract PositionManagerModifyLiquiditiesTest is Test, PosmTestSetup, LiquidityF mint(config, initialLiquidity, address(this), ZERO_BYTES); // approve the hook for decreasing liquidity - lpm.approve(address(hookModifyLiquidities), tokenId); + IERC721(address(lpm)).approve(address(hookModifyLiquidities), tokenId); // hook decreases liquidity in beforeSwap via hookData uint256 liquidityToDecrease = 10e18; @@ -174,7 +174,7 @@ contract PositionManagerModifyLiquiditiesTest is Test, PosmTestSetup, LiquidityF mint(config, initialLiquidity, address(this), ZERO_BYTES); // approve the hook for collecting liquidity - lpm.approve(address(hookModifyLiquidities), tokenId); + IERC721(address(lpm)).approve(address(hookModifyLiquidities), tokenId); // donate to generate revenue uint256 feeRevenue0 = 1e18; @@ -212,7 +212,7 @@ contract PositionManagerModifyLiquiditiesTest is Test, PosmTestSetup, LiquidityF BalanceDelta mintDelta = hookModifyLiquidities.deltas(hookModifyLiquidities.numberDeltasReturned() - 1); // approve the hook for burning liquidity - lpm.approve(address(hookModifyLiquidities), tokenId); + IERC721(address(lpm)).approve(address(hookModifyLiquidities), tokenId); uint256 balance0HookBefore = currency0.balanceOf(address(hookModifyLiquidities)); uint256 balance1HookBefore = currency1.balanceOf(address(hookModifyLiquidities)); @@ -227,7 +227,7 @@ contract PositionManagerModifyLiquiditiesTest is Test, PosmTestSetup, LiquidityF assertEq(liquidity, 0); // 721 will revert if the token does not exist vm.expectRevert(); - lpm.ownerOf(tokenId); + IERC721(address(lpm)).ownerOf(tokenId); // hook claimed the burned liquidity assertEq( @@ -417,7 +417,7 @@ contract PositionManagerModifyLiquiditiesTest is Test, PosmTestSetup, LiquidityF // The full eth amount was "spent" because some was wrapped into weth and refunded. assertApproxEqAbs(balanceEthBefore - balanceEthAfter, 102 ether, 1 wei); assertApproxEqAbs(balance1Before - balance1After, 100 ether, 1 wei); - assertEq(lpm.ownerOf(tokenId), address(this)); + assertEq(IERC721(address(lpm)).ownerOf(tokenId), address(this)); assertEq(lpm.getPositionLiquidity(tokenId), liquidityAmount); assertEq(_WETH9.balanceOf(address(lpm)), 0); assertEq(address(lpm).balance, 0); @@ -479,7 +479,7 @@ contract PositionManagerModifyLiquiditiesTest is Test, PosmTestSetup, LiquidityF // Approx 100 eth was spent because the extra 2 were refunded. assertApproxEqAbs(balanceEthBefore - balanceEthAfter, 100 ether, 1 wei); assertApproxEqAbs(balance1Before - balance1After, 100 ether, 1 wei); - assertEq(lpm.ownerOf(tokenId), address(this)); + assertEq(IERC721(address(lpm)).ownerOf(tokenId), address(this)); assertEq(lpm.getPositionLiquidity(tokenId), liquidityAmount); assertEq(_WETH9.balanceOf(address(lpm)), 0); assertEq(address(lpm).balance, 0); @@ -539,7 +539,7 @@ contract PositionManagerModifyLiquiditiesTest is Test, PosmTestSetup, LiquidityF // The full eth amount was "spent" because some was wrapped into weth and refunded. assertApproxEqAbs(balanceEthBefore - balanceEthAfter, 100 ether, 1 wei); assertApproxEqAbs(balance1Before - balance1After, 100 ether, 1 wei); - assertEq(lpm.ownerOf(tokenId), address(this)); + assertEq(IERC721(address(lpm)).ownerOf(tokenId), address(this)); assertEq(lpm.getPositionLiquidity(tokenId), liquidityAmount); assertEq(_WETH9.balanceOf(address(lpm)), 0); assertEq(address(lpm).balance, 0); @@ -756,7 +756,7 @@ contract PositionManagerModifyLiquiditiesTest is Test, PosmTestSetup, LiquidityF uint256 fotBalanceAfter = Currency.wrap(address(fotToken)).balanceOf(address(this)); - assertEq(lpm.ownerOf(tokenId), address(this)); + assertEq(IERC721(address(lpm)).ownerOf(tokenId), address(this)); assertEq(lpm.getPositionLiquidity(tokenId), expectedLiquidity); assertEq(fotBalanceBefore - fotBalanceAfter, 1000e18); } @@ -768,7 +768,7 @@ contract PositionManagerModifyLiquiditiesTest is Test, PosmTestSetup, LiquidityF mint(fotConfig, initialLiquidity, address(this), ZERO_BYTES); - assertEq(lpm.ownerOf(tokenId), address(this)); + assertEq(IERC721(address(lpm)).ownerOf(tokenId), address(this)); assertEq(lpm.getPositionLiquidity(tokenId), initialLiquidity); Plan memory planner = Planner.init(); @@ -801,7 +801,7 @@ contract PositionManagerModifyLiquiditiesTest is Test, PosmTestSetup, LiquidityF mint(fotConfig, initialLiquidity, address(this), ZERO_BYTES); - assertEq(lpm.ownerOf(tokenId), address(this)); + assertEq(IERC721(address(lpm)).ownerOf(tokenId), address(this)); assertEq(lpm.getPositionLiquidity(tokenId), initialLiquidity); // Use a 1% fee. @@ -837,6 +837,16 @@ contract PositionManagerModifyLiquiditiesTest is Test, PosmTestSetup, LiquidityF assertEq(lpm.getPositionLiquidity(tokenId), initialLiquidity + newLiquidity); } + struct BalanceDiff { + uint256 before; + uint256 _after; + } + + struct Balance { + uint256 _0; + uint256 _1; + } + function test_fuzz_mintFromDeltas_burn_fot( uint256 bips, uint256 amount0, @@ -846,7 +856,6 @@ contract PositionManagerModifyLiquiditiesTest is Test, PosmTestSetup, LiquidityF ) public { bips = bound(bips, 1, 10_000); MockFOT(address(fotToken)).setFee(bips); - tickLower = int24( bound( tickLower, @@ -867,28 +876,30 @@ contract PositionManagerModifyLiquiditiesTest is Test, PosmTestSetup, LiquidityF vm.assume(tickUpper > tickLower); (uint160 sqrtPriceX96,,,) = manager.getSlot0(fotKey.toId()); - uint128 maxLiquidityPerTick = Pool.tickSpacingToMaxLiquidityPerTick(fotKey.tickSpacing); - - (uint256 maxAmount0, uint256 maxAmount1) = LiquidityAmounts.getAmountsForLiquidity( - sqrtPriceX96, - TickMath.getSqrtPriceAtTick(tickLower), - TickMath.getSqrtPriceAtTick(tickUpper), - maxLiquidityPerTick - ); + { + uint128 maxLiquidityPerTick = Pool.tickSpacingToMaxLiquidityPerTick(fotKey.tickSpacing); + (uint256 maxAmount0, uint256 maxAmount1) = LiquidityAmounts.getAmountsForLiquidity( + sqrtPriceX96, + TickMath.getSqrtPriceAtTick(tickLower), + TickMath.getSqrtPriceAtTick(tickUpper), + maxLiquidityPerTick + ); - maxAmount0 = maxAmount0 == 0 ? 1 : maxAmount0 > STARTING_USER_BALANCE ? STARTING_USER_BALANCE : maxAmount0; - maxAmount1 = maxAmount1 == 0 ? 1 : maxAmount1 > STARTING_USER_BALANCE ? STARTING_USER_BALANCE : maxAmount1; - amount0 = bound(amount0, 1, maxAmount0); - amount1 = bound(amount1, 1, maxAmount1); + maxAmount0 = maxAmount0 == 0 ? 1 : maxAmount0 > STARTING_USER_BALANCE ? STARTING_USER_BALANCE : maxAmount0; + maxAmount1 = maxAmount1 == 0 ? 1 : maxAmount1 > STARTING_USER_BALANCE ? STARTING_USER_BALANCE : maxAmount1; + amount0 = bound(amount0, 1, maxAmount0); + amount1 = bound(amount1, 1, maxAmount1); + } uint256 tokenId = lpm.nextTokenId(); - uint256 balance0 = fotKey.currency0.balanceOf(address(this)); - uint256 balance1 = fotKey.currency1.balanceOf(address(this)); - uint256 balance0PM = fotKey.currency0.balanceOf(address(manager)); - uint256 balance1PM = fotKey.currency1.balanceOf(address(manager)); + BalanceDiff memory balance0 = BalanceDiff(fotKey.currency0.balanceOf(address(this)), 0); + BalanceDiff memory balance1 = BalanceDiff(fotKey.currency1.balanceOf(address(this)), 0); + BalanceDiff memory balance0PM = BalanceDiff(fotKey.currency0.balanceOf(address(manager)), 0); + BalanceDiff memory balance1PM = BalanceDiff(fotKey.currency1.balanceOf(address(manager)), 0); Plan memory planner = Planner.init(); + planner.add(Actions.SETTLE, abi.encode(fotKey.currency0, amount0, true)); planner.add(Actions.SETTLE, abi.encode(fotKey.currency1, amount1, true)); planner.add( @@ -906,60 +917,68 @@ contract PositionManagerModifyLiquiditiesTest is Test, PosmTestSetup, LiquidityF // take the excess of each currency planner.add(Actions.TAKE_PAIR, abi.encode(fotKey.currency0, fotKey.currency1, ActionConstants.MSG_SENDER)); - bytes memory actions = planner.encode(); - - bool currency0IsFOT = fotKey.currency0 == Currency.wrap(address(fotToken)); - bool positionIsEntirelyInOtherToken = currency0IsFOT - ? tickUpper <= TickMath.getTickAtSqrtPrice(sqrtPriceX96) - : tickLower > TickMath.getTickAtSqrtPrice(sqrtPriceX96); - - if (bips == 10000 && !positionIsEntirelyInOtherToken) { + // needed to remove variables because of stack too deep + // bool currency0IsFOT = fotKey.currency0 == Currency.wrap(address(fotToken)); + // bool positionIsEntirelyInOtherToken = currency0IsFOT + // ? tickUpper <= TickMath.getTickAtSqrtPrice(sqrtPriceX96) + // : tickLower > TickMath.getTickAtSqrtPrice(sqrtPriceX96); + // if (bips == 10000 && !positionIsEntirelyInOtherToken) { + if ( + bips == 10000 + && !( + fotKey.currency0 == Currency.wrap(address(fotToken)) + ? tickUpper <= TickMath.getTickAtSqrtPrice(sqrtPriceX96) + : tickLower > TickMath.getTickAtSqrtPrice(sqrtPriceX96) + ) + ) { vm.expectRevert(Position.CannotUpdateEmptyPosition.selector); - lpm.modifyLiquidities(actions, _deadline); + lpm.modifyLiquidities(planner.encode(), _deadline); } else { // MINT FROM DELTAS. - lpm.modifyLiquidities(actions, _deadline); + lpm.modifyLiquidities(planner.encode(), _deadline); - uint256 balance0After = fotKey.currency0.balanceOf(address(this)); - uint256 balance1After = fotKey.currency1.balanceOf(address(this)); - uint256 balance0PMAfter = fotKey.currency0.balanceOf(address(manager)); - uint256 balance1PMAfter = fotKey.currency1.balanceOf(address(manager)); + balance0._after = fotKey.currency0.balanceOf(address(this)); + balance1._after = fotKey.currency1.balanceOf(address(this)); + balance0PM._after = fotKey.currency0.balanceOf(address(manager)); + balance1PM._after = fotKey.currency1.balanceOf(address(manager)); // Calculate the expected resulting balances used to create liquidity after the fee is applied. - uint256 amountInFOT = currency0IsFOT ? amount0 : amount1; - uint256 expectedFee = amountInFOT.calculatePortion(bips); - (uint256 expected0, uint256 expected1) = currency0IsFOT - ? (balance0 - balance0After - expectedFee, balance1 - balance1After) - : (balance0 - balance0After, balance1 - balance1After - expectedFee); - - assertEq(expected0, balance0PMAfter - balance0PM); - assertEq(expected1, balance1PMAfter - balance1PM); - - // the liquidity that was created is a diff of the balance change - uint128 expectedLiquidity = LiquidityAmounts.getLiquidityForAmounts( - sqrtPriceX96, - TickMath.getSqrtPriceAtTick(tickLower), - TickMath.getSqrtPriceAtTick(tickUpper), - expected0, - expected1 - ); - - assertEq(lpm.ownerOf(tokenId), address(this)); - assertEq(lpm.getPositionLiquidity(tokenId), expectedLiquidity); - + Balance memory expected; + { + bool currency0IsFOT = fotKey.currency0 == Currency.wrap(address(fotToken)); + uint256 expectedFee = (currency0IsFOT ? amount0 : amount1).calculatePortion(bips); + (expected._0, expected._1) = currency0IsFOT + ? (balance0.before - balance0._after - expectedFee, balance1.before - balance1._after) + : (balance0.before - balance0._after, balance1.before - balance1._after - expectedFee); + } + assertEq(expected._0, balance0PM._after - balance0PM.before); + assertEq(expected._1, balance1PM._after - balance1PM.before); + { + // the liquidity that was created is a diff of the balance change + uint128 expectedLiquidity = LiquidityAmounts.getLiquidityForAmounts( + sqrtPriceX96, + TickMath.getSqrtPriceAtTick(tickLower), + TickMath.getSqrtPriceAtTick(tickUpper), + expected._0, + expected._1 + ); + + assertEq(IERC721(address(lpm)).ownerOf(tokenId), address(this)); + assertEq(lpm.getPositionLiquidity(tokenId), expectedLiquidity); + } // BURN. planner = Planner.init(); // Note that the slippage does not include the fee from the transfer. planner.add( Actions.BURN_POSITION, - abi.encode(tokenId, expected0 == 0 ? 0 : expected0 - 1, expected1 == 0 ? 0 : expected1 - 1, ZERO_BYTES) + abi.encode( + tokenId, expected._0 == 0 ? 0 : expected._0 - 1, expected._1 == 0 ? 0 : expected._1 - 1, ZERO_BYTES + ) ); planner.add(Actions.TAKE_PAIR, abi.encode(fotKey.currency0, fotKey.currency1, ActionConstants.MSG_SENDER)); - actions = planner.encode(); - - lpm.modifyLiquidities(actions, _deadline); + lpm.modifyLiquidities(planner.encode(), _deadline); assertEq(lpm.getPositionLiquidity(tokenId), 0); } diff --git a/test/position-managers/PositionManager.multicall.t.sol b/test/position-managers/PositionManager.multicall.t.sol index 087c21027..81ddfed5f 100644 --- a/test/position-managers/PositionManager.multicall.t.sol +++ b/test/position-managers/PositionManager.multicall.t.sol @@ -16,11 +16,10 @@ import {Position} from "@uniswap/v4-core/src/libraries/Position.sol"; import {StateLibrary} from "@uniswap/v4-core/src/libraries/StateLibrary.sol"; import {IERC20} from "forge-std/interfaces/IERC20.sol"; +import {IERC721} from "forge-std/interfaces/IERC721.sol"; -import {IPositionManager} from "../../src/interfaces/IPositionManager.sol"; -import {PoolInitializer} from "../../src/base/PoolInitializer.sol"; +import {IPositionManager, IPoolInitializer} from "../../src/interfaces/IPositionManager.sol"; import {Actions} from "../../src/libraries/Actions.sol"; -import {PositionManager} from "../../src/PositionManager.sol"; import {PositionConfig} from "../shared/PositionConfig.sol"; import {IMulticall_v4} from "../../src/interfaces/IMulticall_v4.sol"; import {LiquidityFuzzers} from "../shared/fuzz/LiquidityFuzzers.sol"; @@ -98,7 +97,7 @@ contract PositionManagerMulticallTest is Test, Permit2SignatureHelpers, PosmTest // Use multicall to initialize a pool and mint liquidity bytes[] memory calls = new bytes[](2); - calls[0] = abi.encodeWithSelector(lpm.initializePool.selector, key, SQRT_PRICE_1_1); + calls[0] = abi.encodeWithSelector(IPoolInitializer.initializePool.selector, key, SQRT_PRICE_1_1); config = PositionConfig({ poolKey: key, @@ -139,7 +138,7 @@ contract PositionManagerMulticallTest is Test, Permit2SignatureHelpers, PosmTest // Use multicall to initialize the pool again. bytes[] memory calls = new bytes[](2); - calls[0] = abi.encodeWithSelector(lpm.initializePool.selector, key, SQRT_PRICE_1_1); + calls[0] = abi.encodeWithSelector(IPoolInitializer.initializePool.selector, key, SQRT_PRICE_1_1); config = PositionConfig({ poolKey: key, @@ -185,7 +184,7 @@ contract PositionManagerMulticallTest is Test, Permit2SignatureHelpers, PosmTest // Use multicall to initialize a pool and mint liquidity bytes[] memory calls = new bytes[](2); - calls[0] = abi.encodeWithSelector(lpm.initializePool.selector, key, SQRT_PRICE_1_1); + calls[0] = abi.encodeWithSelector(IPoolInitializer.initializePool.selector, key, SQRT_PRICE_1_1); config = PositionConfig({ poolKey: key, @@ -341,7 +340,7 @@ contract PositionManagerMulticallTest is Test, Permit2SignatureHelpers, PosmTest assertEq(_amount, permitAmount); assertEq(liquidity, 10e18); - assertEq(lpm.ownerOf(tokenId), bob); + assertEq(IERC721(address(lpm)).ownerOf(tokenId), bob); } function test_multicall_permit_batch_mint() public { @@ -398,7 +397,7 @@ contract PositionManagerMulticallTest is Test, Permit2SignatureHelpers, PosmTest assertEq(_amount0, permitAmount); assertEq(_amount1, permitAmount); assertEq(liquidity, 10e18); - assertEq(lpm.ownerOf(tokenId), bob); + assertEq(IERC721(address(lpm)).ownerOf(tokenId), bob); } /// @notice test that a front-ran permit does not fail a multicall with permit @@ -422,8 +421,8 @@ contract PositionManagerMulticallTest is Test, Permit2SignatureHelpers, PosmTest // bob front-runs the permits vm.startPrank(bob); - lpm.permit(charlie, permit0, sig0); - lpm.permit(charlie, permit1, sig1); + Permit2Forwarder(address(lpm)).permit(charlie, permit0, sig0); + Permit2Forwarder(address(lpm)).permit(charlie, permit1, sig1); vm.stopPrank(); // bob's front-run was successful @@ -440,20 +439,20 @@ contract PositionManagerMulticallTest is Test, Permit2SignatureHelpers, PosmTest // charlie tries to mint an LP token with multicall(permit, permit, mint) bytes[] memory calls = new bytes[](3); - calls[0] = abi.encodeWithSelector(Permit2Forwarder(lpm).permit.selector, charlie, permit0, sig0); - calls[1] = abi.encodeWithSelector(Permit2Forwarder(lpm).permit.selector, charlie, permit1, sig1); + calls[0] = abi.encodeWithSelector(Permit2Forwarder(address(lpm)).permit.selector, charlie, permit0, sig0); + calls[1] = abi.encodeWithSelector(Permit2Forwarder(address(lpm)).permit.selector, charlie, permit1, sig1); bytes memory mintCall = getMintEncoded(config, 10e18, charlie, ZERO_BYTES); calls[2] = abi.encodeWithSelector(IPositionManager.modifyLiquidities.selector, mintCall, _deadline); uint256 tokenId = lpm.nextTokenId(); vm.expectRevert(); - lpm.ownerOf(tokenId); // token does not exist + IERC721(address(lpm)).ownerOf(tokenId); // token does not exist bytes[] memory results = lpm.multicall(calls); assertEq(results[0], abi.encode(abi.encodeWithSelector(InvalidNonce.selector))); assertEq(results[1], abi.encode(abi.encodeWithSelector(InvalidNonce.selector))); - assertEq(lpm.ownerOf(tokenId), charlie); + assertEq(IERC721(address(lpm)).ownerOf(tokenId), charlie); } /// @notice test that a front-ran permitBatch does not fail a multicall with permitBatch @@ -476,7 +475,7 @@ contract PositionManagerMulticallTest is Test, Permit2SignatureHelpers, PosmTest // bob front-runs the permits vm.prank(bob); - lpm.permitBatch(charlie, permit, sig); + Permit2Forwarder(address(lpm)).permitBatch(charlie, permit, sig); // bob's front-run was successful (uint160 _amount, uint48 _expiration, uint48 _nonce) = @@ -492,17 +491,17 @@ contract PositionManagerMulticallTest is Test, Permit2SignatureHelpers, PosmTest // charlie tries to mint an LP token with multicall(permitBatch, mint) bytes[] memory calls = new bytes[](2); - calls[0] = abi.encodeWithSelector(Permit2Forwarder(lpm).permitBatch.selector, charlie, permit, sig); + calls[0] = abi.encodeWithSelector(Permit2Forwarder(address(lpm)).permitBatch.selector, charlie, permit, sig); bytes memory mintCall = getMintEncoded(config, 10e18, charlie, ZERO_BYTES); calls[1] = abi.encodeWithSelector(IPositionManager.modifyLiquidities.selector, mintCall, _deadline); uint256 tokenId = lpm.nextTokenId(); vm.expectRevert(); - lpm.ownerOf(tokenId); // token does not exist + IERC721(address(lpm)).ownerOf(tokenId); // token does not exist bytes[] memory results = lpm.multicall(calls); assertEq(results[0], abi.encode(abi.encodeWithSelector(InvalidNonce.selector))); - assertEq(lpm.ownerOf(tokenId), charlie); + assertEq(IERC721(address(lpm)).ownerOf(tokenId), charlie); } } diff --git a/test/position-managers/PositionManager.notifier.t.sol b/test/position-managers/PositionManager.notifier.t.sol index de25bc412..41504b4e9 100644 --- a/test/position-managers/PositionManager.notifier.t.sol +++ b/test/position-managers/PositionManager.notifier.t.sol @@ -23,6 +23,7 @@ import {INotifier} from "../../src/interfaces/INotifier.sol"; import {MockReturnDataSubscriber, MockRevertSubscriber} from "../mocks/MockBadSubscribers.sol"; import {PositionInfoLibrary, PositionInfo} from "../../src/libraries/PositionInfoLibrary.sol"; import {MockReenterHook} from "../mocks/MockReenterHook.sol"; +import {IERC721} from "forge-std/interfaces/IERC721.sol"; contract PositionManagerNotifierTest is Test, PosmTestSetup, GasSnapshot { using PoolIdLibrary for PoolKey; @@ -91,7 +92,7 @@ contract PositionManagerNotifierTest is Test, PosmTestSetup, GasSnapshot { // approve this contract to operate on alices liq vm.startPrank(alice); - lpm.approve(address(this), tokenId); + IERC721(address(lpm)).approve(address(this), tokenId); vm.stopPrank(); lpm.subscribe(tokenId, address(sub), ZERO_BYTES); @@ -110,7 +111,7 @@ contract PositionManagerNotifierTest is Test, PosmTestSetup, GasSnapshot { // approve this contract to operate on alices liq vm.startPrank(alice); - lpm.approve(address(this), tokenId); + IERC721(address(lpm)).approve(address(this), tokenId); vm.stopPrank(); vm.expectRevert(INotifier.NoCodeSubscriber.selector); @@ -123,7 +124,7 @@ contract PositionManagerNotifierTest is Test, PosmTestSetup, GasSnapshot { // approve this contract to operate on alices liq vm.startPrank(alice); - lpm.approve(address(this), tokenId); + IERC721(address(lpm)).approve(address(this), tokenId); vm.stopPrank(); // successfully subscribe @@ -142,7 +143,7 @@ contract PositionManagerNotifierTest is Test, PosmTestSetup, GasSnapshot { // approve this contract to operate on alices liq vm.startPrank(alice); - lpm.approve(address(this), tokenId); + IERC721(address(lpm)).approve(address(this), tokenId); vm.stopPrank(); lpm.subscribe(tokenId, address(sub), ZERO_BYTES); @@ -171,7 +172,7 @@ contract PositionManagerNotifierTest is Test, PosmTestSetup, GasSnapshot { // approve this contract to operate on alices liq vm.startPrank(alice); - lpm.approve(address(this), tokenId); + IERC721(address(lpm)).approve(address(this), tokenId); vm.stopPrank(); lpm.subscribe(tokenId, address(sub), ZERO_BYTES); @@ -198,7 +199,7 @@ contract PositionManagerNotifierTest is Test, PosmTestSetup, GasSnapshot { // approve this contract to operate on alices liq vm.startPrank(alice); - lpm.approve(address(this), tokenId); + IERC721(address(lpm)).approve(address(this), tokenId); vm.stopPrank(); lpm.subscribe(tokenId, address(sub), ZERO_BYTES); @@ -221,7 +222,7 @@ contract PositionManagerNotifierTest is Test, PosmTestSetup, GasSnapshot { // approve this contract to operate on alices liq vm.startPrank(alice); - lpm.approve(address(this), tokenId); + IERC721(address(lpm)).approve(address(this), tokenId); vm.stopPrank(); lpm.subscribe(tokenId, address(sub), ZERO_BYTES); @@ -229,7 +230,7 @@ contract PositionManagerNotifierTest is Test, PosmTestSetup, GasSnapshot { assertEq(lpm.positionInfo(tokenId).hasSubscriber(), true); assertEq(address(lpm.subscriber(tokenId)), address(sub)); - lpm.transferFrom(alice, bob, tokenId); + IERC721(address(lpm)).transferFrom(alice, bob, tokenId); assertEq(sub.notifyUnsubscribeCount(), 1); assertEq(lpm.positionInfo(tokenId).hasSubscriber(), false); @@ -242,7 +243,7 @@ contract PositionManagerNotifierTest is Test, PosmTestSetup, GasSnapshot { // approve this contract to operate on alices liq vm.startPrank(alice); - lpm.approve(address(this), tokenId); + IERC721(address(lpm)).approve(address(this), tokenId); vm.stopPrank(); lpm.subscribe(tokenId, address(sub), ZERO_BYTES); @@ -253,7 +254,7 @@ contract PositionManagerNotifierTest is Test, PosmTestSetup, GasSnapshot { vm.etch(address(sub), ZERO_BYTES); // unsubscribe happens anyway - lpm.transferFrom(alice, bob, tokenId); + IERC721(address(lpm)).transferFrom(alice, bob, tokenId); assertEq(lpm.positionInfo(tokenId).hasSubscriber(), false); assertEq(address(lpm.subscriber(tokenId)), address(0)); @@ -265,7 +266,7 @@ contract PositionManagerNotifierTest is Test, PosmTestSetup, GasSnapshot { // approve this contract to operate on alices liq vm.startPrank(alice); - lpm.approve(address(this), tokenId); + IERC721(address(lpm)).approve(address(this), tokenId); vm.stopPrank(); lpm.subscribe(tokenId, address(sub), ZERO_BYTES); @@ -273,7 +274,7 @@ contract PositionManagerNotifierTest is Test, PosmTestSetup, GasSnapshot { assertEq(lpm.positionInfo(tokenId).hasSubscriber(), true); assertEq(address(lpm.subscriber(tokenId)), address(sub)); - lpm.safeTransferFrom(alice, bob, tokenId); + IERC721(address(lpm)).safeTransferFrom(alice, bob, tokenId); assertEq(sub.notifyUnsubscribeCount(), 1); assertEq(lpm.positionInfo(tokenId).hasSubscriber(), false); @@ -286,7 +287,7 @@ contract PositionManagerNotifierTest is Test, PosmTestSetup, GasSnapshot { // approve this contract to operate on alices liq vm.startPrank(alice); - lpm.approve(address(this), tokenId); + IERC721(address(lpm)).approve(address(this), tokenId); vm.stopPrank(); lpm.subscribe(tokenId, address(sub), ZERO_BYTES); @@ -297,7 +298,7 @@ contract PositionManagerNotifierTest is Test, PosmTestSetup, GasSnapshot { vm.etch(address(sub), ZERO_BYTES); // unsubscribe happens anyway - lpm.safeTransferFrom(alice, bob, tokenId); + IERC721(address(lpm)).safeTransferFrom(alice, bob, tokenId); assertEq(lpm.positionInfo(tokenId).hasSubscriber(), false); assertEq(address(lpm.subscriber(tokenId)), address(0)); @@ -309,7 +310,7 @@ contract PositionManagerNotifierTest is Test, PosmTestSetup, GasSnapshot { // approve this contract to operate on alices liq vm.startPrank(alice); - lpm.approve(address(this), tokenId); + IERC721(address(lpm)).approve(address(this), tokenId); vm.stopPrank(); lpm.subscribe(tokenId, address(sub), ZERO_BYTES); @@ -317,7 +318,7 @@ contract PositionManagerNotifierTest is Test, PosmTestSetup, GasSnapshot { assertEq(lpm.positionInfo(tokenId).hasSubscriber(), true); assertEq(address(lpm.subscriber(tokenId)), address(sub)); - lpm.safeTransferFrom(alice, bob, tokenId, ""); + IERC721(address(lpm)).safeTransferFrom(alice, bob, tokenId, ""); assertEq(sub.notifyUnsubscribeCount(), 1); assertEq(lpm.positionInfo(tokenId).hasSubscriber(), false); @@ -330,7 +331,7 @@ contract PositionManagerNotifierTest is Test, PosmTestSetup, GasSnapshot { // approve this contract to operate on alices liq vm.startPrank(alice); - lpm.approve(address(this), tokenId); + IERC721(address(lpm)).approve(address(this), tokenId); vm.stopPrank(); lpm.subscribe(tokenId, address(sub), ZERO_BYTES); @@ -348,7 +349,7 @@ contract PositionManagerNotifierTest is Test, PosmTestSetup, GasSnapshot { // approve this contract to operate on alices liq vm.startPrank(alice); - lpm.approve(address(this), tokenId); + IERC721(address(lpm)).approve(address(this), tokenId); vm.stopPrank(); lpm.subscribe(tokenId, address(badSubscriber), ZERO_BYTES); @@ -368,7 +369,7 @@ contract PositionManagerNotifierTest is Test, PosmTestSetup, GasSnapshot { // approve this contract to operate on alices liq vm.startPrank(alice); - lpm.approve(address(this), tokenId); + IERC721(address(lpm)).approve(address(this), tokenId); vm.stopPrank(); lpm.subscribe(tokenId, address(sub), ZERO_BYTES); @@ -468,7 +469,7 @@ contract PositionManagerNotifierTest is Test, PosmTestSetup, GasSnapshot { // approve this contract to operate on alices liq vm.startPrank(alice); - lpm.approve(address(this), tokenId); + IERC721(address(lpm)).approve(address(this), tokenId); vm.stopPrank(); vm.expectRevert(INotifier.NotSubscribed.selector); @@ -481,7 +482,7 @@ contract PositionManagerNotifierTest is Test, PosmTestSetup, GasSnapshot { // approve this contract to operate on alices liq vm.startPrank(alice); - lpm.approve(address(this), tokenId); + IERC721(address(lpm)).approve(address(this), tokenId); vm.stopPrank(); lpm.subscribe(tokenId, address(sub), ZERO_BYTES); @@ -500,7 +501,7 @@ contract PositionManagerNotifierTest is Test, PosmTestSetup, GasSnapshot { // approve this contract to operate on alices liq vm.startPrank(alice); - lpm.approve(address(this), tokenId); + IERC721(address(lpm)).approve(address(this), tokenId); vm.stopPrank(); lpm.subscribe(tokenId, address(sub), subData); @@ -517,7 +518,7 @@ contract PositionManagerNotifierTest is Test, PosmTestSetup, GasSnapshot { // approve this contract to operate on alices liq vm.startPrank(alice); - lpm.approve(address(this), tokenId); + IERC721(address(lpm)).approve(address(this), tokenId); vm.stopPrank(); revertSubscriber.setRevert(true); @@ -540,7 +541,7 @@ contract PositionManagerNotifierTest is Test, PosmTestSetup, GasSnapshot { // approve this contract to operate on alices liq vm.startPrank(alice); - lpm.approve(address(this), tokenId); + IERC721(address(lpm)).approve(address(this), tokenId); vm.stopPrank(); lpm.subscribe(tokenId, address(revertSubscriber), ZERO_BYTES); @@ -575,7 +576,7 @@ contract PositionManagerNotifierTest is Test, PosmTestSetup, GasSnapshot { // approve this contract to operate on alices liq vm.startPrank(alice); - lpm.approve(address(this), tokenId); + IERC721(address(lpm)).approve(address(this), tokenId); vm.stopPrank(); lpm.subscribe(tokenId, address(sub), subData); @@ -602,7 +603,7 @@ contract PositionManagerNotifierTest is Test, PosmTestSetup, GasSnapshot { // approve this contract to operate on alices liq vm.startPrank(alice); - lpm.approve(address(this), tokenId); + IERC721(address(lpm)).approve(address(this), tokenId); vm.stopPrank(); lpm.subscribe(tokenId, address(sub), ZERO_BYTES); @@ -627,7 +628,7 @@ contract PositionManagerNotifierTest is Test, PosmTestSetup, GasSnapshot { bytes memory actions = getMintEncoded(reenterConfig, 10e18, address(this), hookData); // approve hook as it should not revert because it does not have permissions - lpm.approve(address(reenterHook), tokenId); + IERC721(address(lpm)).approve(address(reenterHook), tokenId); // subscribe as it should not revert because there is no subscriber lpm.subscribe(tokenId, address(sub), ZERO_BYTES); @@ -652,7 +653,7 @@ contract PositionManagerNotifierTest is Test, PosmTestSetup, GasSnapshot { bytes memory actions = getMintEncoded(reenterConfig, 10e18, address(this), hookData); // approve hook as it should not revert because it does not have permissions - lpm.approve(address(reenterHook), tokenId); + IERC721(address(lpm)).approve(address(reenterHook), tokenId); // should revert since the pool manager is unlocked vm.expectRevert( @@ -671,11 +672,11 @@ contract PositionManagerNotifierTest is Test, PosmTestSetup, GasSnapshot { uint256 tokenId = lpm.nextTokenId(); mint(reenterConfig, 10e18, address(this), ZERO_BYTES); - bytes memory hookData = abi.encode(lpm.transferFrom.selector, address(this), tokenId); + bytes memory hookData = abi.encode(IERC721(address(lpm)).transferFrom.selector, address(this), tokenId); bytes memory actions = getMintEncoded(reenterConfig, 10e18, address(this), hookData); // approve hook as it should not revert because it does not have permissions - lpm.approve(address(reenterHook), tokenId); + IERC721(address(lpm)).approve(address(reenterHook), tokenId); // should revert since the pool manager is unlocked vm.expectRevert( diff --git a/test/position-managers/PositionManager.t.sol b/test/position-managers/PositionManager.t.sol index 7db64e9b9..a0dc970d2 100644 --- a/test/position-managers/PositionManager.t.sol +++ b/test/position-managers/PositionManager.t.sol @@ -19,10 +19,10 @@ import {Position} from "@uniswap/v4-core/src/libraries/Position.sol"; import {SafeCast} from "@uniswap/v4-core/src/libraries/SafeCast.sol"; import {IERC20} from "forge-std/interfaces/IERC20.sol"; +import {IERC721} from "forge-std/interfaces/IERC721.sol"; import {IPositionManager} from "../../src/interfaces/IPositionManager.sol"; import {Actions} from "../../src/libraries/Actions.sol"; -import {PositionManager} from "../../src/PositionManager.sol"; import {DeltaResolver} from "../../src/base/DeltaResolver.sol"; import {PositionConfig} from "../shared/PositionConfig.sol"; import {SlippageCheck} from "../../src/libraries/SlippageCheck.sol"; @@ -124,7 +124,7 @@ contract PositionManagerTest is Test, PosmTestSetup, LiquidityFuzzers { assertEq(tokenId, 1); assertEq(lpm.nextTokenId(), 2); - assertEq(lpm.ownerOf(tokenId), address(this)); + assertEq(IERC721(address(lpm)).ownerOf(tokenId), address(this)); uint256 liquidity = lpm.getPositionLiquidity(tokenId); @@ -159,7 +159,7 @@ contract PositionManagerTest is Test, PosmTestSetup, LiquidityFuzzers { uint256 balance1After = currency1.balanceOfSelf(); assertEq(tokenId, 1); - assertEq(lpm.ownerOf(1), address(this)); + assertEq(IERC721(address(lpm)).ownerOf(1), address(this)); assertEq(uint256(int256(-delta.amount0())), amount0Desired); assertEq(uint256(int256(-delta.amount1())), amount1Desired); @@ -194,7 +194,7 @@ contract PositionManagerTest is Test, PosmTestSetup, LiquidityFuzzers { uint256 balance1After = currency1.balanceOfSelf(); assertEq(tokenId, 1); - assertEq(lpm.ownerOf(1), alice); + assertEq(IERC721(address(lpm)).ownerOf(1), alice); assertEq(uint256(int256(-delta.amount0())), amount0Desired); assertEq(uint256(int256(-delta.amount1())), amount1Desired); @@ -219,7 +219,7 @@ contract PositionManagerTest is Test, PosmTestSetup, LiquidityFuzzers { BalanceDelta delta = getLastDelta(); assertEq(tokenId, 1); - assertEq(lpm.ownerOf(tokenId), alice); + assertEq(IERC721(address(lpm)).ownerOf(tokenId), alice); // alice was not the payer assertEq(balance0Before - currency0.balanceOfSelf(), uint256(int256(-delta.amount0()))); @@ -355,7 +355,7 @@ contract PositionManagerTest is Test, PosmTestSetup, LiquidityFuzzers { PositionConfig memory config = PositionConfig({poolKey: key, tickLower: params.tickLower, tickUpper: params.tickUpper}); assertEq(tokenId, 1); - assertEq(lpm.ownerOf(1), address(this)); + assertEq(IERC721(address(lpm)).ownerOf(1), address(this)); uint256 liquidity = lpm.getPositionLiquidity(tokenId); @@ -381,7 +381,7 @@ contract PositionManagerTest is Test, PosmTestSetup, LiquidityFuzzers { // 721 will revert if the token does not exist vm.expectRevert(); - lpm.ownerOf(1); + IERC721(address(lpm)).ownerOf(1); // no tokens were lost, TODO: fuzzer showing off by 1 sometimes // Potentially because we round down in core. I believe this is known in V3. But let's check! @@ -399,7 +399,7 @@ contract PositionManagerTest is Test, PosmTestSetup, LiquidityFuzzers { PositionConfig memory config = PositionConfig({poolKey: key, tickLower: params.tickLower, tickUpper: params.tickUpper}); assertEq(tokenId, 1); - assertEq(lpm.ownerOf(1), address(this)); + assertEq(IERC721(address(lpm)).ownerOf(1), address(this)); uint256 liquidity = lpm.getPositionLiquidity(tokenId); @@ -432,7 +432,7 @@ contract PositionManagerTest is Test, PosmTestSetup, LiquidityFuzzers { // OZ 721 will revert if the token does not exist vm.expectRevert(); - lpm.ownerOf(1); + IERC721(address(lpm)).ownerOf(1); // no tokens were lost, TODO: fuzzer showing off by 1 sometimes // Potentially because we round down in core. I believe this is known in V3. But let's check! @@ -750,7 +750,7 @@ contract PositionManagerTest is Test, PosmTestSetup, LiquidityFuzzers { BalanceDelta mintDelta = getLastDelta(); // transfer to alice - lpm.transferFrom(address(this), alice, tokenId); + IERC721(address(lpm)).transferFrom(address(this), alice, tokenId); // alice can burn the position bytes memory calls = getBurnEncoded(tokenId, config, ZERO_BYTES); @@ -763,7 +763,7 @@ contract PositionManagerTest is Test, PosmTestSetup, LiquidityFuzzers { // token was burned and does not exist anymore vm.expectRevert(); - lpm.ownerOf(tokenId); + IERC721(address(lpm)).ownerOf(tokenId); // alice received the principal liquidity assertApproxEqAbs(currency0.balanceOf(alice) - balance0BeforeAlice, uint128(-mintDelta.amount0()), 1 wei); @@ -782,7 +782,7 @@ contract PositionManagerTest is Test, PosmTestSetup, LiquidityFuzzers { donateRouter.donate(key, feeRevenue0, feeRevenue1, ZERO_BYTES); // transfer to alice - lpm.transferFrom(address(this), alice, tokenId); + IERC721(address(lpm)).transferFrom(address(this), alice, tokenId); // alice can collect the fees uint256 balance0BeforeAlice = currency0.balanceOf(alice); @@ -806,7 +806,7 @@ contract PositionManagerTest is Test, PosmTestSetup, LiquidityFuzzers { mint(config, liquidity, ActionConstants.MSG_SENDER, ZERO_BYTES); // transfer to alice - lpm.transferFrom(address(this), alice, tokenId); + IERC721(address(lpm)).transferFrom(address(this), alice, tokenId); // alice increases liquidity and is the payer uint256 balance0BeforeAlice = currency0.balanceOf(alice); @@ -846,7 +846,7 @@ contract PositionManagerTest is Test, PosmTestSetup, LiquidityFuzzers { donateRouter.donate(key, feeRevenue0, feeRevenue1, ZERO_BYTES); // transfer to alice - lpm.transferFrom(address(this), alice, tokenId); + IERC721(address(lpm)).transferFrom(address(this), alice, tokenId); { // alice decreases liquidity and is the recipient @@ -980,7 +980,7 @@ contract PositionManagerTest is Test, PosmTestSetup, LiquidityFuzzers { assertEq( currency1.balanceOfSelf(), balanceBefore1 - uint256(-int256(deltaDecrease.amount1() + deltaMint.amount1())) ); - assertEq(lpm.ownerOf(tokenIdMint), address(this)); + assertEq(IERC721(address(lpm)).ownerOf(tokenIdMint), address(this)); assertLt(currency1.balanceOfSelf(), balanceBefore1); // currency1 was owed assertLt(uint256(int256(deltaDecrease.amount1())), uint256(int256(-deltaMint.amount1()))); // amount1 in the second position was greater than amount1 in the first position } diff --git a/test/shared/Deploy.sol b/test/shared/Deploy.sol new file mode 100644 index 000000000..f85cd364d --- /dev/null +++ b/test/shared/Deploy.sol @@ -0,0 +1,55 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.26; + +import {Vm} from "forge-std/Vm.sol"; +import {IPositionDescriptor} from "../../src/interfaces/IPositionDescriptor.sol"; +import {IPositionManager} from "../../src/interfaces/IPositionManager.sol"; +import {StateView} from "../../src/lens/StateView.sol"; +import {IV4Quoter} from "../../src/interfaces/IV4Quoter.sol"; + +library Deploy { + Vm internal constant vm = Vm(address(uint160(uint256(keccak256("hevm cheat code"))))); + + function positionManager( + address poolManager, + address permit2, + uint256 unsubscribeGasLimit, + address positionDescriptor_, + address wrappedNative, + bytes memory salt + ) internal returns (IPositionManager manager) { + bytes memory args = abi.encode(poolManager, permit2, unsubscribeGasLimit, positionDescriptor_, wrappedNative); + bytes memory initcode = abi.encodePacked(vm.getCode("PositionManager.sol:PositionManager"), args); + assembly { + manager := create2(0, add(initcode, 0x20), mload(initcode), salt) + } + } + + // no interface available, wrap in contract, this results in both versions being compiled, that's why we are importing the default version explicitly from the json file + function stateView(address poolManager) internal returns (StateView stateView_) { + bytes memory args = abi.encode(poolManager); + bytes memory initcode = abi.encodePacked(vm.getCode("foundry-out/StateView.sol/StateView.default.json"), args); + assembly { + stateView_ := create(0, add(initcode, 0x20), mload(initcode)) + } + } + + function v4Quoter(address poolManager) internal returns (IV4Quoter quoter) { + bytes memory args = abi.encode(poolManager); + bytes memory initcode = abi.encodePacked(vm.getCode("V4Quoter.sol:V4Quoter"), args); + assembly { + quoter := create(0, add(initcode, 0x20), mload(initcode)) + } + } + + function positionDescriptor(address poolManager, address wrappedNative, string memory nativeCurrencyLabel) + internal + returns (IPositionDescriptor descriptor) + { + bytes memory args = abi.encode(poolManager, wrappedNative, nativeCurrencyLabel); + bytes memory initcode = abi.encodePacked(vm.getCode("PositionDescriptor.sol:PositionDescriptor"), args); + assembly { + descriptor := create(0, add(initcode, 0x20), mload(initcode)) + } + } +} diff --git a/test/shared/FeeMath.sol b/test/shared/FeeMath.sol index 72ad5659a..cc97afb65 100644 --- a/test/shared/FeeMath.sol +++ b/test/shared/FeeMath.sol @@ -12,7 +12,6 @@ import {PoolId, PoolIdLibrary} from "@uniswap/v4-core/src/types/PoolId.sol"; import {PoolKey} from "@uniswap/v4-core/src/types/PoolKey.sol"; import {IPositionManager} from "../../src/interfaces/IPositionManager.sol"; -import {PositionManager} from "../../src/PositionManager.sol"; import {PositionConfig} from "../shared/PositionConfig.sol"; library FeeMath { diff --git a/test/shared/LiquidityOperations.sol b/test/shared/LiquidityOperations.sol index 80d2d81e7..9c65223ce 100644 --- a/test/shared/LiquidityOperations.sol +++ b/test/shared/LiquidityOperations.sol @@ -9,7 +9,8 @@ import {TickMath} from "@uniswap/v4-core/src/libraries/TickMath.sol"; import {LiquidityAmounts} from "@uniswap/v4-core/test/utils/LiquidityAmounts.sol"; import {SafeCast} from "@uniswap/v4-core/src/libraries/SafeCast.sol"; -import {PositionManager, Actions} from "../../src/PositionManager.sol"; +import {IPositionManager} from "../../src/interfaces/IPositionManager.sol"; +import {Actions} from "../../src/libraries/Actions.sol"; import {PositionConfig} from "./PositionConfig.sol"; import {Planner, Plan} from "../shared/Planner.sol"; import {HookSavesDelta} from "./HookSavesDelta.sol"; @@ -18,7 +19,7 @@ abstract contract LiquidityOperations is CommonBase { using Planner for Plan; using SafeCast for *; - PositionManager lpm; + IPositionManager lpm; uint256 _deadline = block.timestamp + 1; diff --git a/test/shared/PosmTestSetup.sol b/test/shared/PosmTestSetup.sol index bce86b97b..4c934c9d2 100644 --- a/test/shared/PosmTestSetup.sol +++ b/test/shared/PosmTestSetup.sol @@ -8,14 +8,13 @@ import {IPoolManager} from "@uniswap/v4-core/src/interfaces/IPoolManager.sol"; import {Hooks} from "@uniswap/v4-core/src/libraries/Hooks.sol"; import {PoolKey} from "@uniswap/v4-core/src/types/PoolKey.sol"; import {Deployers} from "@uniswap/v4-core/test/utils/Deployers.sol"; -import {PositionManager} from "../../src/PositionManager.sol"; import {IERC20} from "forge-std/interfaces/IERC20.sol"; import {LiquidityOperations} from "./LiquidityOperations.sol"; import {IAllowanceTransfer} from "permit2/src/interfaces/IAllowanceTransfer.sol"; import {DeployPermit2} from "permit2/test/utils/DeployPermit2.sol"; import {HookSavesDelta} from "./HookSavesDelta.sol"; import {HookModifyLiquidities} from "./HookModifyLiquidities.sol"; -import {PositionDescriptor} from "../../src/PositionDescriptor.sol"; +import {Deploy, IPositionDescriptor} from "./Deploy.sol"; import {ERC721PermitHash} from "../../src/libraries/ERC721PermitHash.sol"; import {IWETH9} from "../../src/interfaces/external/IWETH9.sol"; import {WETH} from "solmate/src/tokens/WETH.sol"; @@ -29,7 +28,7 @@ contract PosmTestSetup is Test, Deployers, DeployPermit2, LiquidityOperations { uint256 constant STARTING_USER_BALANCE = 10_000_000 ether; IAllowanceTransfer permit2; - PositionDescriptor public positionDescriptor; + IPositionDescriptor public positionDescriptor; HookSavesDelta hook; address hookAddr = address(uint160(Hooks.AFTER_ADD_LIQUIDITY_FLAG | Hooks.AFTER_REMOVE_LIQUIDITY_FLAG)); IWETH9 public _WETH9 = IWETH9(address(new WETH())); @@ -68,8 +67,11 @@ contract PosmTestSetup is Test, Deployers, DeployPermit2, LiquidityOperations { function deployPosm(IPoolManager poolManager) internal { // We use deployPermit2() to prevent having to use via-ir in this repository. permit2 = IAllowanceTransfer(deployPermit2()); - positionDescriptor = new PositionDescriptor(poolManager, 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2, "ETH"); - lpm = new PositionManager(poolManager, permit2, 100_000, positionDescriptor, _WETH9); + positionDescriptor = + Deploy.positionDescriptor(address(poolManager), 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2, "ETH"); + lpm = Deploy.positionManager( + address(poolManager), address(permit2), 100_000, address(positionDescriptor), address(_WETH9), hex"03" + ); } function seedBalance(address to) internal { diff --git a/test/shared/RoutingTestHelpers.sol b/test/shared/RoutingTestHelpers.sol index 67b8f6011..b29972b9c 100644 --- a/test/shared/RoutingTestHelpers.sol +++ b/test/shared/RoutingTestHelpers.sol @@ -14,7 +14,6 @@ import {Currency, CurrencyLibrary} from "@uniswap/v4-core/src/types/Currency.sol import {IPoolManager} from "@uniswap/v4-core/src/interfaces/IPoolManager.sol"; import {PoolKey} from "@uniswap/v4-core/src/types/PoolKey.sol"; import {Deployers} from "@uniswap/v4-core/test/utils/Deployers.sol"; -import {PositionManager} from "../../src/PositionManager.sol"; import {IERC20} from "forge-std/interfaces/IERC20.sol"; import {LiquidityOperations} from "./LiquidityOperations.sol"; import {IV4Router} from "../../src/interfaces/IV4Router.sol"; From e67c0e66fde4cb8077477f3687c037fa8249f143 Mon Sep 17 00:00:00 2001 From: gretzke Date: Tue, 26 Nov 2024 22:04:52 +0100 Subject: [PATCH 02/20] optimize compiler runs --- foundry.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/foundry.toml b/foundry.toml index 78967d2ce..993837a64 100644 --- a/foundry.toml +++ b/foundry.toml @@ -1,7 +1,7 @@ [profile.default] out = 'foundry-out' solc_version = '0.8.26' -optimizer_runs = 44444444 +optimizer_runs = 30000 via_ir = true ffi = true fs_permissions = [{ access = "read-write", path = ".forge-snapshots/" }, { access = "read", path = "foundry-out/" }] From 2a4d7faa0f51edbead71b3deedae09577d92a63b Mon Sep 17 00:00:00 2001 From: Daniel Gretzke Date: Tue, 26 Nov 2024 22:13:23 +0100 Subject: [PATCH 03/20] Update src/interfaces/IPoolInitializer.sol Co-authored-by: Louis Brown <48462338+louisbrown0212@users.noreply.github.com> --- src/interfaces/IPoolInitializer.sol | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/interfaces/IPoolInitializer.sol b/src/interfaces/IPoolInitializer.sol index ee3e6163d..3a2115eed 100644 --- a/src/interfaces/IPoolInitializer.sol +++ b/src/interfaces/IPoolInitializer.sol @@ -6,8 +6,8 @@ import {PoolKey} from "@uniswap/v4-core/src/types/PoolKey.sol"; interface IPoolInitializer { /// @notice Initialize a Uniswap v4 Pool /// @dev If the pool is already initialized, this function will not revert and just return type(int24).max - /// @param key the PoolKey of the pool to initialize - /// @param sqrtPriceX96 the initial sqrtPriceX96 of the pool + /// @param key The PoolKey of the pool to initialize + /// @param sqrtPriceX96 The initial sqrtPriceX96 of the pool /// @return tick The current tick of the pool function initializePool(PoolKey calldata key, uint160 sqrtPriceX96) external payable returns (int24); } From 272d07811b7832f6ae22411662bd4ad382841080 Mon Sep 17 00:00:00 2001 From: gretzke Date: Tue, 26 Nov 2024 22:14:56 +0100 Subject: [PATCH 04/20] remove override --- src/PositionDescriptor.sol | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/PositionDescriptor.sol b/src/PositionDescriptor.sol index 5184d07ae..50b22c0e6 100644 --- a/src/PositionDescriptor.sol +++ b/src/PositionDescriptor.sol @@ -86,7 +86,7 @@ contract PositionDescriptor is IPositionDescriptor { } /// @inheritdoc IPositionDescriptor - function flipRatio(address currency0, address currency1) public view override returns (bool) { + function flipRatio(address currency0, address currency1) public view returns (bool) { return currencyRatioPriority(currency0) > currencyRatioPriority(currency1); } From d1d087f0794116a851d44a1b62f998c27cb39c8a Mon Sep 17 00:00:00 2001 From: gretzke Date: Tue, 26 Nov 2024 22:22:57 +0100 Subject: [PATCH 05/20] regenerate gas snapshots --- .../Payments_swap_settleFromCaller_takeAllToMsgSender.snap | 2 +- ...ayments_swap_settleFromCaller_takeAllToSpecifiedAddress.snap | 2 +- .../Payments_swap_settleWithBalance_takeAllToMsgSender.snap | 2 +- ...yments_swap_settleWithBalance_takeAllToSpecifiedAddress.snap | 2 +- .forge-snapshots/PositionManager_burn_empty.snap | 2 +- .forge-snapshots/PositionManager_burn_empty_native.snap | 2 +- .../PositionManager_burn_nonEmpty_native_withClose.snap | 2 +- .../PositionManager_burn_nonEmpty_native_withTakePair.snap | 2 +- .forge-snapshots/PositionManager_burn_nonEmpty_withClose.snap | 2 +- .../PositionManager_burn_nonEmpty_withTakePair.snap | 2 +- .forge-snapshots/PositionManager_collect_native.snap | 2 +- .forge-snapshots/PositionManager_collect_sameRange.snap | 2 +- .forge-snapshots/PositionManager_collect_withClose.snap | 2 +- .forge-snapshots/PositionManager_collect_withTakePair.snap | 2 +- .forge-snapshots/PositionManager_decreaseLiquidity_native.snap | 2 +- .../PositionManager_decreaseLiquidity_withClose.snap | 2 +- .../PositionManager_decreaseLiquidity_withTakePair.snap | 2 +- .forge-snapshots/PositionManager_decrease_burnEmpty.snap | 2 +- .forge-snapshots/PositionManager_decrease_burnEmpty_native.snap | 2 +- .../PositionManager_decrease_sameRange_allLiquidity.snap | 2 +- .forge-snapshots/PositionManager_decrease_take_take.snap | 2 +- .../PositionManager_increaseLiquidity_erc20_withClose.snap | 2 +- .../PositionManager_increaseLiquidity_erc20_withSettlePair.snap | 2 +- .forge-snapshots/PositionManager_increaseLiquidity_native.snap | 2 +- ...PositionManager_increase_autocompoundExactUnclaimedFees.snap | 2 +- .../PositionManager_increase_autocompoundExcessFeesCredit.snap | 2 +- .../PositionManager_increase_autocompound_clearExcess.snap | 2 +- .forge-snapshots/PositionManager_mint_native.snap | 2 +- .../PositionManager_mint_nativeWithSweep_withClose.snap | 2 +- .../PositionManager_mint_nativeWithSweep_withSettlePair.snap | 2 +- .forge-snapshots/PositionManager_mint_onSameTickLower.snap | 2 +- .forge-snapshots/PositionManager_mint_onSameTickUpper.snap | 2 +- .forge-snapshots/PositionManager_mint_sameRange.snap | 2 +- .../PositionManager_mint_settleWithBalance_sweep.snap | 2 +- .../PositionManager_mint_warmedPool_differentRange.snap | 2 +- .forge-snapshots/PositionManager_mint_withClose.snap | 2 +- .forge-snapshots/PositionManager_mint_withSettlePair.snap | 2 +- .forge-snapshots/PositionManager_multicall_initialize_mint.snap | 2 +- .forge-snapshots/PositionManager_permit.snap | 2 +- .forge-snapshots/PositionManager_permit_secondPosition.snap | 2 +- .forge-snapshots/PositionManager_permit_twice.snap | 2 +- .forge-snapshots/PositionManager_subscribe.snap | 2 +- .forge-snapshots/PositionManager_unsubscribe.snap | 2 +- .../Quoter_exactInputSingle_oneForZero_multiplePositions.snap | 2 +- .../Quoter_exactInputSingle_zeroForOne_multiplePositions.snap | 2 +- .forge-snapshots/Quoter_exactOutputSingle_oneForZero.snap | 2 +- .forge-snapshots/Quoter_exactOutputSingle_zeroForOne.snap | 2 +- .forge-snapshots/Quoter_quoteExactInput_oneHop_1TickLoaded.snap | 2 +- .../Quoter_quoteExactInput_oneHop_initializedAfter.snap | 2 +- .../Quoter_quoteExactInput_oneHop_startingInitialized.snap | 2 +- .forge-snapshots/Quoter_quoteExactInput_twoHops.snap | 2 +- .../Quoter_quoteExactOutput_oneHop_1TickLoaded.snap | 2 +- .../Quoter_quoteExactOutput_oneHop_2TicksLoaded.snap | 2 +- .../Quoter_quoteExactOutput_oneHop_initializedAfter.snap | 2 +- .../Quoter_quoteExactOutput_oneHop_startingInitialized.snap | 2 +- .forge-snapshots/Quoter_quoteExactOutput_twoHops.snap | 2 +- .forge-snapshots/V4Router_ExactIn1Hop_nativeIn.snap | 2 +- .forge-snapshots/V4Router_ExactIn1Hop_nativeOut.snap | 2 +- .forge-snapshots/V4Router_ExactIn1Hop_oneForZero.snap | 2 +- .forge-snapshots/V4Router_ExactIn1Hop_zeroForOne.snap | 2 +- .forge-snapshots/V4Router_ExactIn2Hops.snap | 2 +- .forge-snapshots/V4Router_ExactIn2Hops_nativeIn.snap | 2 +- .forge-snapshots/V4Router_ExactIn3Hops.snap | 2 +- .forge-snapshots/V4Router_ExactIn3Hops_nativeIn.snap | 2 +- .forge-snapshots/V4Router_ExactInputSingle.snap | 2 +- .forge-snapshots/V4Router_ExactInputSingle_nativeIn.snap | 2 +- .forge-snapshots/V4Router_ExactInputSingle_nativeOut.snap | 2 +- .forge-snapshots/V4Router_ExactOut1Hop_nativeIn_sweepETH.snap | 2 +- .forge-snapshots/V4Router_ExactOut1Hop_nativeOut.snap | 2 +- .forge-snapshots/V4Router_ExactOut1Hop_oneForZero.snap | 2 +- .forge-snapshots/V4Router_ExactOut1Hop_zeroForOne.snap | 2 +- .forge-snapshots/V4Router_ExactOut2Hops.snap | 2 +- .forge-snapshots/V4Router_ExactOut2Hops_nativeIn.snap | 2 +- .forge-snapshots/V4Router_ExactOut3Hops.snap | 2 +- .forge-snapshots/V4Router_ExactOut3Hops_nativeIn.snap | 2 +- .forge-snapshots/V4Router_ExactOut3Hops_nativeOut.snap | 2 +- .forge-snapshots/V4Router_ExactOutputSingle.snap | 2 +- .../V4Router_ExactOutputSingle_nativeIn_sweepETH.snap | 2 +- .forge-snapshots/V4Router_ExactOutputSingle_nativeOut.snap | 2 +- .forge-snapshots/positionDescriptor bytecode size.snap | 2 +- .forge-snapshots/positionManager bytecode size.snap | 2 +- 81 files changed, 81 insertions(+), 81 deletions(-) diff --git a/.forge-snapshots/Payments_swap_settleFromCaller_takeAllToMsgSender.snap b/.forge-snapshots/Payments_swap_settleFromCaller_takeAllToMsgSender.snap index 94949b13c..646d167c3 100644 --- a/.forge-snapshots/Payments_swap_settleFromCaller_takeAllToMsgSender.snap +++ b/.forge-snapshots/Payments_swap_settleFromCaller_takeAllToMsgSender.snap @@ -1 +1 @@ -133006 \ No newline at end of file +133930 \ No newline at end of file diff --git a/.forge-snapshots/Payments_swap_settleFromCaller_takeAllToSpecifiedAddress.snap b/.forge-snapshots/Payments_swap_settleFromCaller_takeAllToSpecifiedAddress.snap index 75de88e95..805b98bbc 100644 --- a/.forge-snapshots/Payments_swap_settleFromCaller_takeAllToSpecifiedAddress.snap +++ b/.forge-snapshots/Payments_swap_settleFromCaller_takeAllToSpecifiedAddress.snap @@ -1 +1 @@ -134475 \ No newline at end of file +135399 \ No newline at end of file diff --git a/.forge-snapshots/Payments_swap_settleWithBalance_takeAllToMsgSender.snap b/.forge-snapshots/Payments_swap_settleWithBalance_takeAllToMsgSender.snap index e0dd700d5..b179f65d1 100644 --- a/.forge-snapshots/Payments_swap_settleWithBalance_takeAllToMsgSender.snap +++ b/.forge-snapshots/Payments_swap_settleWithBalance_takeAllToMsgSender.snap @@ -1 +1 @@ -126957 \ No newline at end of file +127881 \ No newline at end of file diff --git a/.forge-snapshots/Payments_swap_settleWithBalance_takeAllToSpecifiedAddress.snap b/.forge-snapshots/Payments_swap_settleWithBalance_takeAllToSpecifiedAddress.snap index 9390c7055..2edf2f600 100644 --- a/.forge-snapshots/Payments_swap_settleWithBalance_takeAllToSpecifiedAddress.snap +++ b/.forge-snapshots/Payments_swap_settleWithBalance_takeAllToSpecifiedAddress.snap @@ -1 +1 @@ -127095 \ No newline at end of file +128019 \ No newline at end of file diff --git a/.forge-snapshots/PositionManager_burn_empty.snap b/.forge-snapshots/PositionManager_burn_empty.snap index a807a6daa..9a3eec280 100644 --- a/.forge-snapshots/PositionManager_burn_empty.snap +++ b/.forge-snapshots/PositionManager_burn_empty.snap @@ -1 +1 @@ -50953 \ No newline at end of file +51102 \ No newline at end of file diff --git a/.forge-snapshots/PositionManager_burn_empty_native.snap b/.forge-snapshots/PositionManager_burn_empty_native.snap index a807a6daa..9a3eec280 100644 --- a/.forge-snapshots/PositionManager_burn_empty_native.snap +++ b/.forge-snapshots/PositionManager_burn_empty_native.snap @@ -1 +1 @@ -50953 \ No newline at end of file +51102 \ No newline at end of file diff --git a/.forge-snapshots/PositionManager_burn_nonEmpty_native_withClose.snap b/.forge-snapshots/PositionManager_burn_nonEmpty_native_withClose.snap index 5d5a90de3..6c5691354 100644 --- a/.forge-snapshots/PositionManager_burn_nonEmpty_native_withClose.snap +++ b/.forge-snapshots/PositionManager_burn_nonEmpty_native_withClose.snap @@ -1 +1 @@ -127469 \ No newline at end of file +128040 \ No newline at end of file diff --git a/.forge-snapshots/PositionManager_burn_nonEmpty_native_withTakePair.snap b/.forge-snapshots/PositionManager_burn_nonEmpty_native_withTakePair.snap index 79a47be6c..ae8deb172 100644 --- a/.forge-snapshots/PositionManager_burn_nonEmpty_native_withTakePair.snap +++ b/.forge-snapshots/PositionManager_burn_nonEmpty_native_withTakePair.snap @@ -1 +1 @@ -126902 \ No newline at end of file +127483 \ No newline at end of file diff --git a/.forge-snapshots/PositionManager_burn_nonEmpty_withClose.snap b/.forge-snapshots/PositionManager_burn_nonEmpty_withClose.snap index f50d601b5..5080cb8cb 100644 --- a/.forge-snapshots/PositionManager_burn_nonEmpty_withClose.snap +++ b/.forge-snapshots/PositionManager_burn_nonEmpty_withClose.snap @@ -1 +1 @@ -134375 \ No newline at end of file +134956 \ No newline at end of file diff --git a/.forge-snapshots/PositionManager_burn_nonEmpty_withTakePair.snap b/.forge-snapshots/PositionManager_burn_nonEmpty_withTakePair.snap index 764b6c2bb..988f465e4 100644 --- a/.forge-snapshots/PositionManager_burn_nonEmpty_withTakePair.snap +++ b/.forge-snapshots/PositionManager_burn_nonEmpty_withTakePair.snap @@ -1 +1 @@ -133808 \ No newline at end of file +134398 \ No newline at end of file diff --git a/.forge-snapshots/PositionManager_collect_native.snap b/.forge-snapshots/PositionManager_collect_native.snap index 4ed0e2d12..462e130b2 100644 --- a/.forge-snapshots/PositionManager_collect_native.snap +++ b/.forge-snapshots/PositionManager_collect_native.snap @@ -1 +1 @@ -147532 \ No newline at end of file +148090 \ No newline at end of file diff --git a/.forge-snapshots/PositionManager_collect_sameRange.snap b/.forge-snapshots/PositionManager_collect_sameRange.snap index 3887727c3..846e8703d 100644 --- a/.forge-snapshots/PositionManager_collect_sameRange.snap +++ b/.forge-snapshots/PositionManager_collect_sameRange.snap @@ -1 +1 @@ -156164 \ No newline at end of file +156734 \ No newline at end of file diff --git a/.forge-snapshots/PositionManager_collect_withClose.snap b/.forge-snapshots/PositionManager_collect_withClose.snap index 3887727c3..846e8703d 100644 --- a/.forge-snapshots/PositionManager_collect_withClose.snap +++ b/.forge-snapshots/PositionManager_collect_withClose.snap @@ -1 +1 @@ -156164 \ No newline at end of file +156734 \ No newline at end of file diff --git a/.forge-snapshots/PositionManager_collect_withTakePair.snap b/.forge-snapshots/PositionManager_collect_withTakePair.snap index 878f2f34a..0bc68a9bc 100644 --- a/.forge-snapshots/PositionManager_collect_withTakePair.snap +++ b/.forge-snapshots/PositionManager_collect_withTakePair.snap @@ -1 +1 @@ -155467 \ No newline at end of file +156049 \ No newline at end of file diff --git a/.forge-snapshots/PositionManager_decreaseLiquidity_native.snap b/.forge-snapshots/PositionManager_decreaseLiquidity_native.snap index d930c56e6..007b50643 100644 --- a/.forge-snapshots/PositionManager_decreaseLiquidity_native.snap +++ b/.forge-snapshots/PositionManager_decreaseLiquidity_native.snap @@ -1 +1 @@ -113521 \ No newline at end of file +114044 \ No newline at end of file diff --git a/.forge-snapshots/PositionManager_decreaseLiquidity_withClose.snap b/.forge-snapshots/PositionManager_decreaseLiquidity_withClose.snap index 34ab0546f..72a09ae97 100644 --- a/.forge-snapshots/PositionManager_decreaseLiquidity_withClose.snap +++ b/.forge-snapshots/PositionManager_decreaseLiquidity_withClose.snap @@ -1 +1 @@ -121733 \ No newline at end of file +122399 \ No newline at end of file diff --git a/.forge-snapshots/PositionManager_decreaseLiquidity_withTakePair.snap b/.forge-snapshots/PositionManager_decreaseLiquidity_withTakePair.snap index d754277bf..b69f5e9f7 100644 --- a/.forge-snapshots/PositionManager_decreaseLiquidity_withTakePair.snap +++ b/.forge-snapshots/PositionManager_decreaseLiquidity_withTakePair.snap @@ -1 +1 @@ -121036 \ No newline at end of file +121714 \ No newline at end of file diff --git a/.forge-snapshots/PositionManager_decrease_burnEmpty.snap b/.forge-snapshots/PositionManager_decrease_burnEmpty.snap index 6dc82b4e9..621e8754a 100644 --- a/.forge-snapshots/PositionManager_decrease_burnEmpty.snap +++ b/.forge-snapshots/PositionManager_decrease_burnEmpty.snap @@ -1 +1 @@ -137225 \ No newline at end of file +137873 \ No newline at end of file diff --git a/.forge-snapshots/PositionManager_decrease_burnEmpty_native.snap b/.forge-snapshots/PositionManager_decrease_burnEmpty_native.snap index cc1c052a3..8c826d744 100644 --- a/.forge-snapshots/PositionManager_decrease_burnEmpty_native.snap +++ b/.forge-snapshots/PositionManager_decrease_burnEmpty_native.snap @@ -1 +1 @@ -130320 \ No newline at end of file +130958 \ No newline at end of file diff --git a/.forge-snapshots/PositionManager_decrease_sameRange_allLiquidity.snap b/.forge-snapshots/PositionManager_decrease_sameRange_allLiquidity.snap index 1dcfbe88d..08fc8edf1 100644 --- a/.forge-snapshots/PositionManager_decrease_sameRange_allLiquidity.snap +++ b/.forge-snapshots/PositionManager_decrease_sameRange_allLiquidity.snap @@ -1 +1 @@ -134449 \ No newline at end of file +135115 \ No newline at end of file diff --git a/.forge-snapshots/PositionManager_decrease_take_take.snap b/.forge-snapshots/PositionManager_decrease_take_take.snap index 7dac0ddfe..a950af202 100644 --- a/.forge-snapshots/PositionManager_decrease_take_take.snap +++ b/.forge-snapshots/PositionManager_decrease_take_take.snap @@ -1 +1 @@ -122266 \ No newline at end of file +122956 \ No newline at end of file diff --git a/.forge-snapshots/PositionManager_increaseLiquidity_erc20_withClose.snap b/.forge-snapshots/PositionManager_increaseLiquidity_erc20_withClose.snap index 5be4cdb84..c1bfc8497 100644 --- a/.forge-snapshots/PositionManager_increaseLiquidity_erc20_withClose.snap +++ b/.forge-snapshots/PositionManager_increaseLiquidity_erc20_withClose.snap @@ -1 +1 @@ -160356 \ No newline at end of file +161238 \ No newline at end of file diff --git a/.forge-snapshots/PositionManager_increaseLiquidity_erc20_withSettlePair.snap b/.forge-snapshots/PositionManager_increaseLiquidity_erc20_withSettlePair.snap index b7c87ac4d..9a8626bd1 100644 --- a/.forge-snapshots/PositionManager_increaseLiquidity_erc20_withSettlePair.snap +++ b/.forge-snapshots/PositionManager_increaseLiquidity_erc20_withSettlePair.snap @@ -1 +1 @@ -159267 \ No newline at end of file +160149 \ No newline at end of file diff --git a/.forge-snapshots/PositionManager_increaseLiquidity_native.snap b/.forge-snapshots/PositionManager_increaseLiquidity_native.snap index 0cc7dea3b..27adf03c8 100644 --- a/.forge-snapshots/PositionManager_increaseLiquidity_native.snap +++ b/.forge-snapshots/PositionManager_increaseLiquidity_native.snap @@ -1 +1 @@ -143272 \ No newline at end of file +144034 \ No newline at end of file diff --git a/.forge-snapshots/PositionManager_increase_autocompoundExactUnclaimedFees.snap b/.forge-snapshots/PositionManager_increase_autocompoundExactUnclaimedFees.snap index f0d93aa69..560ba5fe0 100644 --- a/.forge-snapshots/PositionManager_increase_autocompoundExactUnclaimedFees.snap +++ b/.forge-snapshots/PositionManager_increase_autocompoundExactUnclaimedFees.snap @@ -1 +1 @@ -138103 \ No newline at end of file +138481 \ No newline at end of file diff --git a/.forge-snapshots/PositionManager_increase_autocompoundExcessFeesCredit.snap b/.forge-snapshots/PositionManager_increase_autocompoundExcessFeesCredit.snap index 85ababc91..52d7b3932 100644 --- a/.forge-snapshots/PositionManager_increase_autocompoundExcessFeesCredit.snap +++ b/.forge-snapshots/PositionManager_increase_autocompoundExcessFeesCredit.snap @@ -1 +1 @@ -179393 \ No newline at end of file +180059 \ No newline at end of file diff --git a/.forge-snapshots/PositionManager_increase_autocompound_clearExcess.snap b/.forge-snapshots/PositionManager_increase_autocompound_clearExcess.snap index 4f993caf9..db428c346 100644 --- a/.forge-snapshots/PositionManager_increase_autocompound_clearExcess.snap +++ b/.forge-snapshots/PositionManager_increase_autocompound_clearExcess.snap @@ -1 +1 @@ -149311 \ No newline at end of file +149905 \ No newline at end of file diff --git a/.forge-snapshots/PositionManager_mint_native.snap b/.forge-snapshots/PositionManager_mint_native.snap index aa4ab24bb..5e111f3da 100644 --- a/.forge-snapshots/PositionManager_mint_native.snap +++ b/.forge-snapshots/PositionManager_mint_native.snap @@ -1 +1 @@ -367148 \ No newline at end of file +368030 \ No newline at end of file diff --git a/.forge-snapshots/PositionManager_mint_nativeWithSweep_withClose.snap b/.forge-snapshots/PositionManager_mint_nativeWithSweep_withClose.snap index aa9ec51a2..ebf4737e3 100644 --- a/.forge-snapshots/PositionManager_mint_nativeWithSweep_withClose.snap +++ b/.forge-snapshots/PositionManager_mint_nativeWithSweep_withClose.snap @@ -1 +1 @@ -375715 \ No newline at end of file +376633 \ No newline at end of file diff --git a/.forge-snapshots/PositionManager_mint_nativeWithSweep_withSettlePair.snap b/.forge-snapshots/PositionManager_mint_nativeWithSweep_withSettlePair.snap index ba5376799..432f0fa5d 100644 --- a/.forge-snapshots/PositionManager_mint_nativeWithSweep_withSettlePair.snap +++ b/.forge-snapshots/PositionManager_mint_nativeWithSweep_withSettlePair.snap @@ -1 +1 @@ -374910 \ No newline at end of file +375828 \ No newline at end of file diff --git a/.forge-snapshots/PositionManager_mint_onSameTickLower.snap b/.forge-snapshots/PositionManager_mint_onSameTickLower.snap index a7c97bf80..c252cf5f9 100644 --- a/.forge-snapshots/PositionManager_mint_onSameTickLower.snap +++ b/.forge-snapshots/PositionManager_mint_onSameTickLower.snap @@ -1 +1 @@ -318932 \ No newline at end of file +319862 \ No newline at end of file diff --git a/.forge-snapshots/PositionManager_mint_onSameTickUpper.snap b/.forge-snapshots/PositionManager_mint_onSameTickUpper.snap index 458417a10..d2aeb72e3 100644 --- a/.forge-snapshots/PositionManager_mint_onSameTickUpper.snap +++ b/.forge-snapshots/PositionManager_mint_onSameTickUpper.snap @@ -1 +1 @@ -319574 \ No newline at end of file +320504 \ No newline at end of file diff --git a/.forge-snapshots/PositionManager_mint_sameRange.snap b/.forge-snapshots/PositionManager_mint_sameRange.snap index b6526289a..709a34c4a 100644 --- a/.forge-snapshots/PositionManager_mint_sameRange.snap +++ b/.forge-snapshots/PositionManager_mint_sameRange.snap @@ -1 +1 @@ -245156 \ No newline at end of file +246086 \ No newline at end of file diff --git a/.forge-snapshots/PositionManager_mint_settleWithBalance_sweep.snap b/.forge-snapshots/PositionManager_mint_settleWithBalance_sweep.snap index 3e6618aea..4808ff68c 100644 --- a/.forge-snapshots/PositionManager_mint_settleWithBalance_sweep.snap +++ b/.forge-snapshots/PositionManager_mint_settleWithBalance_sweep.snap @@ -1 +1 @@ -420178 \ No newline at end of file +421324 \ No newline at end of file diff --git a/.forge-snapshots/PositionManager_mint_warmedPool_differentRange.snap b/.forge-snapshots/PositionManager_mint_warmedPool_differentRange.snap index 94a4af8c3..9c4d68b65 100644 --- a/.forge-snapshots/PositionManager_mint_warmedPool_differentRange.snap +++ b/.forge-snapshots/PositionManager_mint_warmedPool_differentRange.snap @@ -1 +1 @@ -324950 \ No newline at end of file +325880 \ No newline at end of file diff --git a/.forge-snapshots/PositionManager_mint_withClose.snap b/.forge-snapshots/PositionManager_mint_withClose.snap index 57812b4a9..00b56a2a3 100644 --- a/.forge-snapshots/PositionManager_mint_withClose.snap +++ b/.forge-snapshots/PositionManager_mint_withClose.snap @@ -1 +1 @@ -421472 \ No newline at end of file +422474 \ No newline at end of file diff --git a/.forge-snapshots/PositionManager_mint_withSettlePair.snap b/.forge-snapshots/PositionManager_mint_withSettlePair.snap index 00f6a1988..8d42bdac1 100644 --- a/.forge-snapshots/PositionManager_mint_withSettlePair.snap +++ b/.forge-snapshots/PositionManager_mint_withSettlePair.snap @@ -1 +1 @@ -420501 \ No newline at end of file +421503 \ No newline at end of file diff --git a/.forge-snapshots/PositionManager_multicall_initialize_mint.snap b/.forge-snapshots/PositionManager_multicall_initialize_mint.snap index a78f3b0ca..b8f3ed012 100644 --- a/.forge-snapshots/PositionManager_multicall_initialize_mint.snap +++ b/.forge-snapshots/PositionManager_multicall_initialize_mint.snap @@ -1 +1 @@ -457709 \ No newline at end of file +459041 \ No newline at end of file diff --git a/.forge-snapshots/PositionManager_permit.snap b/.forge-snapshots/PositionManager_permit.snap index 227e327e4..5c2ef89a9 100644 --- a/.forge-snapshots/PositionManager_permit.snap +++ b/.forge-snapshots/PositionManager_permit.snap @@ -1 +1 @@ -79076 \ No newline at end of file +79175 \ No newline at end of file diff --git a/.forge-snapshots/PositionManager_permit_secondPosition.snap b/.forge-snapshots/PositionManager_permit_secondPosition.snap index 31ad61876..b1dc5c691 100644 --- a/.forge-snapshots/PositionManager_permit_secondPosition.snap +++ b/.forge-snapshots/PositionManager_permit_secondPosition.snap @@ -1 +1 @@ -61976 \ No newline at end of file +62075 \ No newline at end of file diff --git a/.forge-snapshots/PositionManager_permit_twice.snap b/.forge-snapshots/PositionManager_permit_twice.snap index 68eb0f5de..54b7cc91a 100644 --- a/.forge-snapshots/PositionManager_permit_twice.snap +++ b/.forge-snapshots/PositionManager_permit_twice.snap @@ -1 +1 @@ -44864 \ No newline at end of file +44975 \ No newline at end of file diff --git a/.forge-snapshots/PositionManager_subscribe.snap b/.forge-snapshots/PositionManager_subscribe.snap index 36cff1d2c..73693d017 100644 --- a/.forge-snapshots/PositionManager_subscribe.snap +++ b/.forge-snapshots/PositionManager_subscribe.snap @@ -1 +1 @@ -87857 \ No newline at end of file +87968 \ No newline at end of file diff --git a/.forge-snapshots/PositionManager_unsubscribe.snap b/.forge-snapshots/PositionManager_unsubscribe.snap index aaec480e7..33a05c11a 100644 --- a/.forge-snapshots/PositionManager_unsubscribe.snap +++ b/.forge-snapshots/PositionManager_unsubscribe.snap @@ -1 +1 @@ -62622 \ No newline at end of file +62697 \ No newline at end of file diff --git a/.forge-snapshots/Quoter_exactInputSingle_oneForZero_multiplePositions.snap b/.forge-snapshots/Quoter_exactInputSingle_oneForZero_multiplePositions.snap index ddd017c32..fc71cc7d2 100644 --- a/.forge-snapshots/Quoter_exactInputSingle_oneForZero_multiplePositions.snap +++ b/.forge-snapshots/Quoter_exactInputSingle_oneForZero_multiplePositions.snap @@ -1 +1 @@ -145902 \ No newline at end of file +146790 \ No newline at end of file diff --git a/.forge-snapshots/Quoter_exactInputSingle_zeroForOne_multiplePositions.snap b/.forge-snapshots/Quoter_exactInputSingle_zeroForOne_multiplePositions.snap index 6bfe32457..9f344ee42 100644 --- a/.forge-snapshots/Quoter_exactInputSingle_zeroForOne_multiplePositions.snap +++ b/.forge-snapshots/Quoter_exactInputSingle_zeroForOne_multiplePositions.snap @@ -1 +1 @@ -152117 \ No newline at end of file +153173 \ No newline at end of file diff --git a/.forge-snapshots/Quoter_exactOutputSingle_oneForZero.snap b/.forge-snapshots/Quoter_exactOutputSingle_oneForZero.snap index 0fddaa34a..33b96a518 100644 --- a/.forge-snapshots/Quoter_exactOutputSingle_oneForZero.snap +++ b/.forge-snapshots/Quoter_exactOutputSingle_oneForZero.snap @@ -1 +1 @@ -79267 \ No newline at end of file +79795 \ No newline at end of file diff --git a/.forge-snapshots/Quoter_exactOutputSingle_zeroForOne.snap b/.forge-snapshots/Quoter_exactOutputSingle_zeroForOne.snap index 80c70ad9b..eff8b5788 100644 --- a/.forge-snapshots/Quoter_exactOutputSingle_zeroForOne.snap +++ b/.forge-snapshots/Quoter_exactOutputSingle_zeroForOne.snap @@ -1 +1 @@ -84512 \ No newline at end of file +85220 \ No newline at end of file diff --git a/.forge-snapshots/Quoter_quoteExactInput_oneHop_1TickLoaded.snap b/.forge-snapshots/Quoter_quoteExactInput_oneHop_1TickLoaded.snap index 535f80cb8..473cbcfb5 100644 --- a/.forge-snapshots/Quoter_quoteExactInput_oneHop_1TickLoaded.snap +++ b/.forge-snapshots/Quoter_quoteExactInput_oneHop_1TickLoaded.snap @@ -1 +1 @@ -122728 \ No newline at end of file +123604 \ No newline at end of file diff --git a/.forge-snapshots/Quoter_quoteExactInput_oneHop_initializedAfter.snap b/.forge-snapshots/Quoter_quoteExactInput_oneHop_initializedAfter.snap index 9e2f18c9f..fbabcd0c8 100644 --- a/.forge-snapshots/Quoter_quoteExactInput_oneHop_initializedAfter.snap +++ b/.forge-snapshots/Quoter_quoteExactInput_oneHop_initializedAfter.snap @@ -1 +1 @@ -147363 \ No newline at end of file +148251 \ No newline at end of file diff --git a/.forge-snapshots/Quoter_quoteExactInput_oneHop_startingInitialized.snap b/.forge-snapshots/Quoter_quoteExactInput_oneHop_startingInitialized.snap index 2b5d25c12..c99fa7ac8 100644 --- a/.forge-snapshots/Quoter_quoteExactInput_oneHop_startingInitialized.snap +++ b/.forge-snapshots/Quoter_quoteExactInput_oneHop_startingInitialized.snap @@ -1 +1 @@ -80638 \ No newline at end of file +81166 \ No newline at end of file diff --git a/.forge-snapshots/Quoter_quoteExactInput_twoHops.snap b/.forge-snapshots/Quoter_quoteExactInput_twoHops.snap index 4a002eafd..2c8b0ba6d 100644 --- a/.forge-snapshots/Quoter_quoteExactInput_twoHops.snap +++ b/.forge-snapshots/Quoter_quoteExactInput_twoHops.snap @@ -1 +1 @@ -204942 \ No newline at end of file +206526 \ No newline at end of file diff --git a/.forge-snapshots/Quoter_quoteExactOutput_oneHop_1TickLoaded.snap b/.forge-snapshots/Quoter_quoteExactOutput_oneHop_1TickLoaded.snap index 6d7d1854d..e3f370cb4 100644 --- a/.forge-snapshots/Quoter_quoteExactOutput_oneHop_1TickLoaded.snap +++ b/.forge-snapshots/Quoter_quoteExactOutput_oneHop_1TickLoaded.snap @@ -1 +1 @@ -122224 \ No newline at end of file +123112 \ No newline at end of file diff --git a/.forge-snapshots/Quoter_quoteExactOutput_oneHop_2TicksLoaded.snap b/.forge-snapshots/Quoter_quoteExactOutput_oneHop_2TicksLoaded.snap index 141d1a3ed..688bf821b 100644 --- a/.forge-snapshots/Quoter_quoteExactOutput_oneHop_2TicksLoaded.snap +++ b/.forge-snapshots/Quoter_quoteExactOutput_oneHop_2TicksLoaded.snap @@ -1 +1 @@ -152879 \ No newline at end of file +153947 \ No newline at end of file diff --git a/.forge-snapshots/Quoter_quoteExactOutput_oneHop_initializedAfter.snap b/.forge-snapshots/Quoter_quoteExactOutput_oneHop_initializedAfter.snap index ce1e06318..2d3a1e066 100644 --- a/.forge-snapshots/Quoter_quoteExactOutput_oneHop_initializedAfter.snap +++ b/.forge-snapshots/Quoter_quoteExactOutput_oneHop_initializedAfter.snap @@ -1 +1 @@ -122251 \ No newline at end of file +123139 \ No newline at end of file diff --git a/.forge-snapshots/Quoter_quoteExactOutput_oneHop_startingInitialized.snap b/.forge-snapshots/Quoter_quoteExactOutput_oneHop_startingInitialized.snap index 44946b692..7d711fb1d 100644 --- a/.forge-snapshots/Quoter_quoteExactOutput_oneHop_startingInitialized.snap +++ b/.forge-snapshots/Quoter_quoteExactOutput_oneHop_startingInitialized.snap @@ -1 +1 @@ -98545 \ No newline at end of file +99253 \ No newline at end of file diff --git a/.forge-snapshots/Quoter_quoteExactOutput_twoHops.snap b/.forge-snapshots/Quoter_quoteExactOutput_twoHops.snap index 15336cc2d..f15d14b41 100644 --- a/.forge-snapshots/Quoter_quoteExactOutput_twoHops.snap +++ b/.forge-snapshots/Quoter_quoteExactOutput_twoHops.snap @@ -1 +1 @@ -204670 \ No newline at end of file +206266 \ No newline at end of file diff --git a/.forge-snapshots/V4Router_ExactIn1Hop_nativeIn.snap b/.forge-snapshots/V4Router_ExactIn1Hop_nativeIn.snap index e188f56da..4472479bf 100644 --- a/.forge-snapshots/V4Router_ExactIn1Hop_nativeIn.snap +++ b/.forge-snapshots/V4Router_ExactIn1Hop_nativeIn.snap @@ -1 +1 @@ -121653 \ No newline at end of file +122493 \ No newline at end of file diff --git a/.forge-snapshots/V4Router_ExactIn1Hop_nativeOut.snap b/.forge-snapshots/V4Router_ExactIn1Hop_nativeOut.snap index e7e76c10c..823bd6a54 100644 --- a/.forge-snapshots/V4Router_ExactIn1Hop_nativeOut.snap +++ b/.forge-snapshots/V4Router_ExactIn1Hop_nativeOut.snap @@ -1 +1 @@ -120119 \ No newline at end of file +120863 \ No newline at end of file diff --git a/.forge-snapshots/V4Router_ExactIn1Hop_oneForZero.snap b/.forge-snapshots/V4Router_ExactIn1Hop_oneForZero.snap index 527b24a3a..63895f7c7 100644 --- a/.forge-snapshots/V4Router_ExactIn1Hop_oneForZero.snap +++ b/.forge-snapshots/V4Router_ExactIn1Hop_oneForZero.snap @@ -1 +1 @@ -128991 \ No newline at end of file +129747 \ No newline at end of file diff --git a/.forge-snapshots/V4Router_ExactIn1Hop_zeroForOne.snap b/.forge-snapshots/V4Router_ExactIn1Hop_zeroForOne.snap index 1fcdfdb7b..ce2fd4e7c 100644 --- a/.forge-snapshots/V4Router_ExactIn1Hop_zeroForOne.snap +++ b/.forge-snapshots/V4Router_ExactIn1Hop_zeroForOne.snap @@ -1 +1 @@ -135517 \ No newline at end of file +136441 \ No newline at end of file diff --git a/.forge-snapshots/V4Router_ExactIn2Hops.snap b/.forge-snapshots/V4Router_ExactIn2Hops.snap index 022fe02b0..4573fd600 100644 --- a/.forge-snapshots/V4Router_ExactIn2Hops.snap +++ b/.forge-snapshots/V4Router_ExactIn2Hops.snap @@ -1 +1 @@ -192843 \ No newline at end of file +194463 \ No newline at end of file diff --git a/.forge-snapshots/V4Router_ExactIn2Hops_nativeIn.snap b/.forge-snapshots/V4Router_ExactIn2Hops_nativeIn.snap index 6f68c80eb..2460e81e5 100644 --- a/.forge-snapshots/V4Router_ExactIn2Hops_nativeIn.snap +++ b/.forge-snapshots/V4Router_ExactIn2Hops_nativeIn.snap @@ -1 +1 @@ -178979 \ No newline at end of file +180515 \ No newline at end of file diff --git a/.forge-snapshots/V4Router_ExactIn3Hops.snap b/.forge-snapshots/V4Router_ExactIn3Hops.snap index 72c812f8c..3bec83314 100644 --- a/.forge-snapshots/V4Router_ExactIn3Hops.snap +++ b/.forge-snapshots/V4Router_ExactIn3Hops.snap @@ -1 +1 @@ -250218 \ No newline at end of file +252534 \ No newline at end of file diff --git a/.forge-snapshots/V4Router_ExactIn3Hops_nativeIn.snap b/.forge-snapshots/V4Router_ExactIn3Hops_nativeIn.snap index fea73fd7e..bc2ca05ea 100644 --- a/.forge-snapshots/V4Router_ExactIn3Hops_nativeIn.snap +++ b/.forge-snapshots/V4Router_ExactIn3Hops_nativeIn.snap @@ -1 +1 @@ -236354 \ No newline at end of file +238586 \ No newline at end of file diff --git a/.forge-snapshots/V4Router_ExactInputSingle.snap b/.forge-snapshots/V4Router_ExactInputSingle.snap index e8d120418..880d383db 100644 --- a/.forge-snapshots/V4Router_ExactInputSingle.snap +++ b/.forge-snapshots/V4Router_ExactInputSingle.snap @@ -1 +1 @@ -134001 \ No newline at end of file +134925 \ No newline at end of file diff --git a/.forge-snapshots/V4Router_ExactInputSingle_nativeIn.snap b/.forge-snapshots/V4Router_ExactInputSingle_nativeIn.snap index 182d8da2a..169567949 100644 --- a/.forge-snapshots/V4Router_ExactInputSingle_nativeIn.snap +++ b/.forge-snapshots/V4Router_ExactInputSingle_nativeIn.snap @@ -1 +1 @@ -120137 \ No newline at end of file +120977 \ No newline at end of file diff --git a/.forge-snapshots/V4Router_ExactInputSingle_nativeOut.snap b/.forge-snapshots/V4Router_ExactInputSingle_nativeOut.snap index 9bb44eced..f1ab7e9d6 100644 --- a/.forge-snapshots/V4Router_ExactInputSingle_nativeOut.snap +++ b/.forge-snapshots/V4Router_ExactInputSingle_nativeOut.snap @@ -1 +1 @@ -118581 \ No newline at end of file +119325 \ No newline at end of file diff --git a/.forge-snapshots/V4Router_ExactOut1Hop_nativeIn_sweepETH.snap b/.forge-snapshots/V4Router_ExactOut1Hop_nativeIn_sweepETH.snap index 82db8f7b1..8613f6d91 100644 --- a/.forge-snapshots/V4Router_ExactOut1Hop_nativeIn_sweepETH.snap +++ b/.forge-snapshots/V4Router_ExactOut1Hop_nativeIn_sweepETH.snap @@ -1 +1 @@ -127940 \ No newline at end of file +128792 \ No newline at end of file diff --git a/.forge-snapshots/V4Router_ExactOut1Hop_nativeOut.snap b/.forge-snapshots/V4Router_ExactOut1Hop_nativeOut.snap index 96c04d44d..7470f11ae 100644 --- a/.forge-snapshots/V4Router_ExactOut1Hop_nativeOut.snap +++ b/.forge-snapshots/V4Router_ExactOut1Hop_nativeOut.snap @@ -1 +1 @@ -121329 \ No newline at end of file +122073 \ No newline at end of file diff --git a/.forge-snapshots/V4Router_ExactOut1Hop_oneForZero.snap b/.forge-snapshots/V4Router_ExactOut1Hop_oneForZero.snap index 59010c68f..edf4eb7ad 100644 --- a/.forge-snapshots/V4Router_ExactOut1Hop_oneForZero.snap +++ b/.forge-snapshots/V4Router_ExactOut1Hop_oneForZero.snap @@ -1 +1 @@ -130201 \ No newline at end of file +130957 \ No newline at end of file diff --git a/.forge-snapshots/V4Router_ExactOut1Hop_zeroForOne.snap b/.forge-snapshots/V4Router_ExactOut1Hop_zeroForOne.snap index 7e653318c..b98846f83 100644 --- a/.forge-snapshots/V4Router_ExactOut1Hop_zeroForOne.snap +++ b/.forge-snapshots/V4Router_ExactOut1Hop_zeroForOne.snap @@ -1 +1 @@ -134858 \ No newline at end of file +135794 \ No newline at end of file diff --git a/.forge-snapshots/V4Router_ExactOut2Hops.snap b/.forge-snapshots/V4Router_ExactOut2Hops.snap index bc92fcdbe..481687037 100644 --- a/.forge-snapshots/V4Router_ExactOut2Hops.snap +++ b/.forge-snapshots/V4Router_ExactOut2Hops.snap @@ -1 +1 @@ -191291 \ No newline at end of file +192935 \ No newline at end of file diff --git a/.forge-snapshots/V4Router_ExactOut2Hops_nativeIn.snap b/.forge-snapshots/V4Router_ExactOut2Hops_nativeIn.snap index 6c96d9097..a12f1f80e 100644 --- a/.forge-snapshots/V4Router_ExactOut2Hops_nativeIn.snap +++ b/.forge-snapshots/V4Router_ExactOut2Hops_nativeIn.snap @@ -1 +1 @@ -184373 \ No newline at end of file +185933 \ No newline at end of file diff --git a/.forge-snapshots/V4Router_ExactOut3Hops.snap b/.forge-snapshots/V4Router_ExactOut3Hops.snap index 32a25024e..d0730d4c3 100644 --- a/.forge-snapshots/V4Router_ExactOut3Hops.snap +++ b/.forge-snapshots/V4Router_ExactOut3Hops.snap @@ -1 +1 @@ -247788 \ No newline at end of file +250140 \ No newline at end of file diff --git a/.forge-snapshots/V4Router_ExactOut3Hops_nativeIn.snap b/.forge-snapshots/V4Router_ExactOut3Hops_nativeIn.snap index 42f6448d7..e646399e4 100644 --- a/.forge-snapshots/V4Router_ExactOut3Hops_nativeIn.snap +++ b/.forge-snapshots/V4Router_ExactOut3Hops_nativeIn.snap @@ -1 +1 @@ -240870 \ No newline at end of file +243138 \ No newline at end of file diff --git a/.forge-snapshots/V4Router_ExactOut3Hops_nativeOut.snap b/.forge-snapshots/V4Router_ExactOut3Hops_nativeOut.snap index acd8db05d..37979b28c 100644 --- a/.forge-snapshots/V4Router_ExactOut3Hops_nativeOut.snap +++ b/.forge-snapshots/V4Router_ExactOut3Hops_nativeOut.snap @@ -1 +1 @@ -224943 \ No newline at end of file +226743 \ No newline at end of file diff --git a/.forge-snapshots/V4Router_ExactOutputSingle.snap b/.forge-snapshots/V4Router_ExactOutputSingle.snap index 410b941d2..eaae5c0eb 100644 --- a/.forge-snapshots/V4Router_ExactOutputSingle.snap +++ b/.forge-snapshots/V4Router_ExactOutputSingle.snap @@ -1 +1 @@ -133337 \ No newline at end of file +134273 \ No newline at end of file diff --git a/.forge-snapshots/V4Router_ExactOutputSingle_nativeIn_sweepETH.snap b/.forge-snapshots/V4Router_ExactOutputSingle_nativeIn_sweepETH.snap index cfd3c90d9..638e21611 100644 --- a/.forge-snapshots/V4Router_ExactOutputSingle_nativeIn_sweepETH.snap +++ b/.forge-snapshots/V4Router_ExactOutputSingle_nativeIn_sweepETH.snap @@ -1 +1 @@ -126419 \ No newline at end of file +127271 \ No newline at end of file diff --git a/.forge-snapshots/V4Router_ExactOutputSingle_nativeOut.snap b/.forge-snapshots/V4Router_ExactOutputSingle_nativeOut.snap index 362e3fea2..a0359cc47 100644 --- a/.forge-snapshots/V4Router_ExactOutputSingle_nativeOut.snap +++ b/.forge-snapshots/V4Router_ExactOutputSingle_nativeOut.snap @@ -1 +1 @@ -119821 \ No newline at end of file +120565 \ No newline at end of file diff --git a/.forge-snapshots/positionDescriptor bytecode size.snap b/.forge-snapshots/positionDescriptor bytecode size.snap index 616fe5514..4cdd5179a 100644 --- a/.forge-snapshots/positionDescriptor bytecode size.snap +++ b/.forge-snapshots/positionDescriptor bytecode size.snap @@ -1 +1 @@ -24177 \ No newline at end of file +24108 \ No newline at end of file diff --git a/.forge-snapshots/positionManager bytecode size.snap b/.forge-snapshots/positionManager bytecode size.snap index ec585573f..205166425 100644 --- a/.forge-snapshots/positionManager bytecode size.snap +++ b/.forge-snapshots/positionManager bytecode size.snap @@ -1 +1 @@ -26931 \ No newline at end of file +23885 \ No newline at end of file From 0e1f119f50f48d50e579f77b21ea497e176bc327 Mon Sep 17 00:00:00 2001 From: gretzke Date: Wed, 27 Nov 2024 21:51:32 +0100 Subject: [PATCH 06/20] remove variable name from natspec --- src/interfaces/IPositionDescriptor.sol | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/interfaces/IPositionDescriptor.sol b/src/interfaces/IPositionDescriptor.sol index a6ed2a9a4..c61abc822 100644 --- a/src/interfaces/IPositionDescriptor.sol +++ b/src/interfaces/IPositionDescriptor.sol @@ -18,13 +18,13 @@ interface IPositionDescriptor { /// @notice Returns true if currency0 has higher priority than currency1 /// @param currency0 The first currency address /// @param currency1 The second currency address - /// @return flipRatio True if currency0 has higher priority than currency1 + /// @return True if currency0 has higher priority than currency1 function flipRatio(address currency0, address currency1) external view returns (bool); /// @notice Returns the priority of a currency. /// For certain currencies on mainnet, the smaller the currency, the higher the priority /// @param currency The currency address - /// @return priority The priority of the currency + /// @return The priority of the currency function currencyRatioPriority(address currency) external view returns (int256); /// @return The wrapped native token for this descriptor From 829ef8c8e9f8b0e5d38d00eddd0ae62fc19eae27 Mon Sep 17 00:00:00 2001 From: gretzke Date: Wed, 27 Nov 2024 21:53:14 +0100 Subject: [PATCH 07/20] add notice natspec --- src/interfaces/IPositionManager.sol | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/interfaces/IPositionManager.sol b/src/interfaces/IPositionManager.sol index c6ea8263c..ee31b6960 100644 --- a/src/interfaces/IPositionManager.sol +++ b/src/interfaces/IPositionManager.sol @@ -45,16 +45,19 @@ interface IPositionManager is /// @return uint256 The next token ID function nextTokenId() external view returns (uint256); + /// @notice Returns the liquidity of a position /// @param tokenId the ERC721 tokenId /// @return liquidity the position's liquidity, as a liquidityAmount /// @dev this value can be processed as an amount0 and amount1 by using the LiquidityAmounts library function getPositionLiquidity(uint256 tokenId) external view returns (uint128 liquidity); + /// @notice Returns the pool key and position info of a position /// @param tokenId the ERC721 tokenId /// @return poolKey the pool key of the position /// @return PositionInfo a uint256 packed value holding information about the position including the range (tickLower, tickUpper) function getPoolAndPositionInfo(uint256 tokenId) external view returns (PoolKey memory, PositionInfo); + /// @notice Returns the position info of a position /// @param tokenId the ERC721 tokenId /// @return a uint256 packed value holding information about the position including the range (tickLower, tickUpper) function positionInfo(uint256 tokenId) external view returns (PositionInfo); From fe2458bb196e535690f43f1ac95436f7c8af939b Mon Sep 17 00:00:00 2001 From: gretzke Date: Wed, 27 Nov 2024 21:53:47 +0100 Subject: [PATCH 08/20] remove unused import --- test/shared/Planner.sol | 1 - 1 file changed, 1 deletion(-) diff --git a/test/shared/Planner.sol b/test/shared/Planner.sol index 0d5ca4fc1..f457207f7 100644 --- a/test/shared/Planner.sol +++ b/test/shared/Planner.sol @@ -3,7 +3,6 @@ pragma solidity ^0.8.20; import {PoolKey} from "@uniswap/v4-core/src/types/PoolKey.sol"; -import {IPositionManager} from "../../src/interfaces/IPositionManager.sol"; import {Actions} from "../../src/libraries/Actions.sol"; import {Currency} from "@uniswap/v4-core/src/types/Currency.sol"; import {ActionConstants} from "../../src/libraries/ActionConstants.sol"; From 6a2139c8786e0743a56d4a592e6d329d665edc5b Mon Sep 17 00:00:00 2001 From: gretzke Date: Wed, 27 Nov 2024 22:15:43 +0100 Subject: [PATCH 09/20] fix compiler warnings --- src/base/BaseV4Quoter.sol | 1 + test/mocks/MockBadSubscribers.sol | 8 ++------ test/mocks/MockSubscriber.sol | 5 +---- 3 files changed, 4 insertions(+), 10 deletions(-) diff --git a/src/base/BaseV4Quoter.sol b/src/base/BaseV4Quoter.sol index 52bacdb3f..55e577429 100644 --- a/src/base/BaseV4Quoter.sol +++ b/src/base/BaseV4Quoter.sol @@ -1,4 +1,5 @@ // SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; import {IPoolManager} from "@uniswap/v4-core/src/interfaces/IPoolManager.sol"; import {BalanceDelta} from "@uniswap/v4-core/src/types/BalanceDelta.sol"; diff --git a/test/mocks/MockBadSubscribers.sol b/test/mocks/MockBadSubscribers.sol index 525687e0b..a430185d4 100644 --- a/test/mocks/MockBadSubscribers.sol +++ b/test/mocks/MockBadSubscribers.sol @@ -48,9 +48,7 @@ contract MockReturnDataSubscriber is ISubscriber { notifyModifyLiquidityCount++; } - function notifyBurn(uint256 tokenId, address owner, PositionInfo info, uint256 liquidity, BalanceDelta feesAccrued) - external - { + function notifyBurn(uint256, address, PositionInfo, uint256, BalanceDelta) external pure { return; } @@ -92,9 +90,7 @@ contract MockRevertSubscriber is ISubscriber { revert TestRevert("notifyModifyLiquidity"); } - function notifyBurn(uint256 tokenId, address owner, PositionInfo info, uint256 liquidity, BalanceDelta feesAccrued) - external - { + function notifyBurn(uint256, address, PositionInfo, uint256, BalanceDelta) external pure { return; } diff --git a/test/mocks/MockSubscriber.sol b/test/mocks/MockSubscriber.sol index c38cb6469..fb1269277 100644 --- a/test/mocks/MockSubscriber.sol +++ b/test/mocks/MockSubscriber.sol @@ -47,10 +47,7 @@ contract MockSubscriber is ISubscriber { feesAccrued = _feesAccrued; } - function notifyBurn(uint256 tokenId, address owner, PositionInfo info, uint256 liquidity, BalanceDelta feesAccrued) - external - onlyByPosm - { + function notifyBurn(uint256, address, PositionInfo, uint256, BalanceDelta) external onlyByPosm { notifyBurnCount++; } } From 43f44850a812ed83d603e460cb255e6aed005ce9 Mon Sep 17 00:00:00 2001 From: Daniel Gretzke Date: Wed, 27 Nov 2024 22:16:23 +0100 Subject: [PATCH 10/20] Update src/interfaces/IPoolInitializer.sol Co-authored-by: Alice <34962750+hensha256@users.noreply.github.com> --- src/interfaces/IPoolInitializer.sol | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/interfaces/IPoolInitializer.sol b/src/interfaces/IPoolInitializer.sol index 3a2115eed..39460f3e5 100644 --- a/src/interfaces/IPoolInitializer.sol +++ b/src/interfaces/IPoolInitializer.sol @@ -8,6 +8,6 @@ interface IPoolInitializer { /// @dev If the pool is already initialized, this function will not revert and just return type(int24).max /// @param key The PoolKey of the pool to initialize /// @param sqrtPriceX96 The initial sqrtPriceX96 of the pool - /// @return tick The current tick of the pool + /// @return tick The current tick of the pool, or type(int24).max if the pool creation failed, or the pool already existed function initializePool(PoolKey calldata key, uint160 sqrtPriceX96) external payable returns (int24); } From 309a35a1f350477ad356e1eaf45d4b1e886a2d7e Mon Sep 17 00:00:00 2001 From: gretzke Date: Wed, 27 Nov 2024 22:49:40 +0100 Subject: [PATCH 11/20] add `UnorderedNonce` interface --- src/base/UnorderedNonce.sol | 10 ++--- src/interfaces/IPositionManager.sol | 6 ++- src/interfaces/IUnorderedNonce.sol | 13 +++++++ test/UnorderedNonce.t.sol | 38 +++++++++---------- test/erc721Permit/ERC721Permit.permit.t.sol | 6 +-- .../ERC721Permit.permitForAll.t.sol | 8 ++-- test/position-managers/Permit.t.sol | 6 +-- 7 files changed, 50 insertions(+), 37 deletions(-) create mode 100644 src/interfaces/IUnorderedNonce.sol diff --git a/src/base/UnorderedNonce.sol b/src/base/UnorderedNonce.sol index b08b5d92c..2ee0336f6 100644 --- a/src/base/UnorderedNonce.sol +++ b/src/base/UnorderedNonce.sol @@ -1,11 +1,11 @@ // SPDX-License-Identifier: MIT pragma solidity ^0.8.0; +import {IUnorderedNonce} from "../interfaces/IUnorderedNonce.sol"; + /// @title Unordered Nonce /// @notice Contract state and methods for using unordered nonces in signatures -contract UnorderedNonce { - error NonceAlreadyUsed(); - +contract UnorderedNonce is IUnorderedNonce { /// @notice mapping of nonces consumed by each address, where a nonce is a single bit on the 256-bit bitmap /// @dev word is at most type(uint248).max mapping(address owner => mapping(uint256 word => uint256 bitmap)) public nonces; @@ -22,9 +22,7 @@ contract UnorderedNonce { if (flipped & bit == 0) revert NonceAlreadyUsed(); } - /// @notice Revoke a nonce by spending it, preventing it from being used again - /// @dev Used in cases where a valid nonce has not been broadcasted onchain, and the owner wants to revoke the validity of the nonce - /// @dev payable so it can be multicalled with native-token related actions + /// @inheritdoc IUnorderedNonce function revokeNonce(uint256 nonce) external payable { _useUnorderedNonce(msg.sender, nonce); } diff --git a/src/interfaces/IPositionManager.sol b/src/interfaces/IPositionManager.sol index ee31b6960..421c35d3a 100644 --- a/src/interfaces/IPositionManager.sol +++ b/src/interfaces/IPositionManager.sol @@ -10,16 +10,18 @@ import {IERC721Permit_v4} from "./IERC721Permit_v4.sol"; import {IEIP712_v4} from "./IEIP712_v4.sol"; import {IMulticall_v4} from "./IMulticall_v4.sol"; import {IPoolInitializer} from "./IPoolInitializer.sol"; +import {IUnorderedNonce} from "./IUnorderedNonce.sol"; + /// @title IPositionManager /// @notice Interface for the PositionManager contract - interface IPositionManager is INotifier, IImmutableState, IERC721Permit_v4, IEIP712_v4, IMulticall_v4, - IPoolInitializer + IPoolInitializer, + IUnorderedNonce { /// @notice Thrown when the caller is not approved to modify a position error NotApproved(address caller); diff --git a/src/interfaces/IUnorderedNonce.sol b/src/interfaces/IUnorderedNonce.sol new file mode 100644 index 000000000..03d3987e6 --- /dev/null +++ b/src/interfaces/IUnorderedNonce.sol @@ -0,0 +1,13 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; + +/// @title UnorderedNonce Interface +/// @notice Interface for the UnorderedNonce contract +interface IUnorderedNonce { + error NonceAlreadyUsed(); + + /// @notice Revoke a nonce by spending it, preventing it from being used again + /// @dev Used in cases where a valid nonce has not been broadcasted onchain, and the owner wants to revoke the validity of the nonce + /// @dev payable so it can be multicalled with native-token related actions + function revokeNonce(uint256 nonce) external payable; +} diff --git a/test/UnorderedNonce.t.sol b/test/UnorderedNonce.t.sol index f7b46b2da..0983876dc 100644 --- a/test/UnorderedNonce.t.sol +++ b/test/UnorderedNonce.t.sol @@ -2,7 +2,7 @@ pragma solidity ^0.8.20; import "forge-std/Test.sol"; -import {UnorderedNonce} from "../src/base/UnorderedNonce.sol"; +import {UnorderedNonce, IUnorderedNonce} from "../src/base/UnorderedNonce.sol"; import {MockUnorderedNonce} from "./mocks/MockUnorderedNonce.sol"; contract UnorderedNonceTest is Test { @@ -17,11 +17,11 @@ contract UnorderedNonceTest is Test { unorderedNonce.spendNonce(address(this), 0); unorderedNonce.spendNonce(address(this), 1); - vm.expectRevert(UnorderedNonce.NonceAlreadyUsed.selector); + vm.expectRevert(IUnorderedNonce.NonceAlreadyUsed.selector); unorderedNonce.spendNonce(address(this), 1); - vm.expectRevert(UnorderedNonce.NonceAlreadyUsed.selector); + vm.expectRevert(IUnorderedNonce.NonceAlreadyUsed.selector); unorderedNonce.spendNonce(address(this), 5); - vm.expectRevert(UnorderedNonce.NonceAlreadyUsed.selector); + vm.expectRevert(IUnorderedNonce.NonceAlreadyUsed.selector); unorderedNonce.spendNonce(address(this), 0); unorderedNonce.spendNonce(address(this), 4); } @@ -30,9 +30,9 @@ contract UnorderedNonceTest is Test { unorderedNonce.spendNonce(address(this), 255); unorderedNonce.spendNonce(address(this), 256); - vm.expectRevert(UnorderedNonce.NonceAlreadyUsed.selector); + vm.expectRevert(IUnorderedNonce.NonceAlreadyUsed.selector); unorderedNonce.spendNonce(address(this), 255); - vm.expectRevert(UnorderedNonce.NonceAlreadyUsed.selector); + vm.expectRevert(IUnorderedNonce.NonceAlreadyUsed.selector); unorderedNonce.spendNonce(address(this), 256); } @@ -40,9 +40,9 @@ contract UnorderedNonceTest is Test { unorderedNonce.spendNonce(address(this), 2 ** 240); unorderedNonce.spendNonce(address(this), 2 ** 240 + 1); - vm.expectRevert(UnorderedNonce.NonceAlreadyUsed.selector); + vm.expectRevert(IUnorderedNonce.NonceAlreadyUsed.selector); unorderedNonce.spendNonce(address(this), 2 ** 240); - vm.expectRevert(UnorderedNonce.NonceAlreadyUsed.selector); + vm.expectRevert(IUnorderedNonce.NonceAlreadyUsed.selector); unorderedNonce.spendNonce(address(this), 2 ** 240 + 1); unorderedNonce.spendNonce(address(this), 2 ** 240 + 2); @@ -51,13 +51,13 @@ contract UnorderedNonceTest is Test { function testInvalidateFullWord() public { unorderedNonce.batchSpendNonces(0, 2 ** 256 - 1); - vm.expectRevert(UnorderedNonce.NonceAlreadyUsed.selector); + vm.expectRevert(IUnorderedNonce.NonceAlreadyUsed.selector); unorderedNonce.spendNonce(address(this), 0); - vm.expectRevert(UnorderedNonce.NonceAlreadyUsed.selector); + vm.expectRevert(IUnorderedNonce.NonceAlreadyUsed.selector); unorderedNonce.spendNonce(address(this), 1); - vm.expectRevert(UnorderedNonce.NonceAlreadyUsed.selector); + vm.expectRevert(IUnorderedNonce.NonceAlreadyUsed.selector); unorderedNonce.spendNonce(address(this), 254); - vm.expectRevert(UnorderedNonce.NonceAlreadyUsed.selector); + vm.expectRevert(IUnorderedNonce.NonceAlreadyUsed.selector); unorderedNonce.spendNonce(address(this), 255); unorderedNonce.spendNonce(address(this), 256); } @@ -68,9 +68,9 @@ contract UnorderedNonceTest is Test { unorderedNonce.spendNonce(address(this), 0); unorderedNonce.spendNonce(address(this), 254); unorderedNonce.spendNonce(address(this), 255); - vm.expectRevert(UnorderedNonce.NonceAlreadyUsed.selector); + vm.expectRevert(IUnorderedNonce.NonceAlreadyUsed.selector); unorderedNonce.spendNonce(address(this), 256); - vm.expectRevert(UnorderedNonce.NonceAlreadyUsed.selector); + vm.expectRevert(IUnorderedNonce.NonceAlreadyUsed.selector); unorderedNonce.spendNonce(address(this), 511); unorderedNonce.spendNonce(address(this), 512); } @@ -87,21 +87,21 @@ contract UnorderedNonceTest is Test { nonce = bound(nonce, 0, (word + 2) * 256); if ((word * 256) <= nonce && nonce < ((word + 1) * 256)) { - vm.expectRevert(UnorderedNonce.NonceAlreadyUsed.selector); + vm.expectRevert(IUnorderedNonce.NonceAlreadyUsed.selector); } unorderedNonce.spendNonce(address(this), nonce); } function test_fuzz_UsingNonceTwiceFails(uint256 nonce) public { unorderedNonce.spendNonce(address(this), nonce); - vm.expectRevert(UnorderedNonce.NonceAlreadyUsed.selector); + vm.expectRevert(IUnorderedNonce.NonceAlreadyUsed.selector); unorderedNonce.spendNonce(address(this), nonce); } function test_fuzz_UseTwoRandomNonces(uint256 first, uint256 second) public { unorderedNonce.spendNonce(address(this), first); if (first == second) { - vm.expectRevert(UnorderedNonce.NonceAlreadyUsed.selector); + vm.expectRevert(IUnorderedNonce.NonceAlreadyUsed.selector); unorderedNonce.spendNonce(address(this), second); } else { unorderedNonce.spendNonce(address(this), second); @@ -110,13 +110,13 @@ contract UnorderedNonceTest is Test { function test_fuzz_revokeNonce(uint256 nonce) public { unorderedNonce.revokeNonce(nonce); - vm.expectRevert(UnorderedNonce.NonceAlreadyUsed.selector); + vm.expectRevert(IUnorderedNonce.NonceAlreadyUsed.selector); unorderedNonce.revokeNonce(nonce); } function test_fuzz_revokeNonce_twoNonces(uint256 first, uint256 second) public { unorderedNonce.revokeNonce(first); - if (first == second) vm.expectRevert(UnorderedNonce.NonceAlreadyUsed.selector); + if (first == second) vm.expectRevert(IUnorderedNonce.NonceAlreadyUsed.selector); unorderedNonce.revokeNonce(second); } } diff --git a/test/erc721Permit/ERC721Permit.permit.t.sol b/test/erc721Permit/ERC721Permit.permit.t.sol index 0a741381e..00a50e801 100644 --- a/test/erc721Permit/ERC721Permit.permit.t.sol +++ b/test/erc721Permit/ERC721Permit.permit.t.sol @@ -8,7 +8,7 @@ import {ERC721PermitHash} from "../../src/libraries/ERC721PermitHash.sol"; import {MockERC721Permit} from "../mocks/MockERC721Permit.sol"; import {IERC721Permit_v4} from "../../src/interfaces/IERC721Permit_v4.sol"; import {IERC721} from "forge-std/interfaces/IERC721.sol"; -import {UnorderedNonce} from "../../src/base/UnorderedNonce.sol"; +import {IUnorderedNonce} from "../../src/interfaces/IUnorderedNonce.sol"; contract ERC721PermitTest is Test { MockERC721Permit erc721Permit; @@ -169,7 +169,7 @@ contract ERC721PermitTest is Test { bytes memory signature = abi.encodePacked(r, s, v); vm.startPrank(alice); - vm.expectRevert(UnorderedNonce.NonceAlreadyUsed.selector); + vm.expectRevert(IUnorderedNonce.NonceAlreadyUsed.selector); erc721Permit.permit(bob, tokenIdAlice, block.timestamp, nonce, signature); vm.stopPrank(); } @@ -192,7 +192,7 @@ contract ERC721PermitTest is Test { bytes memory signature = abi.encodePacked(r, s, v); vm.startPrank(alice); - vm.expectRevert(UnorderedNonce.NonceAlreadyUsed.selector); + vm.expectRevert(IUnorderedNonce.NonceAlreadyUsed.selector); erc721Permit.permit(bob, tokenIdAlice2, block.timestamp, nonce, signature); vm.stopPrank(); } diff --git a/test/erc721Permit/ERC721Permit.permitForAll.t.sol b/test/erc721Permit/ERC721Permit.permitForAll.t.sol index c8150895f..4cfa43a87 100644 --- a/test/erc721Permit/ERC721Permit.permitForAll.t.sol +++ b/test/erc721Permit/ERC721Permit.permitForAll.t.sol @@ -8,7 +8,7 @@ import {ERC721PermitHash} from "../../src/libraries/ERC721PermitHash.sol"; import {MockERC721Permit} from "../mocks/MockERC721Permit.sol"; import {IERC721Permit_v4} from "../../src/interfaces/IERC721Permit_v4.sol"; import {IERC721} from "forge-std/interfaces/IERC721.sol"; -import {UnorderedNonce} from "../../src/base/UnorderedNonce.sol"; +import {IUnorderedNonce} from "../../src/interfaces/IUnorderedNonce.sol"; contract ERC721PermitForAllTest is Test { MockERC721Permit erc721Permit; @@ -141,7 +141,7 @@ contract ERC721PermitForAllTest is Test { bytes memory signature = abi.encodePacked(r, s, v); vm.startPrank(alice); - vm.expectRevert(UnorderedNonce.NonceAlreadyUsed.selector); + vm.expectRevert(IUnorderedNonce.NonceAlreadyUsed.selector); erc721Permit.permitForAll(alice, bob, true, block.timestamp, nonce, signature); vm.stopPrank(); } @@ -292,7 +292,7 @@ contract ERC721PermitForAllTest is Test { // Nonce does not work with permitForAll vm.startPrank(bob); - vm.expectRevert(UnorderedNonce.NonceAlreadyUsed.selector); + vm.expectRevert(IUnorderedNonce.NonceAlreadyUsed.selector); erc721Permit.permitForAll(alice, bob, true, deadline, nonce, signature); vm.stopPrank(); } @@ -311,7 +311,7 @@ contract ERC721PermitForAllTest is Test { // Nonce does not work with permitForAll vm.startPrank(bob); - vm.expectRevert(UnorderedNonce.NonceAlreadyUsed.selector); + vm.expectRevert(IUnorderedNonce.NonceAlreadyUsed.selector); erc721Permit.permitForAll(alice, bob, true, deadline, nonce, signature); vm.stopPrank(); } diff --git a/test/position-managers/Permit.t.sol b/test/position-managers/Permit.t.sol index 2bddf39d4..e60c1d27c 100644 --- a/test/position-managers/Permit.t.sol +++ b/test/position-managers/Permit.t.sol @@ -15,7 +15,7 @@ import {SignatureVerification} from "permit2/src/libraries/SignatureVerification import {IERC20} from "forge-std/interfaces/IERC20.sol"; import {IERC721Permit_v4} from "../../src/interfaces/IERC721Permit_v4.sol"; import {ERC721Permit_v4} from "../../src/base/ERC721Permit_v4.sol"; -import {UnorderedNonce} from "../../src/base/UnorderedNonce.sol"; +import {IUnorderedNonce} from "../../src/interfaces/IUnorderedNonce.sol"; import {PositionConfig} from "../shared/PositionConfig.sol"; import {IPositionManager} from "../../src/interfaces/IPositionManager.sol"; @@ -226,7 +226,7 @@ contract PermitTest is Test, PosmTestSetup { // alice revokes the nonce vm.prank(alice); - UnorderedNonce(address(lpm)).revokeNonce(nonce); + lpm.revokeNonce(nonce); // alice gives bob spender permissions bytes32 digest = getDigest(bob, tokenIdAlice, nonce, block.timestamp + 1); @@ -234,7 +234,7 @@ contract PermitTest is Test, PosmTestSetup { (uint8 v, bytes32 r, bytes32 s) = vm.sign(alicePK, digest); bytes memory signature = abi.encodePacked(r, s, v); - vm.expectRevert(UnorderedNonce.NonceAlreadyUsed.selector); + vm.expectRevert(IUnorderedNonce.NonceAlreadyUsed.selector); lpm.permit(bob, tokenIdAlice, block.timestamp + 1, nonce, signature); } From 8678bd4d4adad05ee6646ffa37ea257a42b5a016 Mon Sep 17 00:00:00 2001 From: gretzke Date: Wed, 27 Nov 2024 22:59:28 +0100 Subject: [PATCH 12/20] add `Permit2Forwarder` interface --- .../positionDescriptor bytecode size.snap | 2 +- src/base/Permit2Forwarder.sol | 16 +++------- src/interfaces/IPermit2Forwarder.sol | 30 +++++++++++++++++++ src/interfaces/IPositionManager.sol | 4 ++- .../PositionManager.multicall.t.sol | 14 ++++----- 5 files changed, 45 insertions(+), 21 deletions(-) create mode 100644 src/interfaces/IPermit2Forwarder.sol diff --git a/.forge-snapshots/positionDescriptor bytecode size.snap b/.forge-snapshots/positionDescriptor bytecode size.snap index 4cdd5179a..616fe5514 100644 --- a/.forge-snapshots/positionDescriptor bytecode size.snap +++ b/.forge-snapshots/positionDescriptor bytecode size.snap @@ -1 +1 @@ -24108 \ No newline at end of file +24177 \ No newline at end of file diff --git a/src/base/Permit2Forwarder.sol b/src/base/Permit2Forwarder.sol index d5a749a85..d7cce0355 100644 --- a/src/base/Permit2Forwarder.sol +++ b/src/base/Permit2Forwarder.sol @@ -1,11 +1,11 @@ // SPDX-License-Identifier: MIT pragma solidity ^0.8.0; -import {IAllowanceTransfer} from "permit2/src/interfaces/IAllowanceTransfer.sol"; +import {IPermit2Forwarder, IAllowanceTransfer} from "../interfaces/IPermit2Forwarder.sol"; /// @notice PermitForwarder allows permitting this contract as a spender on permit2 /// @dev This contract does not enforce the spender to be this contract, but that is the intended use case -contract Permit2Forwarder { +contract Permit2Forwarder is IPermit2Forwarder { /// @notice the Permit2 contract to forward approvals IAllowanceTransfer public immutable permit2; @@ -13,11 +13,7 @@ contract Permit2Forwarder { permit2 = _permit2; } - /// @notice allows forwarding a single permit to permit2 - /// @dev this function is payable to allow multicall with NATIVE based actions - /// @param owner the owner of the tokens - /// @param permitSingle the permit data - /// @param signature the signature of the permit; abi.encodePacked(r, s, v) + /// @inheritdoc IPermit2Forwarder function permit(address owner, IAllowanceTransfer.PermitSingle calldata permitSingle, bytes calldata signature) external payable @@ -30,11 +26,7 @@ contract Permit2Forwarder { } } - /// @notice allows forwarding batch permits to permit2 - /// @dev this function is payable to allow multicall with NATIVE based actions - /// @param owner the owner of the tokens - /// @param _permitBatch a batch of approvals - /// @param signature the signature of the permit; abi.encodePacked(r, s, v) + /// @inheritdoc IPermit2Forwarder function permitBatch(address owner, IAllowanceTransfer.PermitBatch calldata _permitBatch, bytes calldata signature) external payable diff --git a/src/interfaces/IPermit2Forwarder.sol b/src/interfaces/IPermit2Forwarder.sol new file mode 100644 index 000000000..0099466c2 --- /dev/null +++ b/src/interfaces/IPermit2Forwarder.sol @@ -0,0 +1,30 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; + +import {IAllowanceTransfer} from "permit2/src/interfaces/IAllowanceTransfer.sol"; + +/// @notice PermitForwarder allows permitting this contract as a spender on permit2 +/// @dev This contract does not enforce the spender to be this contract, but that is the intended use case +interface IPermit2Forwarder { + /// @notice allows forwarding a single permit to permit2 + /// @dev this function is payable to allow multicall with NATIVE based actions + /// @param owner the owner of the tokens + /// @param permitSingle the permit data + /// @param signature the signature of the permit; abi.encodePacked(r, s, v) + /// @return err the error returned by a reverting permit call, empty if successful + function permit(address owner, IAllowanceTransfer.PermitSingle calldata permitSingle, bytes calldata signature) + external + payable + returns (bytes memory err); + + /// @notice allows forwarding batch permits to permit2 + /// @dev this function is payable to allow multicall with NATIVE based actions + /// @param owner the owner of the tokens + /// @param _permitBatch a batch of approvals + /// @param signature the signature of the permit; abi.encodePacked(r, s, v) + /// @return err the error returned by a reverting permit call, empty if successful + function permitBatch(address owner, IAllowanceTransfer.PermitBatch calldata _permitBatch, bytes calldata signature) + external + payable + returns (bytes memory err); +} diff --git a/src/interfaces/IPositionManager.sol b/src/interfaces/IPositionManager.sol index 421c35d3a..e9746fbf0 100644 --- a/src/interfaces/IPositionManager.sol +++ b/src/interfaces/IPositionManager.sol @@ -11,6 +11,7 @@ import {IEIP712_v4} from "./IEIP712_v4.sol"; import {IMulticall_v4} from "./IMulticall_v4.sol"; import {IPoolInitializer} from "./IPoolInitializer.sol"; import {IUnorderedNonce} from "./IUnorderedNonce.sol"; +import {IPermit2Forwarder} from "./IPermit2Forwarder.sol"; /// @title IPositionManager /// @notice Interface for the PositionManager contract @@ -21,7 +22,8 @@ interface IPositionManager is IEIP712_v4, IMulticall_v4, IPoolInitializer, - IUnorderedNonce + IUnorderedNonce, + IPermit2Forwarder { /// @notice Thrown when the caller is not approved to modify a position error NotApproved(address caller); diff --git a/test/position-managers/PositionManager.multicall.t.sol b/test/position-managers/PositionManager.multicall.t.sol index 81ddfed5f..18efd831d 100644 --- a/test/position-managers/PositionManager.multicall.t.sol +++ b/test/position-managers/PositionManager.multicall.t.sol @@ -26,7 +26,7 @@ import {LiquidityFuzzers} from "../shared/fuzz/LiquidityFuzzers.sol"; import {Planner, Plan} from "../shared/Planner.sol"; import {PosmTestSetup} from "../shared/PosmTestSetup.sol"; import {Permit2SignatureHelpers} from "../shared/Permit2SignatureHelpers.sol"; -import {Permit2Forwarder} from "../../src/base/Permit2Forwarder.sol"; +import {Permit2Forwarder, IPermit2Forwarder} from "../../src/base/Permit2Forwarder.sol"; import {ActionConstants} from "../../src/libraries/ActionConstants.sol"; import {IERC721Permit_v4} from "../../src/interfaces/IERC721Permit_v4.sol"; @@ -421,8 +421,8 @@ contract PositionManagerMulticallTest is Test, Permit2SignatureHelpers, PosmTest // bob front-runs the permits vm.startPrank(bob); - Permit2Forwarder(address(lpm)).permit(charlie, permit0, sig0); - Permit2Forwarder(address(lpm)).permit(charlie, permit1, sig1); + lpm.permit(charlie, permit0, sig0); + lpm.permit(charlie, permit1, sig1); vm.stopPrank(); // bob's front-run was successful @@ -439,8 +439,8 @@ contract PositionManagerMulticallTest is Test, Permit2SignatureHelpers, PosmTest // charlie tries to mint an LP token with multicall(permit, permit, mint) bytes[] memory calls = new bytes[](3); - calls[0] = abi.encodeWithSelector(Permit2Forwarder(address(lpm)).permit.selector, charlie, permit0, sig0); - calls[1] = abi.encodeWithSelector(Permit2Forwarder(address(lpm)).permit.selector, charlie, permit1, sig1); + calls[0] = abi.encodeWithSelector(IPermit2Forwarder.permit.selector, charlie, permit0, sig0); + calls[1] = abi.encodeWithSelector(IPermit2Forwarder.permit.selector, charlie, permit1, sig1); bytes memory mintCall = getMintEncoded(config, 10e18, charlie, ZERO_BYTES); calls[2] = abi.encodeWithSelector(IPositionManager.modifyLiquidities.selector, mintCall, _deadline); @@ -475,7 +475,7 @@ contract PositionManagerMulticallTest is Test, Permit2SignatureHelpers, PosmTest // bob front-runs the permits vm.prank(bob); - Permit2Forwarder(address(lpm)).permitBatch(charlie, permit, sig); + lpm.permitBatch(charlie, permit, sig); // bob's front-run was successful (uint160 _amount, uint48 _expiration, uint48 _nonce) = @@ -491,7 +491,7 @@ contract PositionManagerMulticallTest is Test, Permit2SignatureHelpers, PosmTest // charlie tries to mint an LP token with multicall(permitBatch, mint) bytes[] memory calls = new bytes[](2); - calls[0] = abi.encodeWithSelector(Permit2Forwarder(address(lpm)).permitBatch.selector, charlie, permit, sig); + calls[0] = abi.encodeWithSelector(lpm.permitBatch.selector, charlie, permit, sig); bytes memory mintCall = getMintEncoded(config, 10e18, charlie, ZERO_BYTES); calls[1] = abi.encodeWithSelector(IPositionManager.modifyLiquidities.selector, mintCall, _deadline); From 5c7bf71e92d952c7c61d7d609e9b567e9ffe43f1 Mon Sep 17 00:00:00 2001 From: gretzke Date: Wed, 27 Nov 2024 23:09:06 +0100 Subject: [PATCH 13/20] increase optimizer runs for non posm contracts --- .../Payments_swap_settleFromCaller_takeAllToMsgSender.snap | 2 +- ...ments_swap_settleFromCaller_takeAllToSpecifiedAddress.snap | 2 +- .../Payments_swap_settleWithBalance_takeAllToMsgSender.snap | 2 +- ...ents_swap_settleWithBalance_takeAllToSpecifiedAddress.snap | 2 +- .../PositionManager_burn_nonEmpty_native_withClose.snap | 2 +- .../PositionManager_burn_nonEmpty_native_withTakePair.snap | 2 +- .forge-snapshots/PositionManager_burn_nonEmpty_withClose.snap | 2 +- .../PositionManager_burn_nonEmpty_withTakePair.snap | 2 +- .forge-snapshots/PositionManager_collect_native.snap | 2 +- .forge-snapshots/PositionManager_collect_sameRange.snap | 2 +- .forge-snapshots/PositionManager_collect_withClose.snap | 2 +- .forge-snapshots/PositionManager_collect_withTakePair.snap | 2 +- .../PositionManager_decreaseLiquidity_native.snap | 2 +- .../PositionManager_decreaseLiquidity_withClose.snap | 2 +- .../PositionManager_decreaseLiquidity_withTakePair.snap | 2 +- .forge-snapshots/PositionManager_decrease_burnEmpty.snap | 2 +- .../PositionManager_decrease_burnEmpty_native.snap | 2 +- .../PositionManager_decrease_sameRange_allLiquidity.snap | 2 +- .forge-snapshots/PositionManager_decrease_take_take.snap | 2 +- .../PositionManager_increaseLiquidity_erc20_withClose.snap | 2 +- ...ositionManager_increaseLiquidity_erc20_withSettlePair.snap | 2 +- .../PositionManager_increaseLiquidity_native.snap | 2 +- ...sitionManager_increase_autocompoundExactUnclaimedFees.snap | 2 +- ...PositionManager_increase_autocompoundExcessFeesCredit.snap | 2 +- .../PositionManager_increase_autocompound_clearExcess.snap | 2 +- .forge-snapshots/PositionManager_mint_native.snap | 2 +- .../PositionManager_mint_nativeWithSweep_withClose.snap | 2 +- .../PositionManager_mint_nativeWithSweep_withSettlePair.snap | 2 +- .forge-snapshots/PositionManager_mint_onSameTickLower.snap | 2 +- .forge-snapshots/PositionManager_mint_onSameTickUpper.snap | 2 +- .forge-snapshots/PositionManager_mint_sameRange.snap | 2 +- .../PositionManager_mint_settleWithBalance_sweep.snap | 2 +- .../PositionManager_mint_warmedPool_differentRange.snap | 2 +- .forge-snapshots/PositionManager_mint_withClose.snap | 2 +- .forge-snapshots/PositionManager_mint_withSettlePair.snap | 2 +- .../PositionManager_multicall_initialize_mint.snap | 2 +- .../Quoter_exactInputSingle_oneForZero_multiplePositions.snap | 2 +- .../Quoter_exactInputSingle_zeroForOne_multiplePositions.snap | 2 +- .forge-snapshots/Quoter_exactOutputSingle_oneForZero.snap | 2 +- .forge-snapshots/Quoter_exactOutputSingle_zeroForOne.snap | 2 +- .../Quoter_quoteExactInput_oneHop_1TickLoaded.snap | 2 +- .../Quoter_quoteExactInput_oneHop_initializedAfter.snap | 2 +- .../Quoter_quoteExactInput_oneHop_startingInitialized.snap | 2 +- .forge-snapshots/Quoter_quoteExactInput_twoHops.snap | 2 +- .../Quoter_quoteExactOutput_oneHop_1TickLoaded.snap | 2 +- .../Quoter_quoteExactOutput_oneHop_2TicksLoaded.snap | 2 +- .../Quoter_quoteExactOutput_oneHop_initializedAfter.snap | 2 +- .../Quoter_quoteExactOutput_oneHop_startingInitialized.snap | 2 +- .forge-snapshots/Quoter_quoteExactOutput_twoHops.snap | 2 +- .forge-snapshots/V4Router_ExactIn1Hop_nativeIn.snap | 2 +- .forge-snapshots/V4Router_ExactIn1Hop_nativeOut.snap | 2 +- .forge-snapshots/V4Router_ExactIn1Hop_oneForZero.snap | 2 +- .forge-snapshots/V4Router_ExactIn1Hop_zeroForOne.snap | 2 +- .forge-snapshots/V4Router_ExactIn2Hops.snap | 2 +- .forge-snapshots/V4Router_ExactIn2Hops_nativeIn.snap | 2 +- .forge-snapshots/V4Router_ExactIn3Hops.snap | 2 +- .forge-snapshots/V4Router_ExactIn3Hops_nativeIn.snap | 2 +- .forge-snapshots/V4Router_ExactInputSingle.snap | 2 +- .forge-snapshots/V4Router_ExactInputSingle_nativeIn.snap | 2 +- .forge-snapshots/V4Router_ExactInputSingle_nativeOut.snap | 2 +- .forge-snapshots/V4Router_ExactOut1Hop_nativeIn_sweepETH.snap | 2 +- .forge-snapshots/V4Router_ExactOut1Hop_nativeOut.snap | 2 +- .forge-snapshots/V4Router_ExactOut1Hop_oneForZero.snap | 2 +- .forge-snapshots/V4Router_ExactOut1Hop_zeroForOne.snap | 2 +- .forge-snapshots/V4Router_ExactOut2Hops.snap | 2 +- .forge-snapshots/V4Router_ExactOut2Hops_nativeIn.snap | 2 +- .forge-snapshots/V4Router_ExactOut3Hops.snap | 2 +- .forge-snapshots/V4Router_ExactOut3Hops_nativeIn.snap | 2 +- .forge-snapshots/V4Router_ExactOut3Hops_nativeOut.snap | 2 +- .forge-snapshots/V4Router_ExactOutputSingle.snap | 2 +- .../V4Router_ExactOutputSingle_nativeIn_sweepETH.snap | 2 +- .forge-snapshots/V4Router_ExactOutputSingle_nativeOut.snap | 2 +- foundry.toml | 4 +++- 73 files changed, 75 insertions(+), 73 deletions(-) diff --git a/.forge-snapshots/Payments_swap_settleFromCaller_takeAllToMsgSender.snap b/.forge-snapshots/Payments_swap_settleFromCaller_takeAllToMsgSender.snap index 646d167c3..94949b13c 100644 --- a/.forge-snapshots/Payments_swap_settleFromCaller_takeAllToMsgSender.snap +++ b/.forge-snapshots/Payments_swap_settleFromCaller_takeAllToMsgSender.snap @@ -1 +1 @@ -133930 \ No newline at end of file +133006 \ No newline at end of file diff --git a/.forge-snapshots/Payments_swap_settleFromCaller_takeAllToSpecifiedAddress.snap b/.forge-snapshots/Payments_swap_settleFromCaller_takeAllToSpecifiedAddress.snap index 805b98bbc..75de88e95 100644 --- a/.forge-snapshots/Payments_swap_settleFromCaller_takeAllToSpecifiedAddress.snap +++ b/.forge-snapshots/Payments_swap_settleFromCaller_takeAllToSpecifiedAddress.snap @@ -1 +1 @@ -135399 \ No newline at end of file +134475 \ No newline at end of file diff --git a/.forge-snapshots/Payments_swap_settleWithBalance_takeAllToMsgSender.snap b/.forge-snapshots/Payments_swap_settleWithBalance_takeAllToMsgSender.snap index b179f65d1..e0dd700d5 100644 --- a/.forge-snapshots/Payments_swap_settleWithBalance_takeAllToMsgSender.snap +++ b/.forge-snapshots/Payments_swap_settleWithBalance_takeAllToMsgSender.snap @@ -1 +1 @@ -127881 \ No newline at end of file +126957 \ No newline at end of file diff --git a/.forge-snapshots/Payments_swap_settleWithBalance_takeAllToSpecifiedAddress.snap b/.forge-snapshots/Payments_swap_settleWithBalance_takeAllToSpecifiedAddress.snap index 2edf2f600..9390c7055 100644 --- a/.forge-snapshots/Payments_swap_settleWithBalance_takeAllToSpecifiedAddress.snap +++ b/.forge-snapshots/Payments_swap_settleWithBalance_takeAllToSpecifiedAddress.snap @@ -1 +1 @@ -128019 \ No newline at end of file +127095 \ No newline at end of file diff --git a/.forge-snapshots/PositionManager_burn_nonEmpty_native_withClose.snap b/.forge-snapshots/PositionManager_burn_nonEmpty_native_withClose.snap index 6c5691354..0933f7e68 100644 --- a/.forge-snapshots/PositionManager_burn_nonEmpty_native_withClose.snap +++ b/.forge-snapshots/PositionManager_burn_nonEmpty_native_withClose.snap @@ -1 +1 @@ -128040 \ No newline at end of file +127695 \ No newline at end of file diff --git a/.forge-snapshots/PositionManager_burn_nonEmpty_native_withTakePair.snap b/.forge-snapshots/PositionManager_burn_nonEmpty_native_withTakePair.snap index ae8deb172..71cf5daea 100644 --- a/.forge-snapshots/PositionManager_burn_nonEmpty_native_withTakePair.snap +++ b/.forge-snapshots/PositionManager_burn_nonEmpty_native_withTakePair.snap @@ -1 +1 @@ -127483 \ No newline at end of file +127137 \ No newline at end of file diff --git a/.forge-snapshots/PositionManager_burn_nonEmpty_withClose.snap b/.forge-snapshots/PositionManager_burn_nonEmpty_withClose.snap index 5080cb8cb..cd1707c04 100644 --- a/.forge-snapshots/PositionManager_burn_nonEmpty_withClose.snap +++ b/.forge-snapshots/PositionManager_burn_nonEmpty_withClose.snap @@ -1 +1 @@ -134956 \ No newline at end of file +134600 \ No newline at end of file diff --git a/.forge-snapshots/PositionManager_burn_nonEmpty_withTakePair.snap b/.forge-snapshots/PositionManager_burn_nonEmpty_withTakePair.snap index 988f465e4..eb98ee67a 100644 --- a/.forge-snapshots/PositionManager_burn_nonEmpty_withTakePair.snap +++ b/.forge-snapshots/PositionManager_burn_nonEmpty_withTakePair.snap @@ -1 +1 @@ -134398 \ No newline at end of file +134043 \ No newline at end of file diff --git a/.forge-snapshots/PositionManager_collect_native.snap b/.forge-snapshots/PositionManager_collect_native.snap index 462e130b2..dc9a2909b 100644 --- a/.forge-snapshots/PositionManager_collect_native.snap +++ b/.forge-snapshots/PositionManager_collect_native.snap @@ -1 +1 @@ -148090 \ No newline at end of file +147754 \ No newline at end of file diff --git a/.forge-snapshots/PositionManager_collect_sameRange.snap b/.forge-snapshots/PositionManager_collect_sameRange.snap index 846e8703d..65299bacc 100644 --- a/.forge-snapshots/PositionManager_collect_sameRange.snap +++ b/.forge-snapshots/PositionManager_collect_sameRange.snap @@ -1 +1 @@ -156734 \ No newline at end of file +156386 \ No newline at end of file diff --git a/.forge-snapshots/PositionManager_collect_withClose.snap b/.forge-snapshots/PositionManager_collect_withClose.snap index 846e8703d..65299bacc 100644 --- a/.forge-snapshots/PositionManager_collect_withClose.snap +++ b/.forge-snapshots/PositionManager_collect_withClose.snap @@ -1 +1 @@ -156734 \ No newline at end of file +156386 \ No newline at end of file diff --git a/.forge-snapshots/PositionManager_collect_withTakePair.snap b/.forge-snapshots/PositionManager_collect_withTakePair.snap index 0bc68a9bc..102c351d4 100644 --- a/.forge-snapshots/PositionManager_collect_withTakePair.snap +++ b/.forge-snapshots/PositionManager_collect_withTakePair.snap @@ -1 +1 @@ -156049 \ No newline at end of file +155701 \ No newline at end of file diff --git a/.forge-snapshots/PositionManager_decreaseLiquidity_native.snap b/.forge-snapshots/PositionManager_decreaseLiquidity_native.snap index 007b50643..1dcc58261 100644 --- a/.forge-snapshots/PositionManager_decreaseLiquidity_native.snap +++ b/.forge-snapshots/PositionManager_decreaseLiquidity_native.snap @@ -1 +1 @@ -114044 \ No newline at end of file +113699 \ No newline at end of file diff --git a/.forge-snapshots/PositionManager_decreaseLiquidity_withClose.snap b/.forge-snapshots/PositionManager_decreaseLiquidity_withClose.snap index 72a09ae97..db09cd2b3 100644 --- a/.forge-snapshots/PositionManager_decreaseLiquidity_withClose.snap +++ b/.forge-snapshots/PositionManager_decreaseLiquidity_withClose.snap @@ -1 +1 @@ -122399 \ No newline at end of file +121955 \ No newline at end of file diff --git a/.forge-snapshots/PositionManager_decreaseLiquidity_withTakePair.snap b/.forge-snapshots/PositionManager_decreaseLiquidity_withTakePair.snap index b69f5e9f7..1031870ba 100644 --- a/.forge-snapshots/PositionManager_decreaseLiquidity_withTakePair.snap +++ b/.forge-snapshots/PositionManager_decreaseLiquidity_withTakePair.snap @@ -1 +1 @@ -121714 \ No newline at end of file +121270 \ No newline at end of file diff --git a/.forge-snapshots/PositionManager_decrease_burnEmpty.snap b/.forge-snapshots/PositionManager_decrease_burnEmpty.snap index 621e8754a..7ede15068 100644 --- a/.forge-snapshots/PositionManager_decrease_burnEmpty.snap +++ b/.forge-snapshots/PositionManager_decrease_burnEmpty.snap @@ -1 +1 @@ -137873 \ No newline at end of file +137518 \ No newline at end of file diff --git a/.forge-snapshots/PositionManager_decrease_burnEmpty_native.snap b/.forge-snapshots/PositionManager_decrease_burnEmpty_native.snap index 8c826d744..dda288d0e 100644 --- a/.forge-snapshots/PositionManager_decrease_burnEmpty_native.snap +++ b/.forge-snapshots/PositionManager_decrease_burnEmpty_native.snap @@ -1 +1 @@ -130958 \ No newline at end of file +130612 \ No newline at end of file diff --git a/.forge-snapshots/PositionManager_decrease_sameRange_allLiquidity.snap b/.forge-snapshots/PositionManager_decrease_sameRange_allLiquidity.snap index 08fc8edf1..27292b82d 100644 --- a/.forge-snapshots/PositionManager_decrease_sameRange_allLiquidity.snap +++ b/.forge-snapshots/PositionManager_decrease_sameRange_allLiquidity.snap @@ -1 +1 @@ -135115 \ No newline at end of file +134671 \ No newline at end of file diff --git a/.forge-snapshots/PositionManager_decrease_take_take.snap b/.forge-snapshots/PositionManager_decrease_take_take.snap index a950af202..2d85dd7fc 100644 --- a/.forge-snapshots/PositionManager_decrease_take_take.snap +++ b/.forge-snapshots/PositionManager_decrease_take_take.snap @@ -1 +1 @@ -122956 \ No newline at end of file +122512 \ No newline at end of file diff --git a/.forge-snapshots/PositionManager_increaseLiquidity_erc20_withClose.snap b/.forge-snapshots/PositionManager_increaseLiquidity_erc20_withClose.snap index c1bfc8497..f3dd3d052 100644 --- a/.forge-snapshots/PositionManager_increaseLiquidity_erc20_withClose.snap +++ b/.forge-snapshots/PositionManager_increaseLiquidity_erc20_withClose.snap @@ -1 +1 @@ -161238 \ No newline at end of file +160674 \ No newline at end of file diff --git a/.forge-snapshots/PositionManager_increaseLiquidity_erc20_withSettlePair.snap b/.forge-snapshots/PositionManager_increaseLiquidity_erc20_withSettlePair.snap index 9a8626bd1..953e5e29e 100644 --- a/.forge-snapshots/PositionManager_increaseLiquidity_erc20_withSettlePair.snap +++ b/.forge-snapshots/PositionManager_increaseLiquidity_erc20_withSettlePair.snap @@ -1 +1 @@ -160149 \ No newline at end of file +159585 \ No newline at end of file diff --git a/.forge-snapshots/PositionManager_increaseLiquidity_native.snap b/.forge-snapshots/PositionManager_increaseLiquidity_native.snap index 27adf03c8..980f3216d 100644 --- a/.forge-snapshots/PositionManager_increaseLiquidity_native.snap +++ b/.forge-snapshots/PositionManager_increaseLiquidity_native.snap @@ -1 +1 @@ -144034 \ No newline at end of file +143554 \ No newline at end of file diff --git a/.forge-snapshots/PositionManager_increase_autocompoundExactUnclaimedFees.snap b/.forge-snapshots/PositionManager_increase_autocompoundExactUnclaimedFees.snap index 560ba5fe0..806d71d2c 100644 --- a/.forge-snapshots/PositionManager_increase_autocompoundExactUnclaimedFees.snap +++ b/.forge-snapshots/PositionManager_increase_autocompoundExactUnclaimedFees.snap @@ -1 +1 @@ -138481 \ No newline at end of file +138253 \ No newline at end of file diff --git a/.forge-snapshots/PositionManager_increase_autocompoundExcessFeesCredit.snap b/.forge-snapshots/PositionManager_increase_autocompoundExcessFeesCredit.snap index 52d7b3932..0a569bb9b 100644 --- a/.forge-snapshots/PositionManager_increase_autocompoundExcessFeesCredit.snap +++ b/.forge-snapshots/PositionManager_increase_autocompoundExcessFeesCredit.snap @@ -1 +1 @@ -180059 \ No newline at end of file +179615 \ No newline at end of file diff --git a/.forge-snapshots/PositionManager_increase_autocompound_clearExcess.snap b/.forge-snapshots/PositionManager_increase_autocompound_clearExcess.snap index db428c346..0c60d6563 100644 --- a/.forge-snapshots/PositionManager_increase_autocompound_clearExcess.snap +++ b/.forge-snapshots/PositionManager_increase_autocompound_clearExcess.snap @@ -1 +1 @@ -149905 \ No newline at end of file +149533 \ No newline at end of file diff --git a/.forge-snapshots/PositionManager_mint_native.snap b/.forge-snapshots/PositionManager_mint_native.snap index 5e111f3da..5b862083e 100644 --- a/.forge-snapshots/PositionManager_mint_native.snap +++ b/.forge-snapshots/PositionManager_mint_native.snap @@ -1 +1 @@ -368030 \ No newline at end of file +367550 \ No newline at end of file diff --git a/.forge-snapshots/PositionManager_mint_nativeWithSweep_withClose.snap b/.forge-snapshots/PositionManager_mint_nativeWithSweep_withClose.snap index ebf4737e3..92ac683a4 100644 --- a/.forge-snapshots/PositionManager_mint_nativeWithSweep_withClose.snap +++ b/.forge-snapshots/PositionManager_mint_nativeWithSweep_withClose.snap @@ -1 +1 @@ -376633 \ No newline at end of file +376153 \ No newline at end of file diff --git a/.forge-snapshots/PositionManager_mint_nativeWithSweep_withSettlePair.snap b/.forge-snapshots/PositionManager_mint_nativeWithSweep_withSettlePair.snap index 432f0fa5d..4f3f349a7 100644 --- a/.forge-snapshots/PositionManager_mint_nativeWithSweep_withSettlePair.snap +++ b/.forge-snapshots/PositionManager_mint_nativeWithSweep_withSettlePair.snap @@ -1 +1 @@ -375828 \ No newline at end of file +375348 \ No newline at end of file diff --git a/.forge-snapshots/PositionManager_mint_onSameTickLower.snap b/.forge-snapshots/PositionManager_mint_onSameTickLower.snap index c252cf5f9..8940ee8c2 100644 --- a/.forge-snapshots/PositionManager_mint_onSameTickLower.snap +++ b/.forge-snapshots/PositionManager_mint_onSameTickLower.snap @@ -1 +1 @@ -319862 \ No newline at end of file +319298 \ No newline at end of file diff --git a/.forge-snapshots/PositionManager_mint_onSameTickUpper.snap b/.forge-snapshots/PositionManager_mint_onSameTickUpper.snap index d2aeb72e3..9c1fb90c6 100644 --- a/.forge-snapshots/PositionManager_mint_onSameTickUpper.snap +++ b/.forge-snapshots/PositionManager_mint_onSameTickUpper.snap @@ -1 +1 @@ -320504 \ No newline at end of file +319940 \ No newline at end of file diff --git a/.forge-snapshots/PositionManager_mint_sameRange.snap b/.forge-snapshots/PositionManager_mint_sameRange.snap index 709a34c4a..49d810552 100644 --- a/.forge-snapshots/PositionManager_mint_sameRange.snap +++ b/.forge-snapshots/PositionManager_mint_sameRange.snap @@ -1 +1 @@ -246086 \ No newline at end of file +245522 \ No newline at end of file diff --git a/.forge-snapshots/PositionManager_mint_settleWithBalance_sweep.snap b/.forge-snapshots/PositionManager_mint_settleWithBalance_sweep.snap index 4808ff68c..f9b38bb46 100644 --- a/.forge-snapshots/PositionManager_mint_settleWithBalance_sweep.snap +++ b/.forge-snapshots/PositionManager_mint_settleWithBalance_sweep.snap @@ -1 +1 @@ -421324 \ No newline at end of file +420760 \ No newline at end of file diff --git a/.forge-snapshots/PositionManager_mint_warmedPool_differentRange.snap b/.forge-snapshots/PositionManager_mint_warmedPool_differentRange.snap index 9c4d68b65..2446b49ea 100644 --- a/.forge-snapshots/PositionManager_mint_warmedPool_differentRange.snap +++ b/.forge-snapshots/PositionManager_mint_warmedPool_differentRange.snap @@ -1 +1 @@ -325880 \ No newline at end of file +325316 \ No newline at end of file diff --git a/.forge-snapshots/PositionManager_mint_withClose.snap b/.forge-snapshots/PositionManager_mint_withClose.snap index 00b56a2a3..b5961e4ef 100644 --- a/.forge-snapshots/PositionManager_mint_withClose.snap +++ b/.forge-snapshots/PositionManager_mint_withClose.snap @@ -1 +1 @@ -422474 \ No newline at end of file +421910 \ No newline at end of file diff --git a/.forge-snapshots/PositionManager_mint_withSettlePair.snap b/.forge-snapshots/PositionManager_mint_withSettlePair.snap index 8d42bdac1..7b363ec27 100644 --- a/.forge-snapshots/PositionManager_mint_withSettlePair.snap +++ b/.forge-snapshots/PositionManager_mint_withSettlePair.snap @@ -1 +1 @@ -421503 \ No newline at end of file +420939 \ No newline at end of file diff --git a/.forge-snapshots/PositionManager_multicall_initialize_mint.snap b/.forge-snapshots/PositionManager_multicall_initialize_mint.snap index b8f3ed012..16b8c7ae5 100644 --- a/.forge-snapshots/PositionManager_multicall_initialize_mint.snap +++ b/.forge-snapshots/PositionManager_multicall_initialize_mint.snap @@ -1 +1 @@ -459041 \ No newline at end of file +458237 \ No newline at end of file diff --git a/.forge-snapshots/Quoter_exactInputSingle_oneForZero_multiplePositions.snap b/.forge-snapshots/Quoter_exactInputSingle_oneForZero_multiplePositions.snap index fc71cc7d2..ddd017c32 100644 --- a/.forge-snapshots/Quoter_exactInputSingle_oneForZero_multiplePositions.snap +++ b/.forge-snapshots/Quoter_exactInputSingle_oneForZero_multiplePositions.snap @@ -1 +1 @@ -146790 \ No newline at end of file +145902 \ No newline at end of file diff --git a/.forge-snapshots/Quoter_exactInputSingle_zeroForOne_multiplePositions.snap b/.forge-snapshots/Quoter_exactInputSingle_zeroForOne_multiplePositions.snap index 9f344ee42..6bfe32457 100644 --- a/.forge-snapshots/Quoter_exactInputSingle_zeroForOne_multiplePositions.snap +++ b/.forge-snapshots/Quoter_exactInputSingle_zeroForOne_multiplePositions.snap @@ -1 +1 @@ -153173 \ No newline at end of file +152117 \ No newline at end of file diff --git a/.forge-snapshots/Quoter_exactOutputSingle_oneForZero.snap b/.forge-snapshots/Quoter_exactOutputSingle_oneForZero.snap index 33b96a518..0fddaa34a 100644 --- a/.forge-snapshots/Quoter_exactOutputSingle_oneForZero.snap +++ b/.forge-snapshots/Quoter_exactOutputSingle_oneForZero.snap @@ -1 +1 @@ -79795 \ No newline at end of file +79267 \ No newline at end of file diff --git a/.forge-snapshots/Quoter_exactOutputSingle_zeroForOne.snap b/.forge-snapshots/Quoter_exactOutputSingle_zeroForOne.snap index eff8b5788..80c70ad9b 100644 --- a/.forge-snapshots/Quoter_exactOutputSingle_zeroForOne.snap +++ b/.forge-snapshots/Quoter_exactOutputSingle_zeroForOne.snap @@ -1 +1 @@ -85220 \ No newline at end of file +84512 \ No newline at end of file diff --git a/.forge-snapshots/Quoter_quoteExactInput_oneHop_1TickLoaded.snap b/.forge-snapshots/Quoter_quoteExactInput_oneHop_1TickLoaded.snap index 473cbcfb5..535f80cb8 100644 --- a/.forge-snapshots/Quoter_quoteExactInput_oneHop_1TickLoaded.snap +++ b/.forge-snapshots/Quoter_quoteExactInput_oneHop_1TickLoaded.snap @@ -1 +1 @@ -123604 \ No newline at end of file +122728 \ No newline at end of file diff --git a/.forge-snapshots/Quoter_quoteExactInput_oneHop_initializedAfter.snap b/.forge-snapshots/Quoter_quoteExactInput_oneHop_initializedAfter.snap index fbabcd0c8..9e2f18c9f 100644 --- a/.forge-snapshots/Quoter_quoteExactInput_oneHop_initializedAfter.snap +++ b/.forge-snapshots/Quoter_quoteExactInput_oneHop_initializedAfter.snap @@ -1 +1 @@ -148251 \ No newline at end of file +147363 \ No newline at end of file diff --git a/.forge-snapshots/Quoter_quoteExactInput_oneHop_startingInitialized.snap b/.forge-snapshots/Quoter_quoteExactInput_oneHop_startingInitialized.snap index c99fa7ac8..2b5d25c12 100644 --- a/.forge-snapshots/Quoter_quoteExactInput_oneHop_startingInitialized.snap +++ b/.forge-snapshots/Quoter_quoteExactInput_oneHop_startingInitialized.snap @@ -1 +1 @@ -81166 \ No newline at end of file +80638 \ No newline at end of file diff --git a/.forge-snapshots/Quoter_quoteExactInput_twoHops.snap b/.forge-snapshots/Quoter_quoteExactInput_twoHops.snap index 2c8b0ba6d..4a002eafd 100644 --- a/.forge-snapshots/Quoter_quoteExactInput_twoHops.snap +++ b/.forge-snapshots/Quoter_quoteExactInput_twoHops.snap @@ -1 +1 @@ -206526 \ No newline at end of file +204942 \ No newline at end of file diff --git a/.forge-snapshots/Quoter_quoteExactOutput_oneHop_1TickLoaded.snap b/.forge-snapshots/Quoter_quoteExactOutput_oneHop_1TickLoaded.snap index e3f370cb4..6d7d1854d 100644 --- a/.forge-snapshots/Quoter_quoteExactOutput_oneHop_1TickLoaded.snap +++ b/.forge-snapshots/Quoter_quoteExactOutput_oneHop_1TickLoaded.snap @@ -1 +1 @@ -123112 \ No newline at end of file +122224 \ No newline at end of file diff --git a/.forge-snapshots/Quoter_quoteExactOutput_oneHop_2TicksLoaded.snap b/.forge-snapshots/Quoter_quoteExactOutput_oneHop_2TicksLoaded.snap index 688bf821b..141d1a3ed 100644 --- a/.forge-snapshots/Quoter_quoteExactOutput_oneHop_2TicksLoaded.snap +++ b/.forge-snapshots/Quoter_quoteExactOutput_oneHop_2TicksLoaded.snap @@ -1 +1 @@ -153947 \ No newline at end of file +152879 \ No newline at end of file diff --git a/.forge-snapshots/Quoter_quoteExactOutput_oneHop_initializedAfter.snap b/.forge-snapshots/Quoter_quoteExactOutput_oneHop_initializedAfter.snap index 2d3a1e066..ce1e06318 100644 --- a/.forge-snapshots/Quoter_quoteExactOutput_oneHop_initializedAfter.snap +++ b/.forge-snapshots/Quoter_quoteExactOutput_oneHop_initializedAfter.snap @@ -1 +1 @@ -123139 \ No newline at end of file +122251 \ No newline at end of file diff --git a/.forge-snapshots/Quoter_quoteExactOutput_oneHop_startingInitialized.snap b/.forge-snapshots/Quoter_quoteExactOutput_oneHop_startingInitialized.snap index 7d711fb1d..44946b692 100644 --- a/.forge-snapshots/Quoter_quoteExactOutput_oneHop_startingInitialized.snap +++ b/.forge-snapshots/Quoter_quoteExactOutput_oneHop_startingInitialized.snap @@ -1 +1 @@ -99253 \ No newline at end of file +98545 \ No newline at end of file diff --git a/.forge-snapshots/Quoter_quoteExactOutput_twoHops.snap b/.forge-snapshots/Quoter_quoteExactOutput_twoHops.snap index f15d14b41..15336cc2d 100644 --- a/.forge-snapshots/Quoter_quoteExactOutput_twoHops.snap +++ b/.forge-snapshots/Quoter_quoteExactOutput_twoHops.snap @@ -1 +1 @@ -206266 \ No newline at end of file +204670 \ No newline at end of file diff --git a/.forge-snapshots/V4Router_ExactIn1Hop_nativeIn.snap b/.forge-snapshots/V4Router_ExactIn1Hop_nativeIn.snap index 4472479bf..e188f56da 100644 --- a/.forge-snapshots/V4Router_ExactIn1Hop_nativeIn.snap +++ b/.forge-snapshots/V4Router_ExactIn1Hop_nativeIn.snap @@ -1 +1 @@ -122493 \ No newline at end of file +121653 \ No newline at end of file diff --git a/.forge-snapshots/V4Router_ExactIn1Hop_nativeOut.snap b/.forge-snapshots/V4Router_ExactIn1Hop_nativeOut.snap index 823bd6a54..e7e76c10c 100644 --- a/.forge-snapshots/V4Router_ExactIn1Hop_nativeOut.snap +++ b/.forge-snapshots/V4Router_ExactIn1Hop_nativeOut.snap @@ -1 +1 @@ -120863 \ No newline at end of file +120119 \ No newline at end of file diff --git a/.forge-snapshots/V4Router_ExactIn1Hop_oneForZero.snap b/.forge-snapshots/V4Router_ExactIn1Hop_oneForZero.snap index 63895f7c7..527b24a3a 100644 --- a/.forge-snapshots/V4Router_ExactIn1Hop_oneForZero.snap +++ b/.forge-snapshots/V4Router_ExactIn1Hop_oneForZero.snap @@ -1 +1 @@ -129747 \ No newline at end of file +128991 \ No newline at end of file diff --git a/.forge-snapshots/V4Router_ExactIn1Hop_zeroForOne.snap b/.forge-snapshots/V4Router_ExactIn1Hop_zeroForOne.snap index ce2fd4e7c..1fcdfdb7b 100644 --- a/.forge-snapshots/V4Router_ExactIn1Hop_zeroForOne.snap +++ b/.forge-snapshots/V4Router_ExactIn1Hop_zeroForOne.snap @@ -1 +1 @@ -136441 \ No newline at end of file +135517 \ No newline at end of file diff --git a/.forge-snapshots/V4Router_ExactIn2Hops.snap b/.forge-snapshots/V4Router_ExactIn2Hops.snap index 4573fd600..022fe02b0 100644 --- a/.forge-snapshots/V4Router_ExactIn2Hops.snap +++ b/.forge-snapshots/V4Router_ExactIn2Hops.snap @@ -1 +1 @@ -194463 \ No newline at end of file +192843 \ No newline at end of file diff --git a/.forge-snapshots/V4Router_ExactIn2Hops_nativeIn.snap b/.forge-snapshots/V4Router_ExactIn2Hops_nativeIn.snap index 2460e81e5..6f68c80eb 100644 --- a/.forge-snapshots/V4Router_ExactIn2Hops_nativeIn.snap +++ b/.forge-snapshots/V4Router_ExactIn2Hops_nativeIn.snap @@ -1 +1 @@ -180515 \ No newline at end of file +178979 \ No newline at end of file diff --git a/.forge-snapshots/V4Router_ExactIn3Hops.snap b/.forge-snapshots/V4Router_ExactIn3Hops.snap index 3bec83314..72c812f8c 100644 --- a/.forge-snapshots/V4Router_ExactIn3Hops.snap +++ b/.forge-snapshots/V4Router_ExactIn3Hops.snap @@ -1 +1 @@ -252534 \ No newline at end of file +250218 \ No newline at end of file diff --git a/.forge-snapshots/V4Router_ExactIn3Hops_nativeIn.snap b/.forge-snapshots/V4Router_ExactIn3Hops_nativeIn.snap index bc2ca05ea..fea73fd7e 100644 --- a/.forge-snapshots/V4Router_ExactIn3Hops_nativeIn.snap +++ b/.forge-snapshots/V4Router_ExactIn3Hops_nativeIn.snap @@ -1 +1 @@ -238586 \ No newline at end of file +236354 \ No newline at end of file diff --git a/.forge-snapshots/V4Router_ExactInputSingle.snap b/.forge-snapshots/V4Router_ExactInputSingle.snap index 880d383db..e8d120418 100644 --- a/.forge-snapshots/V4Router_ExactInputSingle.snap +++ b/.forge-snapshots/V4Router_ExactInputSingle.snap @@ -1 +1 @@ -134925 \ No newline at end of file +134001 \ No newline at end of file diff --git a/.forge-snapshots/V4Router_ExactInputSingle_nativeIn.snap b/.forge-snapshots/V4Router_ExactInputSingle_nativeIn.snap index 169567949..182d8da2a 100644 --- a/.forge-snapshots/V4Router_ExactInputSingle_nativeIn.snap +++ b/.forge-snapshots/V4Router_ExactInputSingle_nativeIn.snap @@ -1 +1 @@ -120977 \ No newline at end of file +120137 \ No newline at end of file diff --git a/.forge-snapshots/V4Router_ExactInputSingle_nativeOut.snap b/.forge-snapshots/V4Router_ExactInputSingle_nativeOut.snap index f1ab7e9d6..9bb44eced 100644 --- a/.forge-snapshots/V4Router_ExactInputSingle_nativeOut.snap +++ b/.forge-snapshots/V4Router_ExactInputSingle_nativeOut.snap @@ -1 +1 @@ -119325 \ No newline at end of file +118581 \ No newline at end of file diff --git a/.forge-snapshots/V4Router_ExactOut1Hop_nativeIn_sweepETH.snap b/.forge-snapshots/V4Router_ExactOut1Hop_nativeIn_sweepETH.snap index 8613f6d91..82db8f7b1 100644 --- a/.forge-snapshots/V4Router_ExactOut1Hop_nativeIn_sweepETH.snap +++ b/.forge-snapshots/V4Router_ExactOut1Hop_nativeIn_sweepETH.snap @@ -1 +1 @@ -128792 \ No newline at end of file +127940 \ No newline at end of file diff --git a/.forge-snapshots/V4Router_ExactOut1Hop_nativeOut.snap b/.forge-snapshots/V4Router_ExactOut1Hop_nativeOut.snap index 7470f11ae..96c04d44d 100644 --- a/.forge-snapshots/V4Router_ExactOut1Hop_nativeOut.snap +++ b/.forge-snapshots/V4Router_ExactOut1Hop_nativeOut.snap @@ -1 +1 @@ -122073 \ No newline at end of file +121329 \ No newline at end of file diff --git a/.forge-snapshots/V4Router_ExactOut1Hop_oneForZero.snap b/.forge-snapshots/V4Router_ExactOut1Hop_oneForZero.snap index edf4eb7ad..59010c68f 100644 --- a/.forge-snapshots/V4Router_ExactOut1Hop_oneForZero.snap +++ b/.forge-snapshots/V4Router_ExactOut1Hop_oneForZero.snap @@ -1 +1 @@ -130957 \ No newline at end of file +130201 \ No newline at end of file diff --git a/.forge-snapshots/V4Router_ExactOut1Hop_zeroForOne.snap b/.forge-snapshots/V4Router_ExactOut1Hop_zeroForOne.snap index b98846f83..7e653318c 100644 --- a/.forge-snapshots/V4Router_ExactOut1Hop_zeroForOne.snap +++ b/.forge-snapshots/V4Router_ExactOut1Hop_zeroForOne.snap @@ -1 +1 @@ -135794 \ No newline at end of file +134858 \ No newline at end of file diff --git a/.forge-snapshots/V4Router_ExactOut2Hops.snap b/.forge-snapshots/V4Router_ExactOut2Hops.snap index 481687037..bc92fcdbe 100644 --- a/.forge-snapshots/V4Router_ExactOut2Hops.snap +++ b/.forge-snapshots/V4Router_ExactOut2Hops.snap @@ -1 +1 @@ -192935 \ No newline at end of file +191291 \ No newline at end of file diff --git a/.forge-snapshots/V4Router_ExactOut2Hops_nativeIn.snap b/.forge-snapshots/V4Router_ExactOut2Hops_nativeIn.snap index a12f1f80e..6c96d9097 100644 --- a/.forge-snapshots/V4Router_ExactOut2Hops_nativeIn.snap +++ b/.forge-snapshots/V4Router_ExactOut2Hops_nativeIn.snap @@ -1 +1 @@ -185933 \ No newline at end of file +184373 \ No newline at end of file diff --git a/.forge-snapshots/V4Router_ExactOut3Hops.snap b/.forge-snapshots/V4Router_ExactOut3Hops.snap index d0730d4c3..32a25024e 100644 --- a/.forge-snapshots/V4Router_ExactOut3Hops.snap +++ b/.forge-snapshots/V4Router_ExactOut3Hops.snap @@ -1 +1 @@ -250140 \ No newline at end of file +247788 \ No newline at end of file diff --git a/.forge-snapshots/V4Router_ExactOut3Hops_nativeIn.snap b/.forge-snapshots/V4Router_ExactOut3Hops_nativeIn.snap index e646399e4..42f6448d7 100644 --- a/.forge-snapshots/V4Router_ExactOut3Hops_nativeIn.snap +++ b/.forge-snapshots/V4Router_ExactOut3Hops_nativeIn.snap @@ -1 +1 @@ -243138 \ No newline at end of file +240870 \ No newline at end of file diff --git a/.forge-snapshots/V4Router_ExactOut3Hops_nativeOut.snap b/.forge-snapshots/V4Router_ExactOut3Hops_nativeOut.snap index 37979b28c..acd8db05d 100644 --- a/.forge-snapshots/V4Router_ExactOut3Hops_nativeOut.snap +++ b/.forge-snapshots/V4Router_ExactOut3Hops_nativeOut.snap @@ -1 +1 @@ -226743 \ No newline at end of file +224943 \ No newline at end of file diff --git a/.forge-snapshots/V4Router_ExactOutputSingle.snap b/.forge-snapshots/V4Router_ExactOutputSingle.snap index eaae5c0eb..410b941d2 100644 --- a/.forge-snapshots/V4Router_ExactOutputSingle.snap +++ b/.forge-snapshots/V4Router_ExactOutputSingle.snap @@ -1 +1 @@ -134273 \ No newline at end of file +133337 \ No newline at end of file diff --git a/.forge-snapshots/V4Router_ExactOutputSingle_nativeIn_sweepETH.snap b/.forge-snapshots/V4Router_ExactOutputSingle_nativeIn_sweepETH.snap index 638e21611..cfd3c90d9 100644 --- a/.forge-snapshots/V4Router_ExactOutputSingle_nativeIn_sweepETH.snap +++ b/.forge-snapshots/V4Router_ExactOutputSingle_nativeIn_sweepETH.snap @@ -1 +1 @@ -127271 \ No newline at end of file +126419 \ No newline at end of file diff --git a/.forge-snapshots/V4Router_ExactOutputSingle_nativeOut.snap b/.forge-snapshots/V4Router_ExactOutputSingle_nativeOut.snap index a0359cc47..362e3fea2 100644 --- a/.forge-snapshots/V4Router_ExactOutputSingle_nativeOut.snap +++ b/.forge-snapshots/V4Router_ExactOutputSingle_nativeOut.snap @@ -1 +1 @@ -120565 \ No newline at end of file +119821 \ No newline at end of file diff --git a/foundry.toml b/foundry.toml index 993837a64..a77b97d55 100644 --- a/foundry.toml +++ b/foundry.toml @@ -1,7 +1,7 @@ [profile.default] out = 'foundry-out' solc_version = '0.8.26' -optimizer_runs = 30000 +optimizer_runs = 44444444 via_ir = true ffi = true fs_permissions = [{ access = "read-write", path = ".forge-snapshots/" }, { access = "read", path = "foundry-out/" }] @@ -11,11 +11,13 @@ fuzz_runs = 10_000 bytecode_hash = "none" additional_compiler_profiles = [ + { name = "posm", via_ir = true, optimizer_runs = 30000 }, { name = "descriptor", via_ir = true, optimizer_runs = 1 }, { name = "test", via_ir = false } ] compilation_restrictions = [ + { paths = "src/PositionManager.sol", optimizer_runs = 30000 }, { paths = "src/PositionDescriptor.sol", optimizer_runs = 1 }, { paths = "test/**", via_ir = false } ] From 71302ce03b4dda2d5cf17b88f37efb6ae13614c2 Mon Sep 17 00:00:00 2001 From: gretzke Date: Wed, 27 Nov 2024 23:27:09 +0100 Subject: [PATCH 14/20] Add state view interface --- script/DeployPosm.s.sol | 1 - script/DeployStateView.s.sol | 4 +- src/interfaces/IStateView.sol | 133 ++++++++++++++++++++++++++++++++++ src/lens/StateView.sol | 107 ++++----------------------- test/StateViewTest.t.sol | 6 +- test/shared/Deploy.sol | 7 +- 6 files changed, 153 insertions(+), 105 deletions(-) create mode 100644 src/interfaces/IStateView.sol diff --git a/script/DeployPosm.s.sol b/script/DeployPosm.s.sol index e9300630b..006ce4f67 100644 --- a/script/DeployPosm.s.sol +++ b/script/DeployPosm.s.sol @@ -5,7 +5,6 @@ import "forge-std/console2.sol"; import "forge-std/Script.sol"; import {IPoolManager} from "@uniswap/v4-core/src/interfaces/IPoolManager.sol"; -import {StateView} from "../src/lens/StateView.sol"; import {IAllowanceTransfer} from "permit2/src/interfaces/IAllowanceTransfer.sol"; import {Deploy, IPositionDescriptor, IPositionManager} from "../test/shared/Deploy.sol"; import {IWETH9} from "../src/interfaces/external/IWETH9.sol"; diff --git a/script/DeployStateView.s.sol b/script/DeployStateView.s.sol index 77f400000..0e85c4720 100644 --- a/script/DeployStateView.s.sol +++ b/script/DeployStateView.s.sol @@ -5,12 +5,12 @@ import "forge-std/console2.sol"; import "forge-std/Script.sol"; import {IPoolManager} from "@uniswap/v4-core/src/interfaces/IPoolManager.sol"; -import {Deploy, StateView} from "../test/shared/Deploy.sol"; +import {Deploy, IStateView} from "../test/shared/Deploy.sol"; contract DeployStateView is Script { function setUp() public {} - function run(address poolManager) public returns (StateView state) { + function run(address poolManager) public returns (IStateView state) { vm.startBroadcast(); // forge script --broadcast --sig 'run(address)' --rpc-url --private-key --verify script/DeployStateView.s.sol:DeployStateView diff --git a/src/interfaces/IStateView.sol b/src/interfaces/IStateView.sol new file mode 100644 index 000000000..c83b7de6c --- /dev/null +++ b/src/interfaces/IStateView.sol @@ -0,0 +1,133 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; + +import {StateLibrary} from "@uniswap/v4-core/src/libraries/StateLibrary.sol"; +import {PoolId} from "@uniswap/v4-core/src/types/PoolId.sol"; +import {IPoolManager} from "@uniswap/v4-core/src/interfaces/IPoolManager.sol"; +import {Position} from "@uniswap/v4-core/src/libraries/Position.sol"; +import {IImmutableState} from "../interfaces/IImmutableState.sol"; + +/// @title StateView Interface +/// @notice A view only contract wrapping the StateLibrary.sol library for reading storage in v4-core. +interface IStateView is IImmutableState { + /// @notice Get Slot0 of the pool: sqrtPriceX96, tick, protocolFee, lpFee + /// @dev Corresponds to pools[poolId].slot0 + /// @param poolId The ID of the pool. + /// @return sqrtPriceX96 The square root of the price of the pool, in Q96 precision. + /// @return tick The current tick of the pool. + /// @return protocolFee The protocol fee of the pool. + /// @return lpFee The swap fee of the pool. + function getSlot0(PoolId poolId) + external + view + returns (uint160 sqrtPriceX96, int24 tick, uint24 protocolFee, uint24 lpFee); + + /// @notice Retrieves the tick information of a pool at a specific tick. + /// @dev Corresponds to pools[poolId].ticks[tick] + /// @param poolId The ID of the pool. + /// @param tick The tick to retrieve information for. + /// @return liquidityGross The total position liquidity that references this tick + /// @return liquidityNet The amount of net liquidity added (subtracted) when tick is crossed from left to right (right to left) + /// @return feeGrowthOutside0X128 fee growth per unit of liquidity on the _other_ side of this tick (relative to the current tick) + /// @return feeGrowthOutside1X128 fee growth per unit of liquidity on the _other_ side of this tick (relative to the current tick) + function getTickInfo(PoolId poolId, int24 tick) + external + view + returns ( + uint128 liquidityGross, + int128 liquidityNet, + uint256 feeGrowthOutside0X128, + uint256 feeGrowthOutside1X128 + ); + + /// @notice Retrieves the liquidity information of a pool at a specific tick. + /// @dev Corresponds to pools[poolId].ticks[tick].liquidityGross and pools[poolId].ticks[tick].liquidityNet. A more gas efficient version of getTickInfo + /// @param poolId The ID of the pool. + /// @param tick The tick to retrieve liquidity for. + /// @return liquidityGross The total position liquidity that references this tick + /// @return liquidityNet The amount of net liquidity added (subtracted) when tick is crossed from left to right (right to left) + function getTickLiquidity(PoolId poolId, int24 tick) + external + view + returns (uint128 liquidityGross, int128 liquidityNet); + + /// @notice Retrieves the fee growth outside a tick range of a pool + /// @dev Corresponds to pools[poolId].ticks[tick].feeGrowthOutside0X128 and pools[poolId].ticks[tick].feeGrowthOutside1X128. A more gas efficient version of getTickInfo + /// @param poolId The ID of the pool. + /// @param tick The tick to retrieve fee growth for. + /// @return feeGrowthOutside0X128 fee growth per unit of liquidity on the _other_ side of this tick (relative to the current tick) + /// @return feeGrowthOutside1X128 fee growth per unit of liquidity on the _other_ side of this tick (relative to the current tick) + function getTickFeeGrowthOutside(PoolId poolId, int24 tick) + external + view + returns (uint256 feeGrowthOutside0X128, uint256 feeGrowthOutside1X128); + + /// @notice Retrieves the global fee growth of a pool. + /// @dev Corresponds to pools[poolId].feeGrowthGlobal0X128 and pools[poolId].feeGrowthGlobal1X128 + /// @param poolId The ID of the pool. + /// @return feeGrowthGlobal0 The global fee growth for token0. + /// @return feeGrowthGlobal1 The global fee growth for token1. + function getFeeGrowthGlobals(PoolId poolId) + external + view + returns (uint256 feeGrowthGlobal0, uint256 feeGrowthGlobal1); + + /// @notice Retrieves the total liquidity of a pool. + /// @dev Corresponds to pools[poolId].liquidity + /// @param poolId The ID of the pool. + /// @return liquidity The liquidity of the pool. + function getLiquidity(PoolId poolId) external view returns (uint128 liquidity); + + /// @notice Retrieves the tick bitmap of a pool at a specific tick. + /// @dev Corresponds to pools[poolId].tickBitmap[tick] + /// @param poolId The ID of the pool. + /// @param tick The tick to retrieve the bitmap for. + /// @return tickBitmap The bitmap of the tick. + function getTickBitmap(PoolId poolId, int16 tick) external view returns (uint256 tickBitmap); + + /// @notice Retrieves the position info without needing to calculate the `positionId`. + /// @dev Corresponds to pools[poolId].positions[positionId] + /// @param poolId The ID of the pool. + /// @param owner The owner of the liquidity position. + /// @param tickLower The lower tick of the liquidity range. + /// @param tickUpper The upper tick of the liquidity range. + /// @param salt The bytes32 randomness to further distinguish position state. + /// @return liquidity The liquidity of the position. + /// @return feeGrowthInside0LastX128 The fee growth inside the position for token0. + /// @return feeGrowthInside1LastX128 The fee growth inside the position for token1. + function getPositionInfo(PoolId poolId, address owner, int24 tickLower, int24 tickUpper, bytes32 salt) + external + view + returns (uint128 liquidity, uint256 feeGrowthInside0LastX128, uint256 feeGrowthInside1LastX128); + + /// @notice Retrieves the position information of a pool at a specific position ID. + /// @dev Corresponds to pools[poolId].positions[positionId] + /// @param poolId The ID of the pool. + /// @param positionId The ID of the position. + /// @return liquidity The liquidity of the position. + /// @return feeGrowthInside0LastX128 The fee growth inside the position for token0. + /// @return feeGrowthInside1LastX128 The fee growth inside the position for token1. + function getPositionInfo(PoolId poolId, bytes32 positionId) + external + view + returns (uint128 liquidity, uint256 feeGrowthInside0LastX128, uint256 feeGrowthInside1LastX128); + + /// @notice Retrieves the liquidity of a position. + /// @dev Corresponds to pools[poolId].positions[positionId].liquidity. More gas efficient for just retrieving liquidity as compared to getPositionInfo + /// @param poolId The ID of the pool. + /// @param positionId The ID of the position. + /// @return liquidity The liquidity of the position. + function getPositionLiquidity(PoolId poolId, bytes32 positionId) external view returns (uint128 liquidity); + + /// @notice Calculate the fee growth inside a tick range of a pool + /// @dev pools[poolId].feeGrowthInside0LastX128 in Position.Info is cached and can become stale. This function will calculate the up to date feeGrowthInside + /// @param poolId The ID of the pool. + /// @param tickLower The lower tick of the range. + /// @param tickUpper The upper tick of the range. + /// @return feeGrowthInside0X128 The fee growth inside the tick range for token0. + /// @return feeGrowthInside1X128 The fee growth inside the tick range for token1. + function getFeeGrowthInside(PoolId poolId, int24 tickLower, int24 tickUpper) + external + view + returns (uint256 feeGrowthInside0X128, uint256 feeGrowthInside1X128); +} diff --git a/src/lens/StateView.sol b/src/lens/StateView.sol index 6527d2f72..e3894c194 100644 --- a/src/lens/StateView.sol +++ b/src/lens/StateView.sol @@ -5,24 +5,16 @@ import {StateLibrary} from "@uniswap/v4-core/src/libraries/StateLibrary.sol"; import {PoolId} from "@uniswap/v4-core/src/types/PoolId.sol"; import {IPoolManager} from "@uniswap/v4-core/src/interfaces/IPoolManager.sol"; import {Position} from "@uniswap/v4-core/src/libraries/Position.sol"; - import {ImmutableState} from "../base/ImmutableState.sol"; +import {IStateView} from "../interfaces/IStateView.sol"; /// @notice A view only contract wrapping the StateLibrary.sol library for reading storage in v4-core. -contract StateView is ImmutableState { +contract StateView is ImmutableState, IStateView { using StateLibrary for IPoolManager; constructor(IPoolManager _poolManager) ImmutableState(_poolManager) {} - /** - * @notice Get Slot0 of the pool: sqrtPriceX96, tick, protocolFee, lpFee - * @dev Corresponds to pools[poolId].slot0 - * @param poolId The ID of the pool. - * @return sqrtPriceX96 The square root of the price of the pool, in Q96 precision. - * @return tick The current tick of the pool. - * @return protocolFee The protocol fee of the pool. - * @return lpFee The swap fee of the pool. - */ + /// @inheritdoc IStateView function getSlot0(PoolId poolId) external view @@ -31,16 +23,7 @@ contract StateView is ImmutableState { return poolManager.getSlot0(poolId); } - /** - * @notice Retrieves the tick information of a pool at a specific tick. - * @dev Corresponds to pools[poolId].ticks[tick] - * @param poolId The ID of the pool. - * @param tick The tick to retrieve information for. - * @return liquidityGross The total position liquidity that references this tick - * @return liquidityNet The amount of net liquidity added (subtracted) when tick is crossed from left to right (right to left) - * @return feeGrowthOutside0X128 fee growth per unit of liquidity on the _other_ side of this tick (relative to the current tick) - * @return feeGrowthOutside1X128 fee growth per unit of liquidity on the _other_ side of this tick (relative to the current tick) - */ + /// @inheritdoc IStateView function getTickInfo(PoolId poolId, int24 tick) external view @@ -54,14 +37,7 @@ contract StateView is ImmutableState { return poolManager.getTickInfo(poolId, tick); } - /** - * @notice Retrieves the liquidity information of a pool at a specific tick. - * @dev Corresponds to pools[poolId].ticks[tick].liquidityGross and pools[poolId].ticks[tick].liquidityNet. A more gas efficient version of getTickInfo - * @param poolId The ID of the pool. - * @param tick The tick to retrieve liquidity for. - * @return liquidityGross The total position liquidity that references this tick - * @return liquidityNet The amount of net liquidity added (subtracted) when tick is crossed from left to right (right to left) - */ + /// @inheritdoc IStateView function getTickLiquidity(PoolId poolId, int24 tick) external view @@ -70,14 +46,7 @@ contract StateView is ImmutableState { return poolManager.getTickLiquidity(poolId, tick); } - /** - * @notice Retrieves the fee growth outside a tick range of a pool - * @dev Corresponds to pools[poolId].ticks[tick].feeGrowthOutside0X128 and pools[poolId].ticks[tick].feeGrowthOutside1X128. A more gas efficient version of getTickInfo - * @param poolId The ID of the pool. - * @param tick The tick to retrieve fee growth for. - * @return feeGrowthOutside0X128 fee growth per unit of liquidity on the _other_ side of this tick (relative to the current tick) - * @return feeGrowthOutside1X128 fee growth per unit of liquidity on the _other_ side of this tick (relative to the current tick) - */ + /// @inheritdoc IStateView function getTickFeeGrowthOutside(PoolId poolId, int24 tick) external view @@ -86,13 +55,7 @@ contract StateView is ImmutableState { return poolManager.getTickFeeGrowthOutside(poolId, tick); } - /** - * @notice Retrieves the global fee growth of a pool. - * @dev Corresponds to pools[poolId].feeGrowthGlobal0X128 and pools[poolId].feeGrowthGlobal1X128 - * @param poolId The ID of the pool. - * @return feeGrowthGlobal0 The global fee growth for token0. - * @return feeGrowthGlobal1 The global fee growth for token1. - */ + /// @inheritdoc IStateView function getFeeGrowthGlobals(PoolId poolId) external view @@ -101,39 +64,17 @@ contract StateView is ImmutableState { return poolManager.getFeeGrowthGlobals(poolId); } - /** - * @notice Retrieves the total liquidity of a pool. - * @dev Corresponds to pools[poolId].liquidity - * @param poolId The ID of the pool. - * @return liquidity The liquidity of the pool. - */ + /// @inheritdoc IStateView function getLiquidity(PoolId poolId) external view returns (uint128 liquidity) { return poolManager.getLiquidity(poolId); } - /** - * @notice Retrieves the tick bitmap of a pool at a specific tick. - * @dev Corresponds to pools[poolId].tickBitmap[tick] - * @param poolId The ID of the pool. - * @param tick The tick to retrieve the bitmap for. - * @return tickBitmap The bitmap of the tick. - */ + /// @inheritdoc IStateView function getTickBitmap(PoolId poolId, int16 tick) external view returns (uint256 tickBitmap) { return poolManager.getTickBitmap(poolId, tick); } - /** - * @notice Retrieves the position info without needing to calculate the `positionId`. - * @dev Corresponds to pools[poolId].positions[positionId] - * @param poolId The ID of the pool. - * @param owner The owner of the liquidity position. - * @param tickLower The lower tick of the liquidity range. - * @param tickUpper The upper tick of the liquidity range. - * @param salt The bytes32 randomness to further distinguish position state. - * @return liquidity The liquidity of the position. - * @return feeGrowthInside0LastX128 The fee growth inside the position for token0. - * @return feeGrowthInside1LastX128 The fee growth inside the position for token1. - */ + /// @inheritdoc IStateView function getPositionInfo(PoolId poolId, address owner, int24 tickLower, int24 tickUpper, bytes32 salt) external view @@ -142,15 +83,7 @@ contract StateView is ImmutableState { return poolManager.getPositionInfo(poolId, owner, tickLower, tickUpper, salt); } - /** - * @notice Retrieves the position information of a pool at a specific position ID. - * @dev Corresponds to pools[poolId].positions[positionId] - * @param poolId The ID of the pool. - * @param positionId The ID of the position. - * @return liquidity The liquidity of the position. - * @return feeGrowthInside0LastX128 The fee growth inside the position for token0. - * @return feeGrowthInside1LastX128 The fee growth inside the position for token1. - */ + /// @inheritdoc IStateView function getPositionInfo(PoolId poolId, bytes32 positionId) external view @@ -159,26 +92,12 @@ contract StateView is ImmutableState { return poolManager.getPositionInfo(poolId, positionId); } - /** - * @notice Retrieves the liquidity of a position. - * @dev Corresponds to pools[poolId].positions[positionId].liquidity. More gas efficient for just retrieving liquidity as compared to getPositionInfo - * @param poolId The ID of the pool. - * @param positionId The ID of the position. - * @return liquidity The liquidity of the position. - */ + /// @inheritdoc IStateView function getPositionLiquidity(PoolId poolId, bytes32 positionId) external view returns (uint128 liquidity) { return poolManager.getPositionLiquidity(poolId, positionId); } - /** - * @notice Calculate the fee growth inside a tick range of a pool - * @dev pools[poolId].feeGrowthInside0LastX128 in Position.Info is cached and can become stale. This function will calculate the up to date feeGrowthInside - * @param poolId The ID of the pool. - * @param tickLower The lower tick of the range. - * @param tickUpper The upper tick of the range. - * @return feeGrowthInside0X128 The fee growth inside the tick range for token0. - * @return feeGrowthInside1X128 The fee growth inside the tick range for token1. - */ + /// @inheritdoc IStateView function getFeeGrowthInside(PoolId poolId, int24 tickLower, int24 tickUpper) external view diff --git a/test/StateViewTest.t.sol b/test/StateViewTest.t.sol index 9feb9332c..21228f25b 100644 --- a/test/StateViewTest.t.sol +++ b/test/StateViewTest.t.sol @@ -19,9 +19,7 @@ import {FixedPoint128} from "@uniswap/v4-core/src/libraries/FixedPoint128.sol"; import {Deployers} from "@uniswap/v4-core/test/utils/Deployers.sol"; import {Fuzzers} from "@uniswap/v4-core/src/test/Fuzzers.sol"; import {Position} from "@uniswap/v4-core/src/libraries/Position.sol"; -import {Deploy} from "./shared/Deploy.sol"; - -import {StateView} from "../src/lens/StateView.sol"; +import {Deploy, IStateView} from "./shared/Deploy.sol"; /// This test was taken from StateLibrary.t.sol in v4-core and adapted to use the StateView contract instead. contract StateViewTest is Test, Deployers, Fuzzers, GasSnapshot { @@ -30,7 +28,7 @@ contract StateViewTest is Test, Deployers, Fuzzers, GasSnapshot { PoolId poolId; - StateView state; + IStateView state; function setUp() public { deployFreshManagerAndRouters(); diff --git a/test/shared/Deploy.sol b/test/shared/Deploy.sol index f85cd364d..eab08ec06 100644 --- a/test/shared/Deploy.sol +++ b/test/shared/Deploy.sol @@ -4,8 +4,8 @@ pragma solidity ^0.8.26; import {Vm} from "forge-std/Vm.sol"; import {IPositionDescriptor} from "../../src/interfaces/IPositionDescriptor.sol"; import {IPositionManager} from "../../src/interfaces/IPositionManager.sol"; -import {StateView} from "../../src/lens/StateView.sol"; import {IV4Quoter} from "../../src/interfaces/IV4Quoter.sol"; +import {IStateView} from "../../src/interfaces/IStateView.sol"; library Deploy { Vm internal constant vm = Vm(address(uint160(uint256(keccak256("hevm cheat code"))))); @@ -25,10 +25,9 @@ library Deploy { } } - // no interface available, wrap in contract, this results in both versions being compiled, that's why we are importing the default version explicitly from the json file - function stateView(address poolManager) internal returns (StateView stateView_) { + function stateView(address poolManager) internal returns (IStateView stateView_) { bytes memory args = abi.encode(poolManager); - bytes memory initcode = abi.encodePacked(vm.getCode("foundry-out/StateView.sol/StateView.default.json"), args); + bytes memory initcode = abi.encodePacked(vm.getCode("StateView.sol:StateView"), args); assembly { stateView_ := create(0, add(initcode, 0x20), mload(initcode)) } From e0c9dfafb7890629a95fd4f6491578372bc220f1 Mon Sep 17 00:00:00 2001 From: Sara Reynolds Date: Thu, 5 Dec 2024 11:57:33 -0500 Subject: [PATCH 15/20] fix natspec --- src/interfaces/IPoolInitializer.sol | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/interfaces/IPoolInitializer.sol b/src/interfaces/IPoolInitializer.sol index 39460f3e5..a73ed73e1 100644 --- a/src/interfaces/IPoolInitializer.sol +++ b/src/interfaces/IPoolInitializer.sol @@ -8,6 +8,6 @@ interface IPoolInitializer { /// @dev If the pool is already initialized, this function will not revert and just return type(int24).max /// @param key The PoolKey of the pool to initialize /// @param sqrtPriceX96 The initial sqrtPriceX96 of the pool - /// @return tick The current tick of the pool, or type(int24).max if the pool creation failed, or the pool already existed + /// @return The current tick of the pool, or type(int24).max if the pool creation failed, or the pool already existed function initializePool(PoolKey calldata key, uint160 sqrtPriceX96) external payable returns (int24); } From ef69e6d48af9c0c41ea5df1954560af84dd7f63a Mon Sep 17 00:00:00 2001 From: Sara Reynolds Date: Thu, 5 Dec 2024 16:54:11 -0500 Subject: [PATCH 16/20] comments --- script/DeployStateView.s.sol | 1 - script/DeployV4Quoter.s.sol | 1 - src/base/UnorderedNonce.sol | 2 -- src/interfaces/IPoolInitializer.sol | 2 +- src/interfaces/IPositionDescriptor.sol | 1 + src/interfaces/IStateView.sol | 1 + src/interfaces/IUnorderedNonce.sol | 4 ++++ .../PositionManager.modifyLiquidities.t.sol | 11 ++++++----- 8 files changed, 13 insertions(+), 10 deletions(-) diff --git a/script/DeployStateView.s.sol b/script/DeployStateView.s.sol index 0e85c4720..c90fbe6a8 100644 --- a/script/DeployStateView.s.sol +++ b/script/DeployStateView.s.sol @@ -4,7 +4,6 @@ pragma solidity ^0.8.20; import "forge-std/console2.sol"; import "forge-std/Script.sol"; -import {IPoolManager} from "@uniswap/v4-core/src/interfaces/IPoolManager.sol"; import {Deploy, IStateView} from "../test/shared/Deploy.sol"; contract DeployStateView is Script { diff --git a/script/DeployV4Quoter.s.sol b/script/DeployV4Quoter.s.sol index fbd37c33c..1d7e82a9e 100644 --- a/script/DeployV4Quoter.s.sol +++ b/script/DeployV4Quoter.s.sol @@ -4,7 +4,6 @@ pragma solidity ^0.8.20; import "forge-std/console2.sol"; import "forge-std/Script.sol"; -import {IPoolManager} from "@uniswap/v4-core/src/interfaces/IPoolManager.sol"; import {Deploy, IV4Quoter} from "../test/shared/Deploy.sol"; contract DeployV4Quoter is Script { diff --git a/src/base/UnorderedNonce.sol b/src/base/UnorderedNonce.sol index 2ee0336f6..97d3df36d 100644 --- a/src/base/UnorderedNonce.sol +++ b/src/base/UnorderedNonce.sol @@ -6,8 +6,6 @@ import {IUnorderedNonce} from "../interfaces/IUnorderedNonce.sol"; /// @title Unordered Nonce /// @notice Contract state and methods for using unordered nonces in signatures contract UnorderedNonce is IUnorderedNonce { - /// @notice mapping of nonces consumed by each address, where a nonce is a single bit on the 256-bit bitmap - /// @dev word is at most type(uint248).max mapping(address owner => mapping(uint256 word => uint256 bitmap)) public nonces; /// @notice Consume a nonce, reverting if it has already been used diff --git a/src/interfaces/IPoolInitializer.sol b/src/interfaces/IPoolInitializer.sol index a73ed73e1..b6168d4ba 100644 --- a/src/interfaces/IPoolInitializer.sol +++ b/src/interfaces/IPoolInitializer.sol @@ -7,7 +7,7 @@ interface IPoolInitializer { /// @notice Initialize a Uniswap v4 Pool /// @dev If the pool is already initialized, this function will not revert and just return type(int24).max /// @param key The PoolKey of the pool to initialize - /// @param sqrtPriceX96 The initial sqrtPriceX96 of the pool + /// @param sqrtPriceX96 The initial starting price of the pool, expressed as a sqrtPriceX96 /// @return The current tick of the pool, or type(int24).max if the pool creation failed, or the pool already existed function initializePool(PoolKey calldata key, uint160 sqrtPriceX96) external payable returns (int24); } diff --git a/src/interfaces/IPositionDescriptor.sol b/src/interfaces/IPositionDescriptor.sol index c61abc822..70f8d3ebe 100644 --- a/src/interfaces/IPositionDescriptor.sol +++ b/src/interfaces/IPositionDescriptor.sol @@ -23,6 +23,7 @@ interface IPositionDescriptor { /// @notice Returns the priority of a currency. /// For certain currencies on mainnet, the smaller the currency, the higher the priority + /// And those with the higher priority values (more positive values) will be in the numerator of the price ratio /// @param currency The currency address /// @return The priority of the currency function currencyRatioPriority(address currency) external view returns (int256); diff --git a/src/interfaces/IStateView.sol b/src/interfaces/IStateView.sol index c83b7de6c..31f62b3ab 100644 --- a/src/interfaces/IStateView.sol +++ b/src/interfaces/IStateView.sol @@ -9,6 +9,7 @@ import {IImmutableState} from "../interfaces/IImmutableState.sol"; /// @title StateView Interface /// @notice A view only contract wrapping the StateLibrary.sol library for reading storage in v4-core. +/// @dev The contract is intended for offchain clients. Use StateLibrary.sol directly if reading state onchain. interface IStateView is IImmutableState { /// @notice Get Slot0 of the pool: sqrtPriceX96, tick, protocolFee, lpFee /// @dev Corresponds to pools[poolId].slot0 diff --git a/src/interfaces/IUnorderedNonce.sol b/src/interfaces/IUnorderedNonce.sol index 03d3987e6..4e1866a6a 100644 --- a/src/interfaces/IUnorderedNonce.sol +++ b/src/interfaces/IUnorderedNonce.sol @@ -6,6 +6,10 @@ pragma solidity ^0.8.0; interface IUnorderedNonce { error NonceAlreadyUsed(); + /// @notice mapping of nonces consumed by each address, where a nonce is a single bit on the 256-bit bitmap + /// @dev word is at most type(uint248).max + function nonces(address owner, uint256 word) external view returns (uint256); + /// @notice Revoke a nonce by spending it, preventing it from being used again /// @dev Used in cases where a valid nonce has not been broadcasted onchain, and the owner wants to revoke the validity of the nonce /// @dev payable so it can be multicalled with native-token related actions diff --git a/test/position-managers/PositionManager.modifyLiquidities.t.sol b/test/position-managers/PositionManager.modifyLiquidities.t.sol index de8fac20d..f2e5674e7 100644 --- a/test/position-managers/PositionManager.modifyLiquidities.t.sol +++ b/test/position-managers/PositionManager.modifyLiquidities.t.sol @@ -838,7 +838,7 @@ contract PositionManagerModifyLiquiditiesTest is Test, PosmTestSetup, LiquidityF } struct BalanceDiff { - uint256 before; + uint256 _before; uint256 _after; } @@ -918,6 +918,7 @@ contract PositionManagerModifyLiquiditiesTest is Test, PosmTestSetup, LiquidityF planner.add(Actions.TAKE_PAIR, abi.encode(fotKey.currency0, fotKey.currency1, ActionConstants.MSG_SENDER)); // needed to remove variables because of stack too deep + // Read below as: // bool currency0IsFOT = fotKey.currency0 == Currency.wrap(address(fotToken)); // bool positionIsEntirelyInOtherToken = currency0IsFOT // ? tickUpper <= TickMath.getTickAtSqrtPrice(sqrtPriceX96) @@ -948,11 +949,11 @@ contract PositionManagerModifyLiquiditiesTest is Test, PosmTestSetup, LiquidityF bool currency0IsFOT = fotKey.currency0 == Currency.wrap(address(fotToken)); uint256 expectedFee = (currency0IsFOT ? amount0 : amount1).calculatePortion(bips); (expected._0, expected._1) = currency0IsFOT - ? (balance0.before - balance0._after - expectedFee, balance1.before - balance1._after) - : (balance0.before - balance0._after, balance1.before - balance1._after - expectedFee); + ? (balance0._before - balance0._after - expectedFee, balance1._before - balance1._after) + : (balance0._before - balance0._after, balance1._before - balance1._after - expectedFee); } - assertEq(expected._0, balance0PM._after - balance0PM.before); - assertEq(expected._1, balance1PM._after - balance1PM.before); + assertEq(expected._0, balance0PM._after - balance0PM._before); + assertEq(expected._1, balance1PM._after - balance1PM._before); { // the liquidity that was created is a diff of the balance change uint128 expectedLiquidity = LiquidityAmounts.getLiquidityForAmounts( From c6f69e32cf0f34c51ebe74b237df629acf82bbe1 Mon Sep 17 00:00:00 2001 From: Sara Reynolds Date: Thu, 5 Dec 2024 17:04:03 -0500 Subject: [PATCH 17/20] create2 for consistency --- ...PositionManager_permit_secondPosition.snap | 2 +- .../PositionManager_permit_twice.snap | 2 +- script/DeployPosm.s.sol | 2 +- script/DeployStateView.s.sol | 2 +- script/DeployV4Quoter.s.sol | 2 +- test/StateViewTest.t.sol | 2 +- test/V4Quoter.t.sol | 2 +- test/shared/Deploy.sol | 20 ++++++++++--------- test/shared/PosmTestSetup.sol | 2 +- 9 files changed, 19 insertions(+), 17 deletions(-) diff --git a/.forge-snapshots/PositionManager_permit_secondPosition.snap b/.forge-snapshots/PositionManager_permit_secondPosition.snap index b1dc5c691..f7b2bb9f5 100644 --- a/.forge-snapshots/PositionManager_permit_secondPosition.snap +++ b/.forge-snapshots/PositionManager_permit_secondPosition.snap @@ -1 +1 @@ -62075 \ No newline at end of file +62063 \ No newline at end of file diff --git a/.forge-snapshots/PositionManager_permit_twice.snap b/.forge-snapshots/PositionManager_permit_twice.snap index 3df0b01a3..54b7cc91a 100644 --- a/.forge-snapshots/PositionManager_permit_twice.snap +++ b/.forge-snapshots/PositionManager_permit_twice.snap @@ -1 +1 @@ -44963 \ No newline at end of file +44975 \ No newline at end of file diff --git a/script/DeployPosm.s.sol b/script/DeployPosm.s.sol index 006ce4f67..c51c2ca4f 100644 --- a/script/DeployPosm.s.sol +++ b/script/DeployPosm.s.sol @@ -21,7 +21,7 @@ contract DeployPosmTest is Script { ) public returns (IPositionDescriptor positionDescriptor, IPositionManager posm) { vm.startBroadcast(); - positionDescriptor = Deploy.positionDescriptor(poolManager, wrappedNative, nativeCurrencyLabel); + positionDescriptor = Deploy.positionDescriptor(poolManager, wrappedNative, nativeCurrencyLabel, hex"00"); console2.log("PositionDescriptor", address(positionDescriptor)); posm = Deploy.positionManager( diff --git a/script/DeployStateView.s.sol b/script/DeployStateView.s.sol index c90fbe6a8..230bd819a 100644 --- a/script/DeployStateView.s.sol +++ b/script/DeployStateView.s.sol @@ -13,7 +13,7 @@ contract DeployStateView is Script { vm.startBroadcast(); // forge script --broadcast --sig 'run(address)' --rpc-url --private-key --verify script/DeployStateView.s.sol:DeployStateView - state = Deploy.stateView(poolManager); + state = Deploy.stateView(poolManager, hex"00"); console2.log("StateView", address(state)); console2.log("PoolManager", address(state.poolManager())); diff --git a/script/DeployV4Quoter.s.sol b/script/DeployV4Quoter.s.sol index 1d7e82a9e..72361df65 100644 --- a/script/DeployV4Quoter.s.sol +++ b/script/DeployV4Quoter.s.sol @@ -13,7 +13,7 @@ contract DeployV4Quoter is Script { vm.startBroadcast(); // forge script --broadcast --sig 'run(address)' --rpc-url --private-key --verify script/DeployV4Quoter.s.sol:DeployV4Quoter - state = Deploy.v4Quoter(poolManager); + state = Deploy.v4Quoter(poolManager, hex"00"); console2.log("V4Quoter", address(state)); console2.log("PoolManager", address(state.poolManager())); diff --git a/test/StateViewTest.t.sol b/test/StateViewTest.t.sol index 21228f25b..17e8f7f74 100644 --- a/test/StateViewTest.t.sol +++ b/test/StateViewTest.t.sol @@ -39,7 +39,7 @@ contract StateViewTest is Test, Deployers, Fuzzers, GasSnapshot { poolId = key.toId(); manager.initialize(key, SQRT_PRICE_1_1); - state = Deploy.stateView(address(manager)); + state = Deploy.stateView(address(manager), hex"00"); } function test_getSlot0() public { diff --git a/test/V4Quoter.t.sol b/test/V4Quoter.t.sol index 5deaacf11..8b2dc5c35 100644 --- a/test/V4Quoter.t.sol +++ b/test/V4Quoter.t.sol @@ -55,7 +55,7 @@ contract QuoterTest is Test, Deployers, GasSnapshot { function setUp() public { deployFreshManagerAndRouters(); - quoter = Deploy.v4Quoter(address(manager)); + quoter = Deploy.v4Quoter(address(manager), hex"00"); positionManager = new PoolModifyLiquidityTest(manager); // salts are chosen so that address(token0) < address(token1) && address(token1) < address(token2) diff --git a/test/shared/Deploy.sol b/test/shared/Deploy.sol index eab08ec06..4b671d8c8 100644 --- a/test/shared/Deploy.sol +++ b/test/shared/Deploy.sol @@ -25,30 +25,32 @@ library Deploy { } } - function stateView(address poolManager) internal returns (IStateView stateView_) { + function stateView(address poolManager, bytes memory salt) internal returns (IStateView stateView_) { bytes memory args = abi.encode(poolManager); bytes memory initcode = abi.encodePacked(vm.getCode("StateView.sol:StateView"), args); assembly { - stateView_ := create(0, add(initcode, 0x20), mload(initcode)) + stateView_ := create2(0, add(initcode, 0x20), mload(initcode), salt) } } - function v4Quoter(address poolManager) internal returns (IV4Quoter quoter) { + function v4Quoter(address poolManager, bytes memory salt) internal returns (IV4Quoter quoter) { bytes memory args = abi.encode(poolManager); bytes memory initcode = abi.encodePacked(vm.getCode("V4Quoter.sol:V4Quoter"), args); assembly { - quoter := create(0, add(initcode, 0x20), mload(initcode)) + quoter := create2(0, add(initcode, 0x20), mload(initcode), salt) } } - function positionDescriptor(address poolManager, address wrappedNative, string memory nativeCurrencyLabel) - internal - returns (IPositionDescriptor descriptor) - { + function positionDescriptor( + address poolManager, + address wrappedNative, + string memory nativeCurrencyLabel, + bytes memory salt + ) internal returns (IPositionDescriptor descriptor) { bytes memory args = abi.encode(poolManager, wrappedNative, nativeCurrencyLabel); bytes memory initcode = abi.encodePacked(vm.getCode("PositionDescriptor.sol:PositionDescriptor"), args); assembly { - descriptor := create(0, add(initcode, 0x20), mload(initcode)) + descriptor := create2(0, add(initcode, 0x20), mload(initcode), salt) } } } diff --git a/test/shared/PosmTestSetup.sol b/test/shared/PosmTestSetup.sol index 4c934c9d2..8798220ec 100644 --- a/test/shared/PosmTestSetup.sol +++ b/test/shared/PosmTestSetup.sol @@ -68,7 +68,7 @@ contract PosmTestSetup is Test, Deployers, DeployPermit2, LiquidityOperations { // We use deployPermit2() to prevent having to use via-ir in this repository. permit2 = IAllowanceTransfer(deployPermit2()); positionDescriptor = - Deploy.positionDescriptor(address(poolManager), 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2, "ETH"); + Deploy.positionDescriptor(address(poolManager), 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2, "ETH", hex"00"); lpm = Deploy.positionManager( address(poolManager), address(permit2), 100_000, address(positionDescriptor), address(_WETH9), hex"03" ); From 70dc767db03683823a22317a91eb92ab0479b5d3 Mon Sep 17 00:00:00 2001 From: Sara Reynolds Date: Mon, 9 Dec 2024 11:37:49 -0500 Subject: [PATCH 18/20] inheritdoc --- src/base/UnorderedNonce.sol | 1 + 1 file changed, 1 insertion(+) diff --git a/src/base/UnorderedNonce.sol b/src/base/UnorderedNonce.sol index 97d3df36d..53b93b968 100644 --- a/src/base/UnorderedNonce.sol +++ b/src/base/UnorderedNonce.sol @@ -6,6 +6,7 @@ import {IUnorderedNonce} from "../interfaces/IUnorderedNonce.sol"; /// @title Unordered Nonce /// @notice Contract state and methods for using unordered nonces in signatures contract UnorderedNonce is IUnorderedNonce { + /// @inheritdoc IUnorderedNonce mapping(address owner => mapping(uint256 word => uint256 bitmap)) public nonces; /// @notice Consume a nonce, reverting if it has already been used From 5dcbdb7d7211243065a2012ea48f527caa4d9f80 Mon Sep 17 00:00:00 2001 From: Sara Reynolds Date: Mon, 9 Dec 2024 12:39:30 -0500 Subject: [PATCH 19/20] natspec --- src/base/Permit2Forwarder.sol | 2 +- src/interfaces/IPermit2Forwarder.sol | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/base/Permit2Forwarder.sol b/src/base/Permit2Forwarder.sol index d7cce0355..43cdc1ce6 100644 --- a/src/base/Permit2Forwarder.sol +++ b/src/base/Permit2Forwarder.sol @@ -3,7 +3,7 @@ pragma solidity ^0.8.0; import {IPermit2Forwarder, IAllowanceTransfer} from "../interfaces/IPermit2Forwarder.sol"; -/// @notice PermitForwarder allows permitting this contract as a spender on permit2 +/// @notice Permit2Forwarder allows permitting this contract as a spender on permit2 /// @dev This contract does not enforce the spender to be this contract, but that is the intended use case contract Permit2Forwarder is IPermit2Forwarder { /// @notice the Permit2 contract to forward approvals diff --git a/src/interfaces/IPermit2Forwarder.sol b/src/interfaces/IPermit2Forwarder.sol index 0099466c2..7b07cd07d 100644 --- a/src/interfaces/IPermit2Forwarder.sol +++ b/src/interfaces/IPermit2Forwarder.sol @@ -3,7 +3,7 @@ pragma solidity ^0.8.0; import {IAllowanceTransfer} from "permit2/src/interfaces/IAllowanceTransfer.sol"; -/// @notice PermitForwarder allows permitting this contract as a spender on permit2 +/// @notice Permit2Forwarder allows permitting this contract as a spender on permit2 /// @dev This contract does not enforce the spender to be this contract, but that is the intended use case interface IPermit2Forwarder { /// @notice allows forwarding a single permit to permit2 From 9d295b5f0d4f1e7e4c89e98ef2b481d73e9cb568 Mon Sep 17 00:00:00 2001 From: Sara Reynolds Date: Mon, 9 Dec 2024 14:52:32 -0500 Subject: [PATCH 20/20] comments --- src/interfaces/IPermit2Forwarder.sol | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/interfaces/IPermit2Forwarder.sol b/src/interfaces/IPermit2Forwarder.sol index 7b07cd07d..98403ac88 100644 --- a/src/interfaces/IPermit2Forwarder.sol +++ b/src/interfaces/IPermit2Forwarder.sol @@ -3,8 +3,8 @@ pragma solidity ^0.8.0; import {IAllowanceTransfer} from "permit2/src/interfaces/IAllowanceTransfer.sol"; -/// @notice Permit2Forwarder allows permitting this contract as a spender on permit2 -/// @dev This contract does not enforce the spender to be this contract, but that is the intended use case +/// @title IPermit2Forwarder +/// @notice Interface for the Permit2Forwarder contract interface IPermit2Forwarder { /// @notice allows forwarding a single permit to permit2 /// @dev this function is payable to allow multicall with NATIVE based actions