From e68a5dcdf32ee62abf47f7bdf782780ada3f80cf Mon Sep 17 00:00:00 2001 From: Sara Reynolds Date: Thu, 16 Nov 2023 23:09:56 -0500 Subject: [PATCH] use transient storage for the current hook addr --- ...swap hook, already cached dynamic fee.snap | 2 +- .../cached dynamic fee, no hooks.snap | 2 +- .forge-snapshots/donate gas with 1 token.snap | 2 +- .../donate gas with 2 tokens.snap | 2 +- .forge-snapshots/mint with empty hook.snap | 2 +- .forge-snapshots/mint with native token.snap | 2 +- .forge-snapshots/mint.snap | 2 +- .../poolManager bytecode size.snap | 2 +- .forge-snapshots/simple swap native.snap | 1 - .forge-snapshots/simple swap with native.snap | 2 +- .forge-snapshots/simple swap.snap | 2 +- ...p against liquidity with native token.snap | 2 +- .forge-snapshots/swap against liquidity.snap | 2 +- .../swap burn claim for input.snap | 2 +- .../swap mint 1155 as output.snap | 1 - .../swap mint output as claim.snap | 2 +- .forge-snapshots/swap with 1155 as input.snap | 1 - .forge-snapshots/swap with dynamic fee.snap | 2 +- .forge-snapshots/swap with hooks.snap | 2 +- .../update dynamic fee in before swap.snap | 2 +- .gas-snapshot | 179 +++++++++--------- foundry.toml | 2 +- src/PoolManager.sol | 14 +- src/libraries/CurrentHookAddress.sol | 23 +++ src/test/AccessLockHook.sol | 4 - test/AccessLock.t.sol | 2 - test/CurrentHookAddress.t.sol | 23 +++ 27 files changed, 160 insertions(+), 124 deletions(-) delete mode 100644 .forge-snapshots/simple swap native.snap delete mode 100644 .forge-snapshots/swap mint 1155 as output.snap delete mode 100644 .forge-snapshots/swap with 1155 as input.snap create mode 100644 src/libraries/CurrentHookAddress.sol create mode 100644 test/CurrentHookAddress.t.sol diff --git a/.forge-snapshots/before swap hook, already cached dynamic fee.snap b/.forge-snapshots/before swap hook, already cached dynamic fee.snap index 335c917f5..882bdc417 100644 --- a/.forge-snapshots/before swap hook, already cached dynamic fee.snap +++ b/.forge-snapshots/before swap hook, already cached dynamic fee.snap @@ -1 +1 @@ -188685 \ No newline at end of file +186984 \ No newline at end of file diff --git a/.forge-snapshots/cached dynamic fee, no hooks.snap b/.forge-snapshots/cached dynamic fee, no hooks.snap index 3b111811d..ce4928b28 100644 --- a/.forge-snapshots/cached dynamic fee, no hooks.snap +++ b/.forge-snapshots/cached dynamic fee, no hooks.snap @@ -1 +1 @@ -142201 \ No newline at end of file +142310 \ No newline at end of file diff --git a/.forge-snapshots/donate gas with 1 token.snap b/.forge-snapshots/donate gas with 1 token.snap index 83fb09667..548cb86df 100644 --- a/.forge-snapshots/donate gas with 1 token.snap +++ b/.forge-snapshots/donate gas with 1 token.snap @@ -1 +1 @@ -134065 \ No newline at end of file +132186 \ No newline at end of file diff --git a/.forge-snapshots/donate gas with 2 tokens.snap b/.forge-snapshots/donate gas with 2 tokens.snap index 23ccbf4ed..4e0addad8 100644 --- a/.forge-snapshots/donate gas with 2 tokens.snap +++ b/.forge-snapshots/donate gas with 2 tokens.snap @@ -1 +1 @@ -182638 \ No newline at end of file +180759 \ No newline at end of file diff --git a/.forge-snapshots/mint with empty hook.snap b/.forge-snapshots/mint with empty hook.snap index 9810c72fc..5337c9f0e 100644 --- a/.forge-snapshots/mint with empty hook.snap +++ b/.forge-snapshots/mint with empty hook.snap @@ -1 +1 @@ -335320 \ No newline at end of file +313472 \ No newline at end of file diff --git a/.forge-snapshots/mint with native token.snap b/.forge-snapshots/mint with native token.snap index aa6a04e4a..52d5fc48b 100644 --- a/.forge-snapshots/mint with native token.snap +++ b/.forge-snapshots/mint with native token.snap @@ -1 +1 @@ -198076 \ No newline at end of file +196197 \ No newline at end of file diff --git a/.forge-snapshots/mint.snap b/.forge-snapshots/mint.snap index f4e7e290e..5bc2ec174 100644 --- a/.forge-snapshots/mint.snap +++ b/.forge-snapshots/mint.snap @@ -1 +1 @@ -198018 \ No newline at end of file +196139 \ No newline at end of file diff --git a/.forge-snapshots/poolManager bytecode size.snap b/.forge-snapshots/poolManager bytecode size.snap index d98a1a474..259555663 100644 --- a/.forge-snapshots/poolManager bytecode size.snap +++ b/.forge-snapshots/poolManager bytecode size.snap @@ -1 +1 @@ -25133 \ No newline at end of file +25374 \ No newline at end of file diff --git a/.forge-snapshots/simple swap native.snap b/.forge-snapshots/simple swap native.snap deleted file mode 100644 index 65b732d63..000000000 --- a/.forge-snapshots/simple swap native.snap +++ /dev/null @@ -1 +0,0 @@ -132772 \ No newline at end of file diff --git a/.forge-snapshots/simple swap with native.snap b/.forge-snapshots/simple swap with native.snap index 037672a6d..a798ffb0e 100644 --- a/.forge-snapshots/simple swap with native.snap +++ b/.forge-snapshots/simple swap with native.snap @@ -1 +1 @@ -193042 \ No newline at end of file +191151 \ No newline at end of file diff --git a/.forge-snapshots/simple swap.snap b/.forge-snapshots/simple swap.snap index 93ed67dc6..3a06ecae8 100644 --- a/.forge-snapshots/simple swap.snap +++ b/.forge-snapshots/simple swap.snap @@ -1 +1 @@ -201609 \ No newline at end of file +199718 \ No newline at end of file diff --git a/.forge-snapshots/swap against liquidity with native token.snap b/.forge-snapshots/swap against liquidity with native token.snap index f634e0f3b..f22727854 100644 --- a/.forge-snapshots/swap against liquidity with native token.snap +++ b/.forge-snapshots/swap against liquidity with native token.snap @@ -1 +1 @@ -121638 \ No newline at end of file +121747 \ No newline at end of file diff --git a/.forge-snapshots/swap against liquidity.snap b/.forge-snapshots/swap against liquidity.snap index 062600fe8..f02143e91 100644 --- a/.forge-snapshots/swap against liquidity.snap +++ b/.forge-snapshots/swap against liquidity.snap @@ -1 +1 @@ -109127 \ No newline at end of file +109236 \ No newline at end of file diff --git a/.forge-snapshots/swap burn claim for input.snap b/.forge-snapshots/swap burn claim for input.snap index 56de38345..0faa9f431 100644 --- a/.forge-snapshots/swap burn claim for input.snap +++ b/.forge-snapshots/swap burn claim for input.snap @@ -1 +1 @@ -128197 \ No newline at end of file +128306 \ No newline at end of file diff --git a/.forge-snapshots/swap mint 1155 as output.snap b/.forge-snapshots/swap mint 1155 as output.snap deleted file mode 100644 index c02135f5a..000000000 --- a/.forge-snapshots/swap mint 1155 as output.snap +++ /dev/null @@ -1 +0,0 @@ -169753 \ No newline at end of file diff --git a/.forge-snapshots/swap mint output as claim.snap b/.forge-snapshots/swap mint output as claim.snap index d056e6605..8d59c8f6e 100644 --- a/.forge-snapshots/swap mint output as claim.snap +++ b/.forge-snapshots/swap mint output as claim.snap @@ -1 +1 @@ -211778 \ No newline at end of file +209887 \ No newline at end of file diff --git a/.forge-snapshots/swap with 1155 as input.snap b/.forge-snapshots/swap with 1155 as input.snap deleted file mode 100644 index b1978cbc0..000000000 --- a/.forge-snapshots/swap with 1155 as input.snap +++ /dev/null @@ -1 +0,0 @@ -156183 \ No newline at end of file diff --git a/.forge-snapshots/swap with dynamic fee.snap b/.forge-snapshots/swap with dynamic fee.snap index efe381438..f497058b5 100644 --- a/.forge-snapshots/swap with dynamic fee.snap +++ b/.forge-snapshots/swap with dynamic fee.snap @@ -1 +1 @@ -187925 \ No newline at end of file +186224 \ No newline at end of file diff --git a/.forge-snapshots/swap with hooks.snap b/.forge-snapshots/swap with hooks.snap index 45ed71871..983177dc5 100644 --- a/.forge-snapshots/swap with hooks.snap +++ b/.forge-snapshots/swap with hooks.snap @@ -1 +1 @@ -109106 \ No newline at end of file +109215 \ No newline at end of file diff --git a/.forge-snapshots/update dynamic fee in before swap.snap b/.forge-snapshots/update dynamic fee in before swap.snap index 48f95f922..09ccd2fc0 100644 --- a/.forge-snapshots/update dynamic fee in before swap.snap +++ b/.forge-snapshots/update dynamic fee in before swap.snap @@ -1 +1 @@ -194515 \ No newline at end of file +192814 \ No newline at end of file diff --git a/.gas-snapshot b/.gas-snapshot index 95b415bcf..2bef28369 100644 --- a/.gas-snapshot +++ b/.gas-snapshot @@ -1,39 +1,42 @@ -AccessLockTest:test_beforeDonate_donate_succeedsWithAccessLock(uint128) (runs: 100, μ: 496235, ~: 496235) -AccessLockTest:test_beforeDonate_mint_succeedsWithAccessLock(uint128) (runs: 100, μ: 519000, ~: 519000) -AccessLockTest:test_beforeDonate_modifyPosition_succeedsWithAccessLock(uint128) (runs: 100, μ: 590020, ~: 589972) -AccessLockTest:test_beforeDonate_swap_succeedsWithAccessLock(uint128) (runs: 100, μ: 515409, ~: 515408) -AccessLockTest:test_beforeDonate_take_succeedsWithAccessLock(uint128) (runs: 100, μ: 516772, ~: 517832) -AccessLockTest:test_beforeModifyPosition_donate_succeedsWithAccessLock(uint128) (runs: 100, μ: 529171, ~: 529171) -AccessLockTest:test_beforeModifyPosition_mint_succeedsWithAccessLock(uint128) (runs: 100, μ: 383493, ~: 386485) -AccessLockTest:test_beforeModifyPosition_modifyPosition_succeedsWithAccessLock(uint128) (runs: 100, μ: 480962, ~: 480911) -AccessLockTest:test_beforeModifyPosition_swap_succeedsWithAccessLock(uint128) (runs: 100, μ: 676991, ~: 501638) -AccessLockTest:test_beforeModifyPosition_take_succeedsWithAccessLock(uint128) (runs: 100, μ: 549875, ~: 550935) -AccessLockTest:test_beforeSwap_donate_succeedsWithAccessLock(uint128) (runs: 100, μ: 516366, ~: 516366) -AccessLockTest:test_beforeSwap_mint_succeedsWithAccessLock(uint128) (runs: 100, μ: 519137, ~: 519137) -AccessLockTest:test_beforeSwap_modifyPosition_succeedsWithAccessLock(uint128) (runs: 100, μ: 590315, ~: 590207) -AccessLockTest:test_beforeSwap_swap_succeedsWithAccessLock(uint128) (runs: 100, μ: 816390, ~: 527811) -AccessLockTest:test_beforeSwap_take_succeedsWithAccessLock(uint128) (runs: 100, μ: 516413, ~: 518025) -AccessLockTest:test_onlyByLocker_revertsForNoAccessLockPool() (gas: 106069) -ClaimsTest:testCanBurn(uint256) (runs: 100, μ: 32944, ~: 33272) -ClaimsTest:testCanTransfer(uint256) (runs: 100, μ: 50781, ~: 51872) +AccessLockTest:test_beforeDonate_donate_succeedsWithAccessLock(uint128) (runs: 100, μ: 474892, ~: 474892) +AccessLockTest:test_beforeDonate_mint_succeedsWithAccessLock(uint128) (runs: 100, μ: 497536, ~: 497536) +AccessLockTest:test_beforeDonate_modifyPosition_succeedsWithAccessLock(uint128) (runs: 100, μ: 568680, ~: 568629) +AccessLockTest:test_beforeDonate_swap_succeedsWithAccessLock(uint128) (runs: 100, μ: 497285, ~: 497283) +AccessLockTest:test_beforeDonate_take_succeedsWithAccessLock(uint128) (runs: 100, μ: 498568, ~: 499628) +AccessLockTest:test_beforeModifyPosition_donate_succeedsWithAccessLock(uint128) (runs: 100, μ: 507828, ~: 507828) +AccessLockTest:test_beforeModifyPosition_mint_succeedsWithAccessLock(uint128) (runs: 100, μ: 361908, ~: 364900) +AccessLockTest:test_beforeModifyPosition_modifyPosition_succeedsWithAccessLock(uint128) (runs: 100, μ: 459501, ~: 459447) +AccessLockTest:test_beforeModifyPosition_swap_succeedsWithAccessLock(uint128) (runs: 100, μ: 651663, ~: 480283) +AccessLockTest:test_beforeModifyPosition_take_succeedsWithAccessLock(uint128) (runs: 100, μ: 531672, ~: 532732) +AccessLockTest:test_beforeSwap_donate_succeedsWithAccessLock(uint128) (runs: 100, μ: 495011, ~: 495011) +AccessLockTest:test_beforeSwap_mint_succeedsWithAccessLock(uint128) (runs: 100, μ: 497661, ~: 497661) +AccessLockTest:test_beforeSwap_modifyPosition_succeedsWithAccessLock(uint128) (runs: 100, μ: 568948, ~: 568852) +AccessLockTest:test_beforeSwap_swap_succeedsWithAccessLock(uint128) (runs: 100, μ: 808769, ~: 506444) +AccessLockTest:test_beforeSwap_take_succeedsWithAccessLock(uint128) (runs: 100, μ: 498197, ~: 499809) +AccessLockTest:test_onlyByLocker_revertsForNoAccessLockPool() (gas: 84484) +ClaimsTest:testCanBurn(uint256) (runs: 100, μ: 32943, ~: 33270) +ClaimsTest:testCanTransfer(uint256) (runs: 100, μ: 50780, ~: 51870) ClaimsTest:testCanTransferToZeroAddress() (gas: 51088) ClaimsTest:testCatchesOverflowOnTransfer() (gas: 45550) ClaimsTest:testCatchesUnderflowOnBurn(uint256) (runs: 100, μ: 39917, ~: 40912) ClaimsTest:testCatchesUnderflowOnTransfer(uint256) (runs: 100, μ: 40054, ~: 41049) ClaimsTest:testTransferToClaimsContractFails() (gas: 36392) -FeesTest:testCollectFees() (gas: 623284) -FeesTest:testHookWithdrawFeeProtocolWithdrawFee(uint16,uint16) (runs: 100, μ: 497891, ~: 503652) -FeesTest:testInitializeAllFees(uint16,uint16,uint16,uint16) (runs: 100, μ: 139790, ~: 136923) -FeesTest:testInitializeBothHookFee(uint16,uint16) (runs: 100, μ: 85585, ~: 93458) +CurrentHookAddressTest:test_get_currentHookAddress() (gas: 472) +CurrentHookAddressTest:test_set_currentHookAddress() (gas: 1007) +CurrentHookAddressTest:test_set_currentHookAddressTwice() (gas: 1498) +FeesTest:testCollectFees() (gas: 601545) +FeesTest:testHookWithdrawFeeProtocolWithdrawFee(uint16,uint16) (runs: 100, μ: 479581, ~: 486271) +FeesTest:testInitializeAllFees(uint16,uint16,uint16,uint16) (runs: 100, μ: 139794, ~: 136923) +FeesTest:testInitializeBothHookFee(uint16,uint16) (runs: 100, μ: 85187, ~: 93458) FeesTest:testInitializeFailsNoHook() (gas: 20221) -FeesTest:testInitializeHookProtocolSwapFee(uint16,uint16) (runs: 100, μ: 102436, ~: 109361) +FeesTest:testInitializeHookProtocolSwapFee(uint16,uint16) (runs: 100, μ: 102906, ~: 109361) FeesTest:testInitializeHookSwapFee(uint16) (runs: 100, μ: 68405, ~: 70902) -FeesTest:testInitializeHookWithdrawFee(uint16) (runs: 100, μ: 68445, ~: 70942) -FeesTest:testInitializeWithSwapProtocolFeeAndHookFeeDifferentDirections() (gas: 582964) -FeesTest:testNoHookProtocolFee(uint16,uint16) (runs: 100, μ: 756189, ~: 762676) -FeesTest:testProtocolFeeOnWithdrawalRemainsZeroIfNoHookWithdrawalFeeSet(uint16,uint16) (runs: 100, μ: 477595, ~: 479982) -FeesTest:testProtocolSwapFeeAndHookSwapFeeSameDirection() (gas: 603355) -FeesTest:testSwapWithProtocolFeeAllAndHookFeeAllButOnlySwapFlag() (gas: 649906) +FeesTest:testInitializeHookWithdrawFee(uint16) (runs: 100, μ: 68672, ~: 70942) +FeesTest:testInitializeWithSwapProtocolFeeAndHookFeeDifferentDirections() (gas: 561225) +FeesTest:testNoHookProtocolFee(uint16,uint16) (runs: 100, μ: 754318, ~: 761453) +FeesTest:testProtocolFeeOnWithdrawalRemainsZeroIfNoHookWithdrawalFeeSet(uint16,uint16) (runs: 100, μ: 460691, ~: 462600) +FeesTest:testProtocolSwapFeeAndHookSwapFeeSameDirection() (gas: 581616) +FeesTest:testSwapWithProtocolFeeAllAndHookFeeAllButOnlySwapFlag() (gas: 632612) FullMathTest:testResultOverflowsHelper() (gas: 3964) FullMathTest:test_mulDivRounding(uint256,uint256,uint256) (runs: 100, μ: 4715, ~: 4445) FullMathTest:test_mulDivRoundingUp_fuzz(uint256,uint256,uint256) (runs: 100, μ: 4657, ~: 4687) @@ -74,28 +77,28 @@ HooksTest:testValidateHookAddressBeforeInitializeAfterModify(uint160) (runs: 100 HooksTest:testValidateHookAddressBeforeModify(uint160) (runs: 100, μ: 4089, ~: 4089) HooksTest:testValidateHookAddressBeforeSwap(uint160) (runs: 100, μ: 4101, ~: 4101) HooksTest:testValidateHookAddressFailsAllHooks(uint152,uint8) (runs: 100, μ: 4739, ~: 4683) -HooksTest:testValidateHookAddressFailsNoHooks(uint152,uint8) (runs: 100, μ: 4811, ~: 4778) +HooksTest:testValidateHookAddressFailsNoHooks(uint152,uint8) (runs: 100, μ: 4802, ~: 4731) HooksTest:testValidateHookAddressNoHooks(uint160) (runs: 100, μ: 4115, ~: 4115) -HooksTest:test_afterDonate_invalidReturn() (gas: 91350) +HooksTest:test_afterDonate_invalidReturn() (gas: 89661) HooksTest:test_afterInitialize_invalidReturn() (gas: 100738) -HooksTest:test_afterModifyPosition_invalidReturn() (gas: 170871) -HooksTest:test_afterSwap_invalidReturn() (gas: 164357) -HooksTest:test_beforeDonate_invalidReturn() (gas: 91350) +HooksTest:test_afterModifyPosition_invalidReturn() (gas: 169182) +HooksTest:test_afterSwap_invalidReturn() (gas: 162656) +HooksTest:test_beforeDonate_invalidReturn() (gas: 89661) HooksTest:test_beforeInitialize_invalidReturn() (gas: 49199) -HooksTest:test_beforeModifyPosition_invalidReturn() (gas: 66943) -HooksTest:test_beforeSwap_invalidReturn() (gas: 93794) -HooksTest:test_donate_succeedsWithHook() (gas: 444071) +HooksTest:test_beforeModifyPosition_invalidReturn() (gas: 65254) +HooksTest:test_beforeSwap_invalidReturn() (gas: 92105) +HooksTest:test_donate_succeedsWithHook() (gas: 442382) HooksTest:test_initialize_succeedsWithHook() (gas: 208222) -HooksTest:test_modifyPosition_succeedsWithHook() (gas: 297287) -HooksTest:test_swap_succeedsWithHook() (gas: 372215) +HooksTest:test_modifyPosition_succeedsWithHook() (gas: 295598) +HooksTest:test_swap_succeedsWithHook() (gas: 370514) HooksTest:test_validateHookAddress_accessLock(uint160) (runs: 100, μ: 4124, ~: 4124) LockersLibrary:testLockerLengthAndNonzeroDeltaCount() (gas: 52397) LockersLibrary:test_clear(address[]) (runs: 100, μ: 114024, ~: 111101) LockersLibrary:test_decrementNonzeroDeltaCount() (gas: 1157) -LockersLibrary:test_decrementNonzeroDeltaCountFuzz(uint8) (runs: 100, μ: 117875, ~: 65697) +LockersLibrary:test_decrementNonzeroDeltaCountFuzz(uint8) (runs: 100, μ: 117455, ~: 52557) LockersLibrary:test_getCurrentLocker_multipleAddressesFuzz(address[]) (runs: 100, μ: 273024, ~: 265967) LockersLibrary:test_incrementNonzeroDeltaCount() (gas: 785) -LockersLibrary:test_incrementNonzeroDeltaCountFuzz(uint8) (runs: 100, μ: 70280, ~: 39148) +LockersLibrary:test_incrementNonzeroDeltaCountFuzz(uint8) (runs: 100, μ: 70029, ~: 31308) LockersLibrary:test_pop() (gas: 1770) LockersLibrary:test_pop_multipleAddressesFuzz(address[]) (runs: 100, μ: 240601, ~: 234397) LockersLibrary:test_push() (gas: 1421) @@ -108,66 +111,66 @@ PoolManagerInitializeTest:test_initialize_failsIfTickSpaceNeg(uint160) (runs: 10 PoolManagerInitializeTest:test_initialize_failsIfTickSpaceTooLarge(uint160) (runs: 100, μ: 21748, ~: 21748) PoolManagerInitializeTest:test_initialize_failsIfTickSpaceZero(uint160) (runs: 100, μ: 20801, ~: 20801) PoolManagerInitializeTest:test_initialize_failsWithIncorrectSelectors() (gas: 1016146) -PoolManagerInitializeTest:test_initialize_fetchFeeWhenController(uint160) (runs: 100, μ: 95685, ~: 95808) -PoolManagerInitializeTest:test_initialize_forNativeTokens(uint160) (runs: 100, μ: 72103, ~: 72328) +PoolManagerInitializeTest:test_initialize_fetchFeeWhenController(uint160) (runs: 100, μ: 95682, ~: 95796) +PoolManagerInitializeTest:test_initialize_forNativeTokens(uint160) (runs: 100, μ: 72084, ~: 72327) PoolManagerInitializeTest:test_initialize_gas() (gas: 87104) -PoolManagerInitializeTest:test_initialize_revertsWhenPoolAlreadyInitialized(uint160) (runs: 100, μ: 65022, ~: 65126) +PoolManagerInitializeTest:test_initialize_revertsWhenPoolAlreadyInitialized(uint160) (runs: 100, μ: 65002, ~: 65125) PoolManagerInitializeTest:test_initialize_revertsWithIdenticalTokens(uint160) (runs: 100, μ: 22624, ~: 22624) PoolManagerInitializeTest:test_initialize_revertsWithSameTokenCombo(uint160) (runs: 100, μ: 27702, ~: 27702) PoolManagerInitializeTest:test_initialize_succeedsWithCorrectSelectors() (gas: 1012968) -PoolManagerInitializeTest:test_initialize_succeedsWithEmptyHooks(uint160) (runs: 100, μ: 978625, ~: 978758) -PoolManagerInitializeTest:test_initialize_succeedsWithHooks(uint160) (runs: 100, μ: 8937393460516839818, ~: 8937393460516839946) -PoolManagerInitializeTest:test_initialize_succeedsWithMaxTickSpacing(uint160) (runs: 100, μ: 65790, ~: 65895) +PoolManagerInitializeTest:test_initialize_succeedsWithEmptyHooks(uint160) (runs: 100, μ: 978646, ~: 978759) +PoolManagerInitializeTest:test_initialize_succeedsWithHooks(uint160) (runs: 100, μ: 8937393460516839828, ~: 8937393460516839948) +PoolManagerInitializeTest:test_initialize_succeedsWithMaxTickSpacing(uint160) (runs: 100, μ: 65781, ~: 65895) PoolManagerReentrancyTest:testParallelLocker() (gas: 1928666) PoolManagerReentrancyTest:testSimpleLinearLocker() (gas: 389802) PoolManagerReentrancyTest:testTokenLocker() (gas: 566969) PoolManagerReentrancyTest:testTokenRevert() (gas: 585663) PoolManagerTest:test_bytecodeSize() (gas: 12194) -PoolManagerTest:test_collectProtocolFees_ERC20_allowsOwnerToAccumulateFees_gas() (gas: 288812) -PoolManagerTest:test_collectProtocolFees_ERC20_returnsAllFeesIf0IsProvidedAsParameter() (gas: 253804) +PoolManagerTest:test_collectProtocolFees_ERC20_allowsOwnerToAccumulateFees_gas() (gas: 287300) +PoolManagerTest:test_collectProtocolFees_ERC20_returnsAllFeesIf0IsProvidedAsParameter() (gas: 251913) PoolManagerTest:test_collectProtocolFees_initializesWithProtocolFeeIfCalled() (gas: 87808) -PoolManagerTest:test_collectProtocolFees_nativeToken_allowsOwnerToAccumulateFees_gas() (gas: 286480) -PoolManagerTest:test_collectProtocolFees_nativeToken_returnsAllFeesIf0IsProvidedAsParameter() (gas: 250815) -PoolManagerTest:test_donate_OneToken_gas() (gas: 147480) -PoolManagerTest:test_donate_failsIfNoLiquidity(uint160) (runs: 100, μ: 117023, ~: 117126) -PoolManagerTest:test_donate_failsIfNotInitialized() (gas: 62018) -PoolManagerTest:test_donate_failsWithIncorrectSelectors() (gas: 1443632) -PoolManagerTest:test_donate_succeedsForNativeTokensWhenPoolHasLiquidity() (gas: 160210) -PoolManagerTest:test_donate_succeedsWhenPoolHasLiquidity() (gas: 205072) -PoolManagerTest:test_donate_succeedsWithCorrectSelectors() (gas: 1406005) -PoolManagerTest:test_feeControllerSet() (gas: 5134260) +PoolManagerTest:test_collectProtocolFees_nativeToken_allowsOwnerToAccumulateFees_gas() (gas: 284968) +PoolManagerTest:test_collectProtocolFees_nativeToken_returnsAllFeesIf0IsProvidedAsParameter() (gas: 248924) +PoolManagerTest:test_donate_OneToken_gas() (gas: 145601) +PoolManagerTest:test_donate_failsIfNoLiquidity(uint160) (runs: 100, μ: 115102, ~: 115246) +PoolManagerTest:test_donate_failsIfNotInitialized() (gas: 60139) +PoolManagerTest:test_donate_failsWithIncorrectSelectors() (gas: 1422026) +PoolManagerTest:test_donate_succeedsForNativeTokensWhenPoolHasLiquidity() (gas: 158331) +PoolManagerTest:test_donate_succeedsWhenPoolHasLiquidity() (gas: 203569) +PoolManagerTest:test_donate_succeedsWithCorrectSelectors() (gas: 1384278) +PoolManagerTest:test_feeControllerSet() (gas: 5182601) PoolManagerTest:test_getPosition() (gas: 24382) PoolManagerTest:test_lock_EmitsCorrectId() (gas: 18848) PoolManagerTest:test_lock_NoOpIsOk() (gas: 50332) -PoolManagerTest:test_mint_failsIfNotInitialized() (gas: 37511) -PoolManagerTest:test_mint_failsWithIncorrectSelectors() (gas: 1311691) -PoolManagerTest:test_mint_gas() (gas: 196755) -PoolManagerTest:test_mint_succeedsForNativeTokensIfInitialized(uint160) (runs: 100, μ: 166009, ~: 166009) -PoolManagerTest:test_mint_succeedsIfInitialized(uint160) (runs: 100, μ: 165931, ~: 165931) -PoolManagerTest:test_mint_succeedsWithCorrectSelectors() (gas: 1303428) -PoolManagerTest:test_mint_succeedsWithHooksIfInitialized(uint160) (runs: 100, μ: 8937393460517141358, ~: 8937393460517142954) -PoolManagerTest:test_mint_withHooks_gas() (gas: 1299944) -PoolManagerTest:test_mint_withNative_gas() (gas: 196869) +PoolManagerTest:test_mint_failsIfNotInitialized() (gas: 35632) +PoolManagerTest:test_mint_failsWithIncorrectSelectors() (gas: 1267995) +PoolManagerTest:test_mint_gas() (gas: 195252) +PoolManagerTest:test_mint_succeedsForNativeTokensIfInitialized(uint160) (runs: 100, μ: 164130, ~: 164130) +PoolManagerTest:test_mint_succeedsIfInitialized(uint160) (runs: 100, μ: 164052, ~: 164052) +PoolManagerTest:test_mint_succeedsWithCorrectSelectors() (gas: 1281580) +PoolManagerTest:test_mint_succeedsWithHooksIfInitialized(uint160) (runs: 100, μ: 8937393460517119519, ~: 8937393460517121112) +PoolManagerTest:test_mint_withHooks_gas() (gas: 1278096) +PoolManagerTest:test_mint_withNative_gas() (gas: 195366) PoolManagerTest:test_setProtocolFee_updatesProtocolFeeForInitializedPool() (gas: 70482) -PoolManagerTest:test_swap_GasMintClaimIfOutputNotTaken() (gas: 215998) -PoolManagerTest:test_swap_GasUseClaimAsInput() (gas: 321861) -PoolManagerTest:test_swap_againstLiqWithNative_gas() (gas: 331574) -PoolManagerTest:test_swap_againstLiq_gas() (gas: 287090) -PoolManagerTest:test_swap_failsIfNotInitialized(uint160) (runs: 100, μ: 68557, ~: 68557) -PoolManagerTest:test_swap_failsWithIncorrectSelectors() (gas: 1443741) -PoolManagerTest:test_swap_gas() (gas: 199816) -PoolManagerTest:test_swap_succeedsIfInitialized() (gas: 181470) -PoolManagerTest:test_swap_succeedsWithCorrectSelectors() (gas: 1429161) -PoolManagerTest:test_swap_succeedsWithHooksIfInitialized() (gas: 8937393460517312635) -PoolManagerTest:test_swap_succeedsWithNativeTokensIfInitialized() (gas: 172912) -PoolManagerTest:test_swap_withHooks_gas() (gas: 1474017) -PoolManagerTest:test_swap_withNative_gas() (gas: 192961) -PoolManagerTest:test_take_failsWithInvalidTokensThatDoNotReturnTrueOnTransfer() (gas: 892683) -PoolManagerTest:test_take_failsWithNoLiquidity() (gas: 11528036) +PoolManagerTest:test_swap_GasMintClaimIfOutputNotTaken() (gas: 214485) +PoolManagerTest:test_swap_GasUseClaimAsInput() (gas: 320436) +PoolManagerTest:test_swap_againstLiqWithNative_gas() (gas: 330148) +PoolManagerTest:test_swap_againstLiq_gas() (gas: 285664) +PoolManagerTest:test_swap_failsIfNotInitialized(uint160) (runs: 100, μ: 66678, ~: 66678) +PoolManagerTest:test_swap_failsWithIncorrectSelectors() (gas: 1422123) +PoolManagerTest:test_swap_gas() (gas: 198303) +PoolManagerTest:test_swap_succeedsIfInitialized() (gas: 179579) +PoolManagerTest:test_swap_succeedsWithCorrectSelectors() (gas: 1407422) +PoolManagerTest:test_swap_succeedsWithHooksIfInitialized() (gas: 8937393460517290896) +PoolManagerTest:test_swap_succeedsWithNativeTokensIfInitialized() (gas: 171021) +PoolManagerTest:test_swap_withHooks_gas() (gas: 1452387) +PoolManagerTest:test_swap_withNative_gas() (gas: 191448) +PoolManagerTest:test_take_failsWithInvalidTokensThatDoNotReturnTrueOnTransfer() (gas: 890804) +PoolManagerTest:test_take_failsWithNoLiquidity() (gas: 11576377) PoolManagerTest:test_take_succeedsWithPoolWithLiquidity() (gas: 119510) PoolManagerTest:test_take_succeedsWithPoolWithLiquidityWithNativeToken() (gas: 115643) PoolTest:testModifyPosition(uint160,(address,int24,int24,int128,int24)) (runs: 100, μ: 19917, ~: 7542) -PoolTest:testPoolInitialize(uint160,uint16,uint16,uint24) (runs: 100, μ: 16932, ~: 6430) +PoolTest:testPoolInitialize(uint160,uint16,uint16,uint24) (runs: 100, μ: 16678, ~: 6430) PoolTest:testSwap(uint160,uint24,(int24,bool,int256,uint160)) (runs: 100, μ: 212342, ~: 7874) SafeCastTest:testToInt128(int256) (runs: 100, μ: 1453, ~: 445) SafeCastTest:testToInt128(uint256) (runs: 100, μ: 1150, ~: 390) @@ -267,11 +270,11 @@ TestDelegateCall:testCannotDelegateCallPrivateMethodWithModifier() (gas: 10215) TestDelegateCall:testDelegateCallNoModifier() (gas: 5734) TestDelegateCall:testDelegateCallWithModifier() (gas: 10172) TestDelegateCall:testGasOverhead() (gas: 13709) -TestDynamicFees:testCacheDynamicFeeAndSwap() (gas: 270801) -TestDynamicFees:testDynamicFeeAndBeforeSwapHook() (gas: 265086) -TestDynamicFees:testDynamicFeesCacheNoOtherHooks() (gas: 487659) +TestDynamicFees:testCacheDynamicFeeAndSwap() (gas: 269100) +TestDynamicFees:testDynamicFeeAndBeforeSwapHook() (gas: 263385) +TestDynamicFees:testDynamicFeesCacheNoOtherHooks() (gas: 483020) TestDynamicFees:testPoolInitializeFailsWithTooLargeFee() (gas: 1741124) -TestDynamicFees:testSwapWorks() (gas: 219502) +TestDynamicFees:testSwapWorks() (gas: 217801) TestDynamicFees:testUpdateFailsWithTooLargeFee() (gas: 27209) TestDynamicFees:testUpdateRevertsOnStaticFeePool() (gas: 65499) TickBitmapTest:test_flipTick_flipsOnlyTheSpecifiedTick() (gas: 16607) diff --git a/foundry.toml b/foundry.toml index 2ac5730b6..7726681e0 100644 --- a/foundry.toml +++ b/foundry.toml @@ -6,7 +6,7 @@ fs_permissions = [{ access = "read-write", path = ".forge-snapshots/"}, { access cancun = true [profile.default.fuzz] -runs = 1000 +runs = 100 seed = "0x4444" [profile.ci.fuzz] diff --git a/src/PoolManager.sol b/src/PoolManager.sol index 816c1ebe4..9c998e794 100644 --- a/src/PoolManager.sol +++ b/src/PoolManager.sol @@ -21,6 +21,7 @@ import {Claims} from "./Claims.sol"; import {PoolId, PoolIdLibrary} from "./types/PoolId.sol"; import {BalanceDelta} from "./types/BalanceDelta.sol"; import {Lockers} from "./libraries/Lockers.sol"; +import {CurrentHookAddress} from "./libraries/CurrentHookAddress.sol"; /// @notice Holds the state for all pools contract PoolManager is IPoolManager, Fees, NoDelegateCall, Claims { @@ -179,7 +180,7 @@ contract PoolManager is IPoolManager, Fees, NoDelegateCall, Claims { // todo fix stack too deep :/ address locker = Lockers.getCurrentLocker(); if (msg.sender != locker) { - if (msg.sender != currentHook || !Hooks.shouldAccessLock(IHooks(currentHook))) { + if (msg.sender != CurrentHookAddress.get() || !Hooks.shouldAccessLock(IHooks(CurrentHookAddress.get()))) { revert LockedBy(locker); } } @@ -192,7 +193,7 @@ contract PoolManager is IPoolManager, Fees, NoDelegateCall, Claims { IPoolManager.ModifyPositionParams memory params, bytes calldata hookData ) external override noDelegateCall onlyByLocker returns (BalanceDelta delta) { - _setCurrentHook(address(key.hooks)); + CurrentHookAddress.set(address(key.hooks)); if (key.hooks.shouldCallBeforeModifyPosition()) { if ( @@ -252,7 +253,7 @@ contract PoolManager is IPoolManager, Fees, NoDelegateCall, Claims { onlyByLocker returns (BalanceDelta delta) { - _setCurrentHook(address(key.hooks)); + CurrentHookAddress.set(address(key.hooks)); if (key.hooks.shouldCallBeforeSwap()) { if (key.hooks.beforeSwap(msg.sender, key, params, hookData) != IHooks.beforeSwap.selector) { @@ -306,7 +307,7 @@ contract PoolManager is IPoolManager, Fees, NoDelegateCall, Claims { onlyByLocker returns (BalanceDelta delta) { - _setCurrentHook(address(key.hooks)); + CurrentHookAddress.set(address(key.hooks)); if (key.hooks.shouldCallBeforeDonate()) { if (key.hooks.beforeDonate(msg.sender, key, amount0, amount1, hookData) != IHooks.beforeDonate.selector) { @@ -406,11 +407,6 @@ contract PoolManager is IPoolManager, Fees, NoDelegateCall, Claims { return Lockers.nonzeroDeltaCount(); } - // TODO: Use transient storage - function _setCurrentHook(address hookAddr) internal { - if (currentHook != hookAddr) currentHook = hookAddr; - } - /// @notice receive native tokens for native pools receive() external payable {} } diff --git a/src/libraries/CurrentHookAddress.sol b/src/libraries/CurrentHookAddress.sol new file mode 100644 index 000000000..55b673f03 --- /dev/null +++ b/src/libraries/CurrentHookAddress.sol @@ -0,0 +1,23 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.20; + +// TODO: Remove this library once the `transient` keyword is supported in solidity. +library CurrentHookAddress { + uint256 constant HOOK_ADDRESS_SLOT = uint256(keccak256("HookAddress")) - 1; + + function get() internal view returns (address _address) { + uint256 slot = HOOK_ADDRESS_SLOT; + assembly { + _address := tload(slot) + } + } + + function set(address _address) internal { + if (_address != get()) { + uint256 slot = HOOK_ADDRESS_SLOT; + assembly { + tstore(slot, _address) + } + } + } +} diff --git a/src/test/AccessLockHook.sol b/src/test/AccessLockHook.sol index a04878ac2..ed8d2b0f3 100644 --- a/src/test/AccessLockHook.sol +++ b/src/test/AccessLockHook.sol @@ -9,8 +9,6 @@ import {CurrencyLibrary, Currency} from "../types/Currency.sol"; import {Hooks} from "../libraries/Hooks.sol"; import {TickMath} from "../libraries/TickMath.sol"; -import "forge-std/console2.sol"; - contract AccessLockHook is BaseTestHooks { using CurrencyLibrary for Currency; @@ -67,8 +65,6 @@ contract AccessLockHook is BaseTestHooks { if (action == LockAction.Mint) { manager.mint(key.currency1, address(this), amount); } else if (action == LockAction.Take) { - console2.log("TAKE"); - console2.log(key.currency1.balanceOf(address(manager))); manager.take(key.currency1, address(this), amount); } else if (action == LockAction.Donate) { manager.donate(key, amount, amount, new bytes(0)); diff --git a/test/AccessLock.t.sol b/test/AccessLock.t.sol index 1e85220e0..9e641ace3 100644 --- a/test/AccessLock.t.sol +++ b/test/AccessLock.t.sol @@ -18,8 +18,6 @@ import {BalanceDelta} from "../src/types/BalanceDelta.sol"; import {Pool} from "../src/libraries/Pool.sol"; import {TickMath} from "../src/libraries/TickMath.sol"; -import "forge-std/console2.sol"; - contract AccessLockTest is Test, Deployers { using Pool for Pool.State; using CurrencyLibrary for Currency; diff --git a/test/CurrentHookAddress.t.sol b/test/CurrentHookAddress.t.sol new file mode 100644 index 000000000..b0403ccfc --- /dev/null +++ b/test/CurrentHookAddress.t.sol @@ -0,0 +1,23 @@ +// SPDX-License-Identifier: UNLICENSED +pragma solidity ^0.8.20; + +import {Test} from "forge-std/Test.sol"; +import {CurrentHookAddress} from "../src/libraries/CurrentHookAddress.sol"; + +contract CurrentHookAddressTest is Test { + function test_get_currentHookAddress() public { + assertEq(CurrentHookAddress.get(), address(0)); + } + + function test_set_currentHookAddress() public { + CurrentHookAddress.set(address(1)); + assertEq(CurrentHookAddress.get(), address(1)); + } + + function test_set_currentHookAddressTwice() public { + CurrentHookAddress.set(address(1)); + CurrentHookAddress.set(address(2)); + + assertEq(CurrentHookAddress.get(), address(2)); + } +}