From 1b71d99224e73ec6d5f3148d47abed4d36ae2b61 Mon Sep 17 00:00:00 2001 From: Diana Kocsis Date: Mon, 11 Mar 2024 18:14:40 -0400 Subject: [PATCH 01/14] skip calls to hooks when msg.sender is hook contract + test --- .../addLiquidity with empty hook.snap | 2 +- .../addLiquidity with native token.snap | 2 +- .forge-snapshots/addLiquidity.snap | 2 +- ...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/initialize.snap | 2 +- .../poolManager bytecode size.snap | 2 +- .../removeLiquidity with empty hook.snap | 2 +- .../removeLiquidity with native token.snap | 2 +- .forge-snapshots/removeLiquidity.snap | 2 +- .forge-snapshots/simple swap with native.snap | 2 +- .forge-snapshots/simple swap.snap | 2 +- ...p against liquidity with native token.snap | 2 +- .forge-snapshots/swap against liquidity.snap | 2 +- .../swap burn 6909 for input.snap | 2 +- .../swap burn native 6909 for input.snap | 2 +- .../swap mint native output as 6909.snap | 2 +- .../swap mint output as 6909.snap | 2 +- .forge-snapshots/swap with dynamic fee.snap | 2 +- .forge-snapshots/swap with hooks.snap | 2 +- .../update dynamic fee in before swap.snap | 2 +- src/libraries/Hooks.sol | 28 +++++--- src/test/PoolSwapTest.sol | 3 - src/test/SkipCallsTestHook.sol | 62 ++++++++++++++++ test/SkipCallsTestHook.t.sol | 70 +++++++++++++++++++ 27 files changed, 173 insertions(+), 36 deletions(-) create mode 100644 src/test/SkipCallsTestHook.sol create mode 100644 test/SkipCallsTestHook.t.sol diff --git a/.forge-snapshots/addLiquidity with empty hook.snap b/.forge-snapshots/addLiquidity with empty hook.snap index c55f79c35..c538b3737 100644 --- a/.forge-snapshots/addLiquidity with empty hook.snap +++ b/.forge-snapshots/addLiquidity with empty hook.snap @@ -1 +1 @@ -312292 \ No newline at end of file +312376 \ No newline at end of file diff --git a/.forge-snapshots/addLiquidity with native token.snap b/.forge-snapshots/addLiquidity with native token.snap index fe6333627..82ad8f5b0 100644 --- a/.forge-snapshots/addLiquidity with native token.snap +++ b/.forge-snapshots/addLiquidity with native token.snap @@ -1 +1 @@ -192474 \ No newline at end of file +192536 \ No newline at end of file diff --git a/.forge-snapshots/addLiquidity.snap b/.forge-snapshots/addLiquidity.snap index fe4feafa6..ac7f1b8bc 100644 --- a/.forge-snapshots/addLiquidity.snap +++ b/.forge-snapshots/addLiquidity.snap @@ -1 +1 @@ -192452 \ No newline at end of file +192514 \ No newline at end of file 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 de82223f9..f9288ed87 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 @@ -184412 \ No newline at end of file +184368 \ 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 f44c9bfc3..e6043d4f3 100644 --- a/.forge-snapshots/cached dynamic fee, no hooks.snap +++ b/.forge-snapshots/cached dynamic fee, no hooks.snap @@ -1 +1 @@ -138439 \ No newline at end of file +138364 \ 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 870ff5314..993bb79cd 100644 --- a/.forge-snapshots/donate gas with 1 token.snap +++ b/.forge-snapshots/donate gas with 1 token.snap @@ -1 +1 @@ -131592 \ No newline at end of file +131626 \ 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 df44666f1..d3a35246a 100644 --- a/.forge-snapshots/donate gas with 2 tokens.snap +++ b/.forge-snapshots/donate gas with 2 tokens.snap @@ -1 +1 @@ -176613 \ No newline at end of file +176647 \ No newline at end of file diff --git a/.forge-snapshots/initialize.snap b/.forge-snapshots/initialize.snap index c735b0154..df1ae0e82 100644 --- a/.forge-snapshots/initialize.snap +++ b/.forge-snapshots/initialize.snap @@ -1 +1 @@ -51767 \ No newline at end of file +51819 \ No newline at end of file diff --git a/.forge-snapshots/poolManager bytecode size.snap b/.forge-snapshots/poolManager bytecode size.snap index b46643dff..69f3b20a2 100644 --- a/.forge-snapshots/poolManager bytecode size.snap +++ b/.forge-snapshots/poolManager bytecode size.snap @@ -1 +1 @@ -23279 \ No newline at end of file +23469 \ No newline at end of file diff --git a/.forge-snapshots/removeLiquidity with empty hook.snap b/.forge-snapshots/removeLiquidity with empty hook.snap index 19ecf14d0..989679318 100644 --- a/.forge-snapshots/removeLiquidity with empty hook.snap +++ b/.forge-snapshots/removeLiquidity with empty hook.snap @@ -1 +1 @@ -99307 \ No newline at end of file +99369 \ No newline at end of file diff --git a/.forge-snapshots/removeLiquidity with native token.snap b/.forge-snapshots/removeLiquidity with native token.snap index 6e30c7e62..fd774ae8d 100644 --- a/.forge-snapshots/removeLiquidity with native token.snap +++ b/.forge-snapshots/removeLiquidity with native token.snap @@ -1 +1 @@ -200680 \ No newline at end of file +200742 \ No newline at end of file diff --git a/.forge-snapshots/removeLiquidity.snap b/.forge-snapshots/removeLiquidity.snap index 6df5fee55..201f4a58b 100644 --- a/.forge-snapshots/removeLiquidity.snap +++ b/.forge-snapshots/removeLiquidity.snap @@ -1 +1 @@ -196957 \ No newline at end of file +197019 \ 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 a0e246dd6..32b976624 100644 --- a/.forge-snapshots/simple swap with native.snap +++ b/.forge-snapshots/simple swap with native.snap @@ -1 +1 @@ -187012 \ No newline at end of file +186937 \ No newline at end of file diff --git a/.forge-snapshots/simple swap.snap b/.forge-snapshots/simple swap.snap index 5cbe74530..2292d6a90 100644 --- a/.forge-snapshots/simple swap.snap +++ b/.forge-snapshots/simple swap.snap @@ -1 +1 @@ -195549 \ No newline at end of file +195474 \ 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 eeb6c5502..9ec93e937 100644 --- a/.forge-snapshots/swap against liquidity with native token.snap +++ b/.forge-snapshots/swap against liquidity with native token.snap @@ -1 +1 @@ -117675 \ No newline at end of file +117600 \ No newline at end of file diff --git a/.forge-snapshots/swap against liquidity.snap b/.forge-snapshots/swap against liquidity.snap index 7f9fabec9..05da5bb94 100644 --- a/.forge-snapshots/swap against liquidity.snap +++ b/.forge-snapshots/swap against liquidity.snap @@ -1 +1 @@ -105139 \ No newline at end of file +105064 \ No newline at end of file diff --git a/.forge-snapshots/swap burn 6909 for input.snap b/.forge-snapshots/swap burn 6909 for input.snap index 69ff2383b..8a6c5325e 100644 --- a/.forge-snapshots/swap burn 6909 for input.snap +++ b/.forge-snapshots/swap burn 6909 for input.snap @@ -1 +1 @@ -125350 \ No newline at end of file +125275 \ No newline at end of file diff --git a/.forge-snapshots/swap burn native 6909 for input.snap b/.forge-snapshots/swap burn native 6909 for input.snap index db82f9839..3038ea02f 100644 --- a/.forge-snapshots/swap burn native 6909 for input.snap +++ b/.forge-snapshots/swap burn native 6909 for input.snap @@ -1 +1 @@ -121303 \ No newline at end of file +121228 \ No newline at end of file diff --git a/.forge-snapshots/swap mint native output as 6909.snap b/.forge-snapshots/swap mint native output as 6909.snap index 61a67212b..ff3658046 100644 --- a/.forge-snapshots/swap mint native output as 6909.snap +++ b/.forge-snapshots/swap mint native output as 6909.snap @@ -1 +1 @@ -189538 \ No newline at end of file +189463 \ No newline at end of file diff --git a/.forge-snapshots/swap mint output as 6909.snap b/.forge-snapshots/swap mint output as 6909.snap index a5132bdf8..dc3f4d32f 100644 --- a/.forge-snapshots/swap mint output as 6909.snap +++ b/.forge-snapshots/swap mint output as 6909.snap @@ -1 +1 @@ -206343 \ No newline at end of file +206268 \ 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 2f0bba28d..a21aab27e 100644 --- a/.forge-snapshots/swap with dynamic fee.snap +++ b/.forge-snapshots/swap with dynamic fee.snap @@ -1 +1 @@ -183513 \ No newline at end of file +183469 \ No newline at end of file diff --git a/.forge-snapshots/swap with hooks.snap b/.forge-snapshots/swap with hooks.snap index 0c9c98a4d..2b2e734cd 100644 --- a/.forge-snapshots/swap with hooks.snap +++ b/.forge-snapshots/swap with hooks.snap @@ -1 +1 @@ -105117 \ No newline at end of file +105042 \ 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 8ed16188b..bea3574d9 100644 --- a/.forge-snapshots/update dynamic fee in before swap.snap +++ b/.forge-snapshots/update dynamic fee in before swap.snap @@ -1 +1 @@ -190217 \ No newline at end of file +190173 \ No newline at end of file diff --git a/src/libraries/Hooks.sol b/src/libraries/Hooks.sol index 82a6e88c9..8524a9771 100644 --- a/src/libraries/Hooks.sol +++ b/src/libraries/Hooks.sol @@ -107,7 +107,7 @@ library Hooks { function beforeInitialize(IHooks self, PoolKey memory key, uint160 sqrtPriceX96, bytes calldata hookData) internal { - if (self.hasPermission(BEFORE_INITIALIZE_FLAG)) { + if (self.hasPermission(BEFORE_INITIALIZE_FLAG) && (msg.sender != address(self))) { self.callHook( abi.encodeWithSelector(IHooks.beforeInitialize.selector, msg.sender, key, sqrtPriceX96, hookData) ); @@ -118,7 +118,7 @@ library Hooks { function afterInitialize(IHooks self, PoolKey memory key, uint160 sqrtPriceX96, int24 tick, bytes calldata hookData) internal { - if (self.hasPermission(AFTER_INITIALIZE_FLAG)) { + if (self.hasPermission(AFTER_INITIALIZE_FLAG) && (msg.sender != address(self))) { self.callHook( abi.encodeWithSelector(IHooks.afterInitialize.selector, msg.sender, key, sqrtPriceX96, tick, hookData) ); @@ -132,9 +132,13 @@ library Hooks { IPoolManager.ModifyLiquidityParams memory params, bytes calldata hookData ) internal { - if (params.liquidityDelta > 0 && key.hooks.hasPermission(BEFORE_ADD_LIQUIDITY_FLAG)) { + if (params.liquidityDelta > 0 && self.hasPermission(BEFORE_ADD_LIQUIDITY_FLAG) && (msg.sender != address(self))) + { self.callHook(abi.encodeWithSelector(IHooks.beforeAddLiquidity.selector, msg.sender, key, params, hookData)); - } else if (params.liquidityDelta <= 0 && key.hooks.hasPermission(BEFORE_REMOVE_LIQUIDITY_FLAG)) { + } else if ( + params.liquidityDelta <= 0 && self.hasPermission(BEFORE_REMOVE_LIQUIDITY_FLAG) + && (msg.sender != address(self)) + ) { self.callHook( abi.encodeWithSelector(IHooks.beforeRemoveLiquidity.selector, msg.sender, key, params, hookData) ); @@ -149,11 +153,15 @@ library Hooks { BalanceDelta delta, bytes calldata hookData ) internal { - if (params.liquidityDelta > 0 && key.hooks.hasPermission(AFTER_ADD_LIQUIDITY_FLAG)) { + if (params.liquidityDelta > 0 && self.hasPermission(AFTER_ADD_LIQUIDITY_FLAG) && (msg.sender != address(self))) + { self.callHook( abi.encodeWithSelector(IHooks.afterAddLiquidity.selector, msg.sender, key, params, delta, hookData) ); - } else if (params.liquidityDelta <= 0 && key.hooks.hasPermission(AFTER_REMOVE_LIQUIDITY_FLAG)) { + } else if ( + params.liquidityDelta <= 0 && self.hasPermission(AFTER_REMOVE_LIQUIDITY_FLAG) + && (msg.sender != address(self)) + ) { self.callHook( abi.encodeWithSelector(IHooks.afterRemoveLiquidity.selector, msg.sender, key, params, delta, hookData) ); @@ -164,7 +172,7 @@ library Hooks { function beforeSwap(IHooks self, PoolKey memory key, IPoolManager.SwapParams memory params, bytes calldata hookData) internal { - if (key.hooks.hasPermission(BEFORE_SWAP_FLAG)) { + if (self.hasPermission(BEFORE_SWAP_FLAG) && (msg.sender != address(self))) { self.callHook(abi.encodeWithSelector(IHooks.beforeSwap.selector, msg.sender, key, params, hookData)); } } @@ -177,7 +185,7 @@ library Hooks { BalanceDelta delta, bytes calldata hookData ) internal { - if (key.hooks.hasPermission(AFTER_SWAP_FLAG)) { + if (self.hasPermission(AFTER_SWAP_FLAG) && (msg.sender != address(self))) { self.callHook(abi.encodeWithSelector(IHooks.afterSwap.selector, msg.sender, key, params, delta, hookData)); } } @@ -186,7 +194,7 @@ library Hooks { function beforeDonate(IHooks self, PoolKey memory key, uint256 amount0, uint256 amount1, bytes calldata hookData) internal { - if (key.hooks.hasPermission(BEFORE_DONATE_FLAG)) { + if (self.hasPermission(BEFORE_DONATE_FLAG) && (msg.sender != address(self))) { self.callHook( abi.encodeWithSelector(IHooks.beforeDonate.selector, msg.sender, key, amount0, amount1, hookData) ); @@ -197,7 +205,7 @@ library Hooks { function afterDonate(IHooks self, PoolKey memory key, uint256 amount0, uint256 amount1, bytes calldata hookData) internal { - if (key.hooks.hasPermission(AFTER_DONATE_FLAG)) { + if (self.hasPermission(AFTER_DONATE_FLAG) && (msg.sender != address(self))) { self.callHook( abi.encodeWithSelector(IHooks.afterDonate.selector, msg.sender, key, amount0, amount1, hookData) ); diff --git a/src/test/PoolSwapTest.sol b/src/test/PoolSwapTest.sol index 960cb6bd5..7f203af20 100644 --- a/src/test/PoolSwapTest.sol +++ b/src/test/PoolSwapTest.sol @@ -66,9 +66,6 @@ contract PoolSwapTest is Test, PoolTestBase { (,, uint256 reserveAfter0, int256 deltaAfter0) = _fetchBalances(data.key.currency0, data.sender, address(this)); (,, uint256 reserveAfter1, int256 deltaAfter1) = _fetchBalances(data.key.currency1, data.sender, address(this)); - assertEq(reserveBefore0, reserveAfter0); - assertEq(reserveBefore1, reserveAfter1); - if (data.params.zeroForOne) { if (data.params.amountSpecified > 0) { // exact input, 0 for 1 diff --git a/src/test/SkipCallsTestHook.sol b/src/test/SkipCallsTestHook.sol new file mode 100644 index 000000000..673cd2da4 --- /dev/null +++ b/src/test/SkipCallsTestHook.sol @@ -0,0 +1,62 @@ +// SPDX-License-Identifier: UNLICENSED +pragma solidity ^0.8.24; + +import {Hooks} from "../libraries/Hooks.sol"; +import {BaseTestHooks} from "./BaseTestHooks.sol"; +import {IHooks} from "../interfaces/IHooks.sol"; +import {IPoolManager} from "../interfaces/IPoolManager.sol"; +import {PoolKey} from "../types/PoolKey.sol"; +import {BalanceDelta} from "../types/BalanceDelta.sol"; +import {PoolId, PoolIdLibrary} from "../types/PoolId.sol"; +import {FeeLibrary} from "../../src/libraries/FeeLibrary.sol"; +import {IERC20Minimal} from "../interfaces/external/IERC20Minimal.sol"; +import {CurrencyLibrary, Currency} from "../types/Currency.sol"; +import {PoolTestBase} from "./PoolTestBase.sol"; +import {Test} from "forge-std/Test.sol"; +import "forge-std/console.sol"; + +contract SkipCallsTestHook is BaseTestHooks, Test { + using PoolIdLibrary for PoolKey; + using Hooks for IHooks; + using FeeLibrary for uint24; + + uint256 public counter; + IPoolManager manager; + uint24 internal fee; + + constructor() {} + + function setManager(IPoolManager _manager) external { + manager = _manager; + } + + function setFee(uint24 _fee) external { + fee = _fee; + } + + function getFee(address, PoolKey calldata) public view returns (uint24) { + return fee; + } + + function beforeSwap(address, PoolKey calldata key, IPoolManager.SwapParams calldata params, bytes calldata hookData) + external + override + returns (bytes4) + { + counter++; + callSwap(key, params, hookData); + return IHooks.beforeSwap.selector; + } + + function callSwap(PoolKey calldata key, IPoolManager.SwapParams calldata params, bytes calldata hookData) public { + IPoolManager(msg.sender).swap(key, params, hookData); + address payer = abi.decode(hookData, (address)); + int256 delta0 = IPoolManager(msg.sender).currencyDelta(address(this), key.currency0); + assertEq(delta0, params.amountSpecified); + int256 delta1 = IPoolManager(msg.sender).currencyDelta(address(this), key.currency1); + assert(delta1 < 0); + IERC20Minimal(Currency.unwrap(key.currency0)).transferFrom(payer, msg.sender, uint256(delta0)); + manager.settle(key.currency0); + manager.take(key.currency1, payer, uint256(-delta1)); + } +} diff --git a/test/SkipCallsTestHook.t.sol b/test/SkipCallsTestHook.t.sol new file mode 100644 index 000000000..80b739711 --- /dev/null +++ b/test/SkipCallsTestHook.t.sol @@ -0,0 +1,70 @@ +// SPDX-License-Identifier: UNLICENSED +pragma solidity ^0.8.20; + +import {Test} from "forge-std/Test.sol"; +import {Vm} from "forge-std/Vm.sol"; +import {PoolId, PoolIdLibrary} from "../src/types/PoolId.sol"; +import {Hooks} from "../src/libraries/Hooks.sol"; +import {FeeLibrary} from "../src/libraries/FeeLibrary.sol"; +import {IPoolManager} from "../src/interfaces/IPoolManager.sol"; +import {IFees} from "../src/interfaces/IFees.sol"; +import {IHooks} from "../src/interfaces/IHooks.sol"; +import {PoolKey} from "../src/types/PoolKey.sol"; +import {PoolManager} from "../src/PoolManager.sol"; +import {PoolSwapTest} from "../src/test/PoolSwapTest.sol"; +import {Deployers} from "./utils/Deployers.sol"; +import {IDynamicFeeManager} from "././../src/interfaces/IDynamicFeeManager.sol"; +import {GasSnapshot} from "forge-gas-snapshot/GasSnapshot.sol"; +import {DynamicFeesTestHook} from "../src/test/DynamicFeesTestHook.sol"; +import {Currency, CurrencyLibrary} from "../src/types/Currency.sol"; +import {MockERC20} from "solmate/test/utils/mocks/MockERC20.sol"; +import {Constants} from "../test/utils/Constants.sol"; +import {SkipCallsTestHook} from "../src/test/SkipCallsTestHook.sol"; + +contract SkipCallsTest is Test, Deployers, GasSnapshot { + using PoolIdLibrary for PoolKey; + + /// 1111 1111 1100 + SkipCallsTestHook skipCallsTestHook = SkipCallsTestHook( + address( + uint160(0xFFfFfFffFFfffFFfFFfFFFFFffFFFffffFfFFFfF) + & uint160( + ~Hooks.BEFORE_INITIALIZE_FLAG & ~Hooks.AFTER_INITIALIZE_FLAG & ~Hooks.BEFORE_ADD_LIQUIDITY_FLAG + & ~Hooks.AFTER_ADD_LIQUIDITY_FLAG & ~Hooks.BEFORE_REMOVE_LIQUIDITY_FLAG + & ~Hooks.AFTER_REMOVE_LIQUIDITY_FLAG & ~Hooks.AFTER_SWAP_FLAG & ~Hooks.BEFORE_DONATE_FLAG + & ~Hooks.AFTER_DONATE_FLAG + ) + ) + ); + + function setUp() public { + SkipCallsTestHook impl = new SkipCallsTestHook(); + vm.etch(address(skipCallsTestHook), address(impl).code); + deployFreshManagerAndRouters(); + skipCallsTestHook.setManager(IPoolManager(manager)); + + (currency0, currency1) = deployMintAndApprove2Currencies(); + (key,) = initPoolAndAddLiquidity( + currency0, + currency1, + IHooks(address(skipCallsTestHook)), + FeeLibrary.DYNAMIC_FEE_FLAG, + SQRT_RATIO_1_1, + ZERO_BYTES + ); + } + + function test_beforeSwap_invalidSender() public { + IPoolManager.SwapParams memory swapParams = + IPoolManager.SwapParams({zeroForOne: true, amountSpecified: 100, sqrtPriceLimitX96: SQRT_RATIO_1_2}); + + PoolSwapTest.TestSettings memory testSettings = + PoolSwapTest.TestSettings({withdrawTokens: true, settleUsingTransfer: true, currencyAlreadySent: false}); + + MockERC20(Currency.unwrap(key.currency0)).approve(address(skipCallsTestHook), Constants.MAX_UINT256); + + assertEq(skipCallsTestHook.counter(), 0); + swapRouter.swap(key, swapParams, testSettings, abi.encode(address(this))); + assertEq(skipCallsTestHook.counter(), 1); + } +} From cc849f5364a99cfc8cd011ccbec92d1fce1bb908 Mon Sep 17 00:00:00 2001 From: Diana Kocsis Date: Tue, 12 Mar 2024 16:53:26 -0400 Subject: [PATCH 02/14] move into callHook --- .../addLiquidity with empty hook.snap | 2 +- .../addLiquidity with native token.snap | 2 +- .forge-snapshots/addLiquidity.snap | 2 +- ...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/initialize.snap | 2 +- .../poolManager bytecode size.snap | 2 +- .../removeLiquidity with empty hook.snap | 2 +- .../removeLiquidity with native token.snap | 2 +- .forge-snapshots/removeLiquidity.snap | 2 +- .forge-snapshots/simple swap with native.snap | 2 +- .forge-snapshots/simple swap.snap | 2 +- ...p against liquidity with native token.snap | 2 +- .forge-snapshots/swap against liquidity.snap | 2 +- .../swap burn 6909 for input.snap | 2 +- .../swap burn native 6909 for input.snap | 2 +- .../swap mint native output as 6909.snap | 2 +- .../swap mint output as 6909.snap | 2 +- .forge-snapshots/swap with dynamic fee.snap | 2 +- .forge-snapshots/swap with hooks.snap | 2 +- .../update dynamic fee in before swap.snap | 2 +- src/libraries/Hooks.sol | 36 ++++++++----------- src/test/SkipCallsTestHook.sol | 3 -- 25 files changed, 38 insertions(+), 47 deletions(-) diff --git a/.forge-snapshots/addLiquidity with empty hook.snap b/.forge-snapshots/addLiquidity with empty hook.snap index c538b3737..e5013ac3d 100644 --- a/.forge-snapshots/addLiquidity with empty hook.snap +++ b/.forge-snapshots/addLiquidity with empty hook.snap @@ -1 +1 @@ -312376 \ No newline at end of file +312352 \ No newline at end of file diff --git a/.forge-snapshots/addLiquidity with native token.snap b/.forge-snapshots/addLiquidity with native token.snap index 82ad8f5b0..60ecff060 100644 --- a/.forge-snapshots/addLiquidity with native token.snap +++ b/.forge-snapshots/addLiquidity with native token.snap @@ -1 +1 @@ -192536 \ No newline at end of file +192456 \ No newline at end of file diff --git a/.forge-snapshots/addLiquidity.snap b/.forge-snapshots/addLiquidity.snap index ac7f1b8bc..903cd284c 100644 --- a/.forge-snapshots/addLiquidity.snap +++ b/.forge-snapshots/addLiquidity.snap @@ -1 +1 @@ -192514 \ No newline at end of file +192434 \ No newline at end of file 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 f9288ed87..d0637b4c4 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 @@ -184368 \ No newline at end of file +184324 \ 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 e6043d4f3..407a4fe88 100644 --- a/.forge-snapshots/cached dynamic fee, no hooks.snap +++ b/.forge-snapshots/cached dynamic fee, no hooks.snap @@ -1 +1 @@ -138364 \ No newline at end of file +138312 \ 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 993bb79cd..6fc7ea2ad 100644 --- a/.forge-snapshots/donate gas with 1 token.snap +++ b/.forge-snapshots/donate gas with 1 token.snap @@ -1 +1 @@ -131626 \ No newline at end of file +131574 \ 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 d3a35246a..4db500106 100644 --- a/.forge-snapshots/donate gas with 2 tokens.snap +++ b/.forge-snapshots/donate gas with 2 tokens.snap @@ -1 +1 @@ -176647 \ No newline at end of file +176595 \ No newline at end of file diff --git a/.forge-snapshots/initialize.snap b/.forge-snapshots/initialize.snap index df1ae0e82..c735b0154 100644 --- a/.forge-snapshots/initialize.snap +++ b/.forge-snapshots/initialize.snap @@ -1 +1 @@ -51819 \ No newline at end of file +51767 \ No newline at end of file diff --git a/.forge-snapshots/poolManager bytecode size.snap b/.forge-snapshots/poolManager bytecode size.snap index 69f3b20a2..12f7a3f54 100644 --- a/.forge-snapshots/poolManager bytecode size.snap +++ b/.forge-snapshots/poolManager bytecode size.snap @@ -1 +1 @@ -23469 \ No newline at end of file +23263 \ No newline at end of file diff --git a/.forge-snapshots/removeLiquidity with empty hook.snap b/.forge-snapshots/removeLiquidity with empty hook.snap index 989679318..c4d63411c 100644 --- a/.forge-snapshots/removeLiquidity with empty hook.snap +++ b/.forge-snapshots/removeLiquidity with empty hook.snap @@ -1 +1 @@ -99369 \ No newline at end of file +99289 \ No newline at end of file diff --git a/.forge-snapshots/removeLiquidity with native token.snap b/.forge-snapshots/removeLiquidity with native token.snap index fd774ae8d..4d6a3fe37 100644 --- a/.forge-snapshots/removeLiquidity with native token.snap +++ b/.forge-snapshots/removeLiquidity with native token.snap @@ -1 +1 @@ -200742 \ No newline at end of file +200662 \ No newline at end of file diff --git a/.forge-snapshots/removeLiquidity.snap b/.forge-snapshots/removeLiquidity.snap index 201f4a58b..dc983cf60 100644 --- a/.forge-snapshots/removeLiquidity.snap +++ b/.forge-snapshots/removeLiquidity.snap @@ -1 +1 @@ -197019 \ No newline at end of file +196939 \ 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 32b976624..69a5dd8f7 100644 --- a/.forge-snapshots/simple swap with native.snap +++ b/.forge-snapshots/simple swap with native.snap @@ -1 +1 @@ -186937 \ No newline at end of file +186885 \ No newline at end of file diff --git a/.forge-snapshots/simple swap.snap b/.forge-snapshots/simple swap.snap index 2292d6a90..d3e1bd9e1 100644 --- a/.forge-snapshots/simple swap.snap +++ b/.forge-snapshots/simple swap.snap @@ -1 +1 @@ -195474 \ No newline at end of file +195422 \ 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 9ec93e937..42ea3e9ad 100644 --- a/.forge-snapshots/swap against liquidity with native token.snap +++ b/.forge-snapshots/swap against liquidity with native token.snap @@ -1 +1 @@ -117600 \ No newline at end of file +117548 \ No newline at end of file diff --git a/.forge-snapshots/swap against liquidity.snap b/.forge-snapshots/swap against liquidity.snap index 05da5bb94..22c407edc 100644 --- a/.forge-snapshots/swap against liquidity.snap +++ b/.forge-snapshots/swap against liquidity.snap @@ -1 +1 @@ -105064 \ No newline at end of file +105012 \ No newline at end of file diff --git a/.forge-snapshots/swap burn 6909 for input.snap b/.forge-snapshots/swap burn 6909 for input.snap index 8a6c5325e..64704b61f 100644 --- a/.forge-snapshots/swap burn 6909 for input.snap +++ b/.forge-snapshots/swap burn 6909 for input.snap @@ -1 +1 @@ -125275 \ No newline at end of file +125223 \ No newline at end of file diff --git a/.forge-snapshots/swap burn native 6909 for input.snap b/.forge-snapshots/swap burn native 6909 for input.snap index 3038ea02f..815405b68 100644 --- a/.forge-snapshots/swap burn native 6909 for input.snap +++ b/.forge-snapshots/swap burn native 6909 for input.snap @@ -1 +1 @@ -121228 \ No newline at end of file +121176 \ No newline at end of file diff --git a/.forge-snapshots/swap mint native output as 6909.snap b/.forge-snapshots/swap mint native output as 6909.snap index ff3658046..b062474fa 100644 --- a/.forge-snapshots/swap mint native output as 6909.snap +++ b/.forge-snapshots/swap mint native output as 6909.snap @@ -1 +1 @@ -189463 \ No newline at end of file +189411 \ No newline at end of file diff --git a/.forge-snapshots/swap mint output as 6909.snap b/.forge-snapshots/swap mint output as 6909.snap index dc3f4d32f..d7e6c67da 100644 --- a/.forge-snapshots/swap mint output as 6909.snap +++ b/.forge-snapshots/swap mint output as 6909.snap @@ -1 +1 @@ -206268 \ No newline at end of file +206216 \ 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 a21aab27e..f9a9b2d12 100644 --- a/.forge-snapshots/swap with dynamic fee.snap +++ b/.forge-snapshots/swap with dynamic fee.snap @@ -1 +1 @@ -183469 \ No newline at end of file +183425 \ No newline at end of file diff --git a/.forge-snapshots/swap with hooks.snap b/.forge-snapshots/swap with hooks.snap index 2b2e734cd..4a524734b 100644 --- a/.forge-snapshots/swap with hooks.snap +++ b/.forge-snapshots/swap with hooks.snap @@ -1 +1 @@ -105042 \ No newline at end of file +104990 \ 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 bea3574d9..ac6b94b78 100644 --- a/.forge-snapshots/update dynamic fee in before swap.snap +++ b/.forge-snapshots/update dynamic fee in before swap.snap @@ -1 +1 @@ -190173 \ No newline at end of file +190129 \ No newline at end of file diff --git a/src/libraries/Hooks.sol b/src/libraries/Hooks.sol index 8524a9771..2daff5d48 100644 --- a/src/libraries/Hooks.sol +++ b/src/libraries/Hooks.sol @@ -96,10 +96,12 @@ library Hooks { /// @notice performs a hook call using the given calldata on the given hook function callHook(IHooks self, bytes memory data) internal { - (bytes4 expectedSelector, bytes4 selector) = _callHook(self, data); + if (msg.sender != address(self)) { + (bytes4 expectedSelector, bytes4 selector) = _callHook(self, data); - if (selector != expectedSelector) { - revert InvalidHookResponse(); + if (selector != expectedSelector) { + revert InvalidHookResponse(); + } } } @@ -107,7 +109,7 @@ library Hooks { function beforeInitialize(IHooks self, PoolKey memory key, uint160 sqrtPriceX96, bytes calldata hookData) internal { - if (self.hasPermission(BEFORE_INITIALIZE_FLAG) && (msg.sender != address(self))) { + if (self.hasPermission(BEFORE_INITIALIZE_FLAG)) { self.callHook( abi.encodeWithSelector(IHooks.beforeInitialize.selector, msg.sender, key, sqrtPriceX96, hookData) ); @@ -118,7 +120,7 @@ library Hooks { function afterInitialize(IHooks self, PoolKey memory key, uint160 sqrtPriceX96, int24 tick, bytes calldata hookData) internal { - if (self.hasPermission(AFTER_INITIALIZE_FLAG) && (msg.sender != address(self))) { + if (self.hasPermission(AFTER_INITIALIZE_FLAG)) { self.callHook( abi.encodeWithSelector(IHooks.afterInitialize.selector, msg.sender, key, sqrtPriceX96, tick, hookData) ); @@ -132,13 +134,9 @@ library Hooks { IPoolManager.ModifyLiquidityParams memory params, bytes calldata hookData ) internal { - if (params.liquidityDelta > 0 && self.hasPermission(BEFORE_ADD_LIQUIDITY_FLAG) && (msg.sender != address(self))) - { + if (params.liquidityDelta > 0 && self.hasPermission(BEFORE_ADD_LIQUIDITY_FLAG)) { self.callHook(abi.encodeWithSelector(IHooks.beforeAddLiquidity.selector, msg.sender, key, params, hookData)); - } else if ( - params.liquidityDelta <= 0 && self.hasPermission(BEFORE_REMOVE_LIQUIDITY_FLAG) - && (msg.sender != address(self)) - ) { + } else if (params.liquidityDelta <= 0 && self.hasPermission(BEFORE_REMOVE_LIQUIDITY_FLAG)) { self.callHook( abi.encodeWithSelector(IHooks.beforeRemoveLiquidity.selector, msg.sender, key, params, hookData) ); @@ -153,15 +151,11 @@ library Hooks { BalanceDelta delta, bytes calldata hookData ) internal { - if (params.liquidityDelta > 0 && self.hasPermission(AFTER_ADD_LIQUIDITY_FLAG) && (msg.sender != address(self))) - { + if (params.liquidityDelta > 0 && self.hasPermission(AFTER_ADD_LIQUIDITY_FLAG)) { self.callHook( abi.encodeWithSelector(IHooks.afterAddLiquidity.selector, msg.sender, key, params, delta, hookData) ); - } else if ( - params.liquidityDelta <= 0 && self.hasPermission(AFTER_REMOVE_LIQUIDITY_FLAG) - && (msg.sender != address(self)) - ) { + } else if (params.liquidityDelta <= 0 && self.hasPermission(AFTER_REMOVE_LIQUIDITY_FLAG)) { self.callHook( abi.encodeWithSelector(IHooks.afterRemoveLiquidity.selector, msg.sender, key, params, delta, hookData) ); @@ -172,7 +166,7 @@ library Hooks { function beforeSwap(IHooks self, PoolKey memory key, IPoolManager.SwapParams memory params, bytes calldata hookData) internal { - if (self.hasPermission(BEFORE_SWAP_FLAG) && (msg.sender != address(self))) { + if (self.hasPermission(BEFORE_SWAP_FLAG)) { self.callHook(abi.encodeWithSelector(IHooks.beforeSwap.selector, msg.sender, key, params, hookData)); } } @@ -185,7 +179,7 @@ library Hooks { BalanceDelta delta, bytes calldata hookData ) internal { - if (self.hasPermission(AFTER_SWAP_FLAG) && (msg.sender != address(self))) { + if (self.hasPermission(AFTER_SWAP_FLAG)) { self.callHook(abi.encodeWithSelector(IHooks.afterSwap.selector, msg.sender, key, params, delta, hookData)); } } @@ -194,7 +188,7 @@ library Hooks { function beforeDonate(IHooks self, PoolKey memory key, uint256 amount0, uint256 amount1, bytes calldata hookData) internal { - if (self.hasPermission(BEFORE_DONATE_FLAG) && (msg.sender != address(self))) { + if (self.hasPermission(BEFORE_DONATE_FLAG)) { self.callHook( abi.encodeWithSelector(IHooks.beforeDonate.selector, msg.sender, key, amount0, amount1, hookData) ); @@ -205,7 +199,7 @@ library Hooks { function afterDonate(IHooks self, PoolKey memory key, uint256 amount0, uint256 amount1, bytes calldata hookData) internal { - if (self.hasPermission(AFTER_DONATE_FLAG) && (msg.sender != address(self))) { + if (self.hasPermission(AFTER_DONATE_FLAG)) { self.callHook( abi.encodeWithSelector(IHooks.afterDonate.selector, msg.sender, key, amount0, amount1, hookData) ); diff --git a/src/test/SkipCallsTestHook.sol b/src/test/SkipCallsTestHook.sol index 673cd2da4..470a90f59 100644 --- a/src/test/SkipCallsTestHook.sol +++ b/src/test/SkipCallsTestHook.sol @@ -13,7 +13,6 @@ import {IERC20Minimal} from "../interfaces/external/IERC20Minimal.sol"; import {CurrencyLibrary, Currency} from "../types/Currency.sol"; import {PoolTestBase} from "./PoolTestBase.sol"; import {Test} from "forge-std/Test.sol"; -import "forge-std/console.sol"; contract SkipCallsTestHook is BaseTestHooks, Test { using PoolIdLibrary for PoolKey; @@ -24,8 +23,6 @@ contract SkipCallsTestHook is BaseTestHooks, Test { IPoolManager manager; uint24 internal fee; - constructor() {} - function setManager(IPoolManager _manager) external { manager = _manager; } From 5c7e31dd79655bda99eaf0128b9307648bb912c9 Mon Sep 17 00:00:00 2001 From: Diana Kocsis Date: Fri, 15 Mar 2024 10:54:38 -0400 Subject: [PATCH 03/14] changes --- .../addLiquidity with empty hook.snap | 2 +- ...swap hook, already cached dynamic fee.snap | 2 +- .../cached dynamic fee, no hooks.snap | 2 +- .../poolManager bytecode size.snap | 2 +- .forge-snapshots/simple swap with native.snap | 2 +- .forge-snapshots/simple swap.snap | 2 +- ...p against liquidity with native token.snap | 2 +- .forge-snapshots/swap against liquidity.snap | 2 +- .../swap burn 6909 for input.snap | 2 +- .../swap burn native 6909 for input.snap | 2 +- .../swap mint native output as 6909.snap | 2 +- .../swap mint output as 6909.snap | 2 +- .forge-snapshots/swap with dynamic fee.snap | 2 +- .forge-snapshots/swap with hooks.snap | 2 +- .../update dynamic fee in before swap.snap | 2 +- src/libraries/Hooks.sol | 99 +++++++++---------- src/test/PoolSwapTest.sol | 8 +- src/test/SkipCallsTestHook.sol | 16 +-- test/SkipCallsTestHook.t.sol | 14 +-- 19 files changed, 75 insertions(+), 92 deletions(-) diff --git a/.forge-snapshots/addLiquidity with empty hook.snap b/.forge-snapshots/addLiquidity with empty hook.snap index e5013ac3d..c5aa13485 100644 --- a/.forge-snapshots/addLiquidity with empty hook.snap +++ b/.forge-snapshots/addLiquidity with empty hook.snap @@ -1 +1 @@ -312352 \ No newline at end of file +312354 \ No newline at end of file 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 d0637b4c4..8963774fd 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 @@ -184324 \ No newline at end of file +184293 \ 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 407a4fe88..981291ff5 100644 --- a/.forge-snapshots/cached dynamic fee, no hooks.snap +++ b/.forge-snapshots/cached dynamic fee, no hooks.snap @@ -1 +1 @@ -138312 \ No newline at end of file +138280 \ No newline at end of file diff --git a/.forge-snapshots/poolManager bytecode size.snap b/.forge-snapshots/poolManager bytecode size.snap index 12f7a3f54..244d6a445 100644 --- a/.forge-snapshots/poolManager bytecode size.snap +++ b/.forge-snapshots/poolManager bytecode size.snap @@ -1 +1 @@ -23263 \ No newline at end of file +23267 \ 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 69a5dd8f7..8802697e6 100644 --- a/.forge-snapshots/simple swap with native.snap +++ b/.forge-snapshots/simple swap with native.snap @@ -1 +1 @@ -186885 \ No newline at end of file +186853 \ No newline at end of file diff --git a/.forge-snapshots/simple swap.snap b/.forge-snapshots/simple swap.snap index d3e1bd9e1..07a4c18a2 100644 --- a/.forge-snapshots/simple swap.snap +++ b/.forge-snapshots/simple swap.snap @@ -1 +1 @@ -195422 \ No newline at end of file +195390 \ 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 42ea3e9ad..83288ff9c 100644 --- a/.forge-snapshots/swap against liquidity with native token.snap +++ b/.forge-snapshots/swap against liquidity with native token.snap @@ -1 +1 @@ -117548 \ No newline at end of file +117516 \ No newline at end of file diff --git a/.forge-snapshots/swap against liquidity.snap b/.forge-snapshots/swap against liquidity.snap index 22c407edc..dde19ae55 100644 --- a/.forge-snapshots/swap against liquidity.snap +++ b/.forge-snapshots/swap against liquidity.snap @@ -1 +1 @@ -105012 \ No newline at end of file +104980 \ No newline at end of file diff --git a/.forge-snapshots/swap burn 6909 for input.snap b/.forge-snapshots/swap burn 6909 for input.snap index 64704b61f..08c616765 100644 --- a/.forge-snapshots/swap burn 6909 for input.snap +++ b/.forge-snapshots/swap burn 6909 for input.snap @@ -1 +1 @@ -125223 \ No newline at end of file +125191 \ No newline at end of file diff --git a/.forge-snapshots/swap burn native 6909 for input.snap b/.forge-snapshots/swap burn native 6909 for input.snap index 815405b68..9008ac615 100644 --- a/.forge-snapshots/swap burn native 6909 for input.snap +++ b/.forge-snapshots/swap burn native 6909 for input.snap @@ -1 +1 @@ -121176 \ No newline at end of file +121144 \ No newline at end of file diff --git a/.forge-snapshots/swap mint native output as 6909.snap b/.forge-snapshots/swap mint native output as 6909.snap index b062474fa..76e794452 100644 --- a/.forge-snapshots/swap mint native output as 6909.snap +++ b/.forge-snapshots/swap mint native output as 6909.snap @@ -1 +1 @@ -189411 \ No newline at end of file +189379 \ No newline at end of file diff --git a/.forge-snapshots/swap mint output as 6909.snap b/.forge-snapshots/swap mint output as 6909.snap index d7e6c67da..bcb3d6f0d 100644 --- a/.forge-snapshots/swap mint output as 6909.snap +++ b/.forge-snapshots/swap mint output as 6909.snap @@ -1 +1 @@ -206216 \ No newline at end of file +206184 \ 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 f9a9b2d12..8e97e4feb 100644 --- a/.forge-snapshots/swap with dynamic fee.snap +++ b/.forge-snapshots/swap with dynamic fee.snap @@ -1 +1 @@ -183425 \ No newline at end of file +183394 \ No newline at end of file diff --git a/.forge-snapshots/swap with hooks.snap b/.forge-snapshots/swap with hooks.snap index 4a524734b..0086ff1f4 100644 --- a/.forge-snapshots/swap with hooks.snap +++ b/.forge-snapshots/swap with hooks.snap @@ -1 +1 @@ -104990 \ No newline at end of file +104958 \ 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 ac6b94b78..6c68ccb71 100644 --- a/.forge-snapshots/update dynamic fee in before swap.snap +++ b/.forge-snapshots/update dynamic fee in before swap.snap @@ -1 +1 @@ -190129 \ No newline at end of file +190098 \ No newline at end of file diff --git a/src/libraries/Hooks.sol b/src/libraries/Hooks.sol index 2daff5d48..22e6590b2 100644 --- a/src/libraries/Hooks.sol +++ b/src/libraries/Hooks.sol @@ -53,20 +53,20 @@ library Hooks { /// the deployed hooks address causes the intended hooks to be called /// @param permissions The hooks that are intended to be called /// @dev permissions param is memory as the function will be called from constructors - function validateHookPermissions(IHooks self, Permissions memory permissions) internal pure { + function validateHookPermissions(IHooks hook, Permissions memory permissions) internal pure { if ( - permissions.beforeInitialize != self.hasPermission(BEFORE_INITIALIZE_FLAG) - || permissions.afterInitialize != self.hasPermission(AFTER_INITIALIZE_FLAG) - || permissions.beforeAddLiquidity != self.hasPermission(BEFORE_ADD_LIQUIDITY_FLAG) - || permissions.afterAddLiquidity != self.hasPermission(AFTER_ADD_LIQUIDITY_FLAG) - || permissions.beforeRemoveLiquidity != self.hasPermission(BEFORE_REMOVE_LIQUIDITY_FLAG) - || permissions.afterRemoveLiquidity != self.hasPermission(AFTER_REMOVE_LIQUIDITY_FLAG) - || permissions.beforeSwap != self.hasPermission(BEFORE_SWAP_FLAG) - || permissions.afterSwap != self.hasPermission(AFTER_SWAP_FLAG) - || permissions.beforeDonate != self.hasPermission(BEFORE_DONATE_FLAG) - || permissions.afterDonate != self.hasPermission(AFTER_DONATE_FLAG) + permissions.beforeInitialize != hook.hasPermission(BEFORE_INITIALIZE_FLAG) + || permissions.afterInitialize != hook.hasPermission(AFTER_INITIALIZE_FLAG) + || permissions.beforeAddLiquidity != hook.hasPermission(BEFORE_ADD_LIQUIDITY_FLAG) + || permissions.afterAddLiquidity != hook.hasPermission(AFTER_ADD_LIQUIDITY_FLAG) + || permissions.beforeRemoveLiquidity != hook.hasPermission(BEFORE_REMOVE_LIQUIDITY_FLAG) + || permissions.afterRemoveLiquidity != hook.hasPermission(AFTER_REMOVE_LIQUIDITY_FLAG) + || permissions.beforeSwap != hook.hasPermission(BEFORE_SWAP_FLAG) + || permissions.afterSwap != hook.hasPermission(AFTER_SWAP_FLAG) + || permissions.beforeDonate != hook.hasPermission(BEFORE_DONATE_FLAG) + || permissions.afterDonate != hook.hasPermission(AFTER_DONATE_FLAG) ) { - revert HookAddressNotValid(address(self)); + revert HookAddressNotValid(address(hook)); } } @@ -83,45 +83,44 @@ library Hooks { /// @notice performs a hook call using the given calldata on the given hook /// @return expectedSelector The selector that the hook is expected to return /// @return selector The selector that the hook actually returned - function _callHook(IHooks self, bytes memory data) private returns (bytes4 expectedSelector, bytes4 selector) { + function _callHook(IHooks hook, bytes memory data) private returns (bytes4 expectedSelector, bytes4 selector) { assembly { expectedSelector := mload(add(data, 0x20)) } - (bool success, bytes memory result) = address(self).call(data); + (bool success, bytes memory result) = address(hook).call(data); if (!success) _revert(result); selector = abi.decode(result, (bytes4)); } /// @notice performs a hook call using the given calldata on the given hook - function callHook(IHooks self, bytes memory data) internal { - if (msg.sender != address(self)) { - (bytes4 expectedSelector, bytes4 selector) = _callHook(self, data); + function callHook(IHooks hook, bytes memory data) internal { + if (msg.sender == address(hook)) return; + (bytes4 expectedSelector, bytes4 selector) = _callHook(hook, data); - if (selector != expectedSelector) { - revert InvalidHookResponse(); - } + if (selector != expectedSelector) { + revert InvalidHookResponse(); } } /// @notice calls beforeInitialize hook if permissioned and validates return value - function beforeInitialize(IHooks self, PoolKey memory key, uint160 sqrtPriceX96, bytes calldata hookData) + function beforeInitialize(IHooks hook, PoolKey memory key, uint160 sqrtPriceX96, bytes calldata hookData) internal { - if (self.hasPermission(BEFORE_INITIALIZE_FLAG)) { - self.callHook( + if (hook.hasPermission(BEFORE_INITIALIZE_FLAG)) { + hook.callHook( abi.encodeWithSelector(IHooks.beforeInitialize.selector, msg.sender, key, sqrtPriceX96, hookData) ); } } /// @notice calls afterInitialize hook if permissioned and validates return value - function afterInitialize(IHooks self, PoolKey memory key, uint160 sqrtPriceX96, int24 tick, bytes calldata hookData) + function afterInitialize(IHooks hook, PoolKey memory key, uint160 sqrtPriceX96, int24 tick, bytes calldata hookData) internal { - if (self.hasPermission(AFTER_INITIALIZE_FLAG)) { - self.callHook( + if (hook.hasPermission(AFTER_INITIALIZE_FLAG)) { + hook.callHook( abi.encodeWithSelector(IHooks.afterInitialize.selector, msg.sender, key, sqrtPriceX96, tick, hookData) ); } @@ -129,15 +128,15 @@ library Hooks { /// @notice calls beforeModifyLiquidity hook if permissioned and validates return value function beforeModifyLiquidity( - IHooks self, + IHooks hook, PoolKey memory key, IPoolManager.ModifyLiquidityParams memory params, bytes calldata hookData ) internal { - if (params.liquidityDelta > 0 && self.hasPermission(BEFORE_ADD_LIQUIDITY_FLAG)) { - self.callHook(abi.encodeWithSelector(IHooks.beforeAddLiquidity.selector, msg.sender, key, params, hookData)); - } else if (params.liquidityDelta <= 0 && self.hasPermission(BEFORE_REMOVE_LIQUIDITY_FLAG)) { - self.callHook( + if (params.liquidityDelta > 0 && hook.hasPermission(BEFORE_ADD_LIQUIDITY_FLAG)) { + hook.callHook(abi.encodeWithSelector(IHooks.beforeAddLiquidity.selector, msg.sender, key, params, hookData)); + } else if (params.liquidityDelta <= 0 && hook.hasPermission(BEFORE_REMOVE_LIQUIDITY_FLAG)) { + hook.callHook( abi.encodeWithSelector(IHooks.beforeRemoveLiquidity.selector, msg.sender, key, params, hookData) ); } @@ -145,69 +144,69 @@ library Hooks { /// @notice calls afterModifyLiquidity hook if permissioned and validates return value function afterModifyLiquidity( - IHooks self, + IHooks hook, PoolKey memory key, IPoolManager.ModifyLiquidityParams memory params, BalanceDelta delta, bytes calldata hookData ) internal { - if (params.liquidityDelta > 0 && self.hasPermission(AFTER_ADD_LIQUIDITY_FLAG)) { - self.callHook( + if (params.liquidityDelta > 0 && hook.hasPermission(AFTER_ADD_LIQUIDITY_FLAG)) { + hook.callHook( abi.encodeWithSelector(IHooks.afterAddLiquidity.selector, msg.sender, key, params, delta, hookData) ); - } else if (params.liquidityDelta <= 0 && self.hasPermission(AFTER_REMOVE_LIQUIDITY_FLAG)) { - self.callHook( + } else if (params.liquidityDelta <= 0 && hook.hasPermission(AFTER_REMOVE_LIQUIDITY_FLAG)) { + hook.callHook( abi.encodeWithSelector(IHooks.afterRemoveLiquidity.selector, msg.sender, key, params, delta, hookData) ); } } /// @notice calls beforeSwap hook if permissioned and validates return value - function beforeSwap(IHooks self, PoolKey memory key, IPoolManager.SwapParams memory params, bytes calldata hookData) + function beforeSwap(IHooks hook, PoolKey memory key, IPoolManager.SwapParams memory params, bytes calldata hookData) internal { - if (self.hasPermission(BEFORE_SWAP_FLAG)) { - self.callHook(abi.encodeWithSelector(IHooks.beforeSwap.selector, msg.sender, key, params, hookData)); + if (hook.hasPermission(BEFORE_SWAP_FLAG)) { + hook.callHook(abi.encodeWithSelector(IHooks.beforeSwap.selector, msg.sender, key, params, hookData)); } } /// @notice calls afterSwap hook if permissioned and validates return value function afterSwap( - IHooks self, + IHooks hook, PoolKey memory key, IPoolManager.SwapParams memory params, BalanceDelta delta, bytes calldata hookData ) internal { - if (self.hasPermission(AFTER_SWAP_FLAG)) { - self.callHook(abi.encodeWithSelector(IHooks.afterSwap.selector, msg.sender, key, params, delta, hookData)); + if (hook.hasPermission(AFTER_SWAP_FLAG)) { + hook.callHook(abi.encodeWithSelector(IHooks.afterSwap.selector, msg.sender, key, params, delta, hookData)); } } /// @notice calls beforeDonate hook if permissioned and validates return value - function beforeDonate(IHooks self, PoolKey memory key, uint256 amount0, uint256 amount1, bytes calldata hookData) + function beforeDonate(IHooks hook, PoolKey memory key, uint256 amount0, uint256 amount1, bytes calldata hookData) internal { - if (self.hasPermission(BEFORE_DONATE_FLAG)) { - self.callHook( + if (hook.hasPermission(BEFORE_DONATE_FLAG)) { + hook.callHook( abi.encodeWithSelector(IHooks.beforeDonate.selector, msg.sender, key, amount0, amount1, hookData) ); } } /// @notice calls afterDonate hook if permissioned and validates return value - function afterDonate(IHooks self, PoolKey memory key, uint256 amount0, uint256 amount1, bytes calldata hookData) + function afterDonate(IHooks hook, PoolKey memory key, uint256 amount0, uint256 amount1, bytes calldata hookData) internal { - if (self.hasPermission(AFTER_DONATE_FLAG)) { - self.callHook( + if (hook.hasPermission(AFTER_DONATE_FLAG)) { + hook.callHook( abi.encodeWithSelector(IHooks.afterDonate.selector, msg.sender, key, amount0, amount1, hookData) ); } } - function hasPermission(IHooks self, uint256 flag) internal pure returns (bool) { - return uint256(uint160(address(self))) & flag != 0; + function hasPermission(IHooks hook, uint256 flag) internal pure returns (bool) { + return uint256(uint160(address(hook))) & flag != 0; } /// @notice bubble up revert if present. Else throw FailedHookCall diff --git a/src/test/PoolSwapTest.sol b/src/test/PoolSwapTest.sol index 7f203af20..0431d59e4 100644 --- a/src/test/PoolSwapTest.sol +++ b/src/test/PoolSwapTest.sol @@ -53,9 +53,9 @@ contract PoolSwapTest is Test, PoolTestBase { CallbackData memory data = abi.decode(rawData, (CallbackData)); - (,, uint256 reserveBefore0, int256 deltaBefore0) = + (,,, int256 deltaBefore0) = _fetchBalances(data.key.currency0, data.sender, address(this)); - (,, uint256 reserveBefore1, int256 deltaBefore1) = + (,,, int256 deltaBefore1) = _fetchBalances(data.key.currency1, data.sender, address(this)); assertEq(deltaBefore0, 0); @@ -63,8 +63,8 @@ contract PoolSwapTest is Test, PoolTestBase { BalanceDelta delta = manager.swap(data.key, data.params, data.hookData); - (,, uint256 reserveAfter0, int256 deltaAfter0) = _fetchBalances(data.key.currency0, data.sender, address(this)); - (,, uint256 reserveAfter1, int256 deltaAfter1) = _fetchBalances(data.key.currency1, data.sender, address(this)); + (,,, int256 deltaAfter0) = _fetchBalances(data.key.currency0, data.sender, address(this)); + (,,, int256 deltaAfter1) = _fetchBalances(data.key.currency1, data.sender, address(this)); if (data.params.zeroForOne) { if (data.params.amountSpecified > 0) { diff --git a/src/test/SkipCallsTestHook.sol b/src/test/SkipCallsTestHook.sol index 470a90f59..db2e8162b 100644 --- a/src/test/SkipCallsTestHook.sol +++ b/src/test/SkipCallsTestHook.sol @@ -27,14 +27,6 @@ contract SkipCallsTestHook is BaseTestHooks, Test { manager = _manager; } - function setFee(uint24 _fee) external { - fee = _fee; - } - - function getFee(address, PoolKey calldata) public view returns (uint24) { - return fee; - } - function beforeSwap(address, PoolKey calldata key, IPoolManager.SwapParams calldata params, bytes calldata hookData) external override @@ -46,13 +38,13 @@ contract SkipCallsTestHook is BaseTestHooks, Test { } function callSwap(PoolKey calldata key, IPoolManager.SwapParams calldata params, bytes calldata hookData) public { - IPoolManager(msg.sender).swap(key, params, hookData); + IPoolManager(manager).swap(key, params, hookData); address payer = abi.decode(hookData, (address)); - int256 delta0 = IPoolManager(msg.sender).currencyDelta(address(this), key.currency0); + int256 delta0 = IPoolManager(manager).currencyDelta(address(this), key.currency0); assertEq(delta0, params.amountSpecified); - int256 delta1 = IPoolManager(msg.sender).currencyDelta(address(this), key.currency1); + int256 delta1 = IPoolManager(manager).currencyDelta(address(this), key.currency1); assert(delta1 < 0); - IERC20Minimal(Currency.unwrap(key.currency0)).transferFrom(payer, msg.sender, uint256(delta0)); + IERC20Minimal(Currency.unwrap(key.currency0)).transferFrom(payer, address(manager), uint256(delta0)); manager.settle(key.currency0); manager.take(key.currency1, payer, uint256(-delta1)); } diff --git a/test/SkipCallsTestHook.t.sol b/test/SkipCallsTestHook.t.sol index 80b739711..a660f536f 100644 --- a/test/SkipCallsTestHook.t.sol +++ b/test/SkipCallsTestHook.t.sol @@ -24,17 +24,9 @@ import {SkipCallsTestHook} from "../src/test/SkipCallsTestHook.sol"; contract SkipCallsTest is Test, Deployers, GasSnapshot { using PoolIdLibrary for PoolKey; - /// 1111 1111 1100 SkipCallsTestHook skipCallsTestHook = SkipCallsTestHook( address( - uint160(0xFFfFfFffFFfffFFfFFfFFFFFffFFFffffFfFFFfF) - & uint160( - ~Hooks.BEFORE_INITIALIZE_FLAG & ~Hooks.AFTER_INITIALIZE_FLAG & ~Hooks.BEFORE_ADD_LIQUIDITY_FLAG - & ~Hooks.AFTER_ADD_LIQUIDITY_FLAG & ~Hooks.BEFORE_REMOVE_LIQUIDITY_FLAG - & ~Hooks.AFTER_REMOVE_LIQUIDITY_FLAG & ~Hooks.AFTER_SWAP_FLAG & ~Hooks.BEFORE_DONATE_FLAG - & ~Hooks.AFTER_DONATE_FLAG - ) - ) + uint160(Hooks.BEFORE_SWAP_FLAG)) ); function setUp() public { @@ -48,13 +40,13 @@ contract SkipCallsTest is Test, Deployers, GasSnapshot { currency0, currency1, IHooks(address(skipCallsTestHook)), - FeeLibrary.DYNAMIC_FEE_FLAG, + 3000, SQRT_RATIO_1_1, ZERO_BYTES ); } - function test_beforeSwap_invalidSender() public { + function test_beforeSwap_skipIfCalledByHook() public { IPoolManager.SwapParams memory swapParams = IPoolManager.SwapParams({zeroForOne: true, amountSpecified: 100, sqrtPriceLimitX96: SQRT_RATIO_1_2}); From 87032f6d7cb3a49bbb359c072f63795a0e262ab8 Mon Sep 17 00:00:00 2001 From: Diana Kocsis Date: Fri, 15 Mar 2024 10:57:54 -0400 Subject: [PATCH 04/14] linting --- src/test/PoolSwapTest.sol | 6 ++---- test/SkipCallsTestHook.t.sol | 12 ++---------- 2 files changed, 4 insertions(+), 14 deletions(-) diff --git a/src/test/PoolSwapTest.sol b/src/test/PoolSwapTest.sol index 0431d59e4..8f0d3f3a2 100644 --- a/src/test/PoolSwapTest.sol +++ b/src/test/PoolSwapTest.sol @@ -53,10 +53,8 @@ contract PoolSwapTest is Test, PoolTestBase { CallbackData memory data = abi.decode(rawData, (CallbackData)); - (,,, int256 deltaBefore0) = - _fetchBalances(data.key.currency0, data.sender, address(this)); - (,,, int256 deltaBefore1) = - _fetchBalances(data.key.currency1, data.sender, address(this)); + (,,, int256 deltaBefore0) = _fetchBalances(data.key.currency0, data.sender, address(this)); + (,,, int256 deltaBefore1) = _fetchBalances(data.key.currency1, data.sender, address(this)); assertEq(deltaBefore0, 0); assertEq(deltaBefore1, 0); diff --git a/test/SkipCallsTestHook.t.sol b/test/SkipCallsTestHook.t.sol index a660f536f..1538746d9 100644 --- a/test/SkipCallsTestHook.t.sol +++ b/test/SkipCallsTestHook.t.sol @@ -24,10 +24,7 @@ import {SkipCallsTestHook} from "../src/test/SkipCallsTestHook.sol"; contract SkipCallsTest is Test, Deployers, GasSnapshot { using PoolIdLibrary for PoolKey; - SkipCallsTestHook skipCallsTestHook = SkipCallsTestHook( - address( - uint160(Hooks.BEFORE_SWAP_FLAG)) - ); + SkipCallsTestHook skipCallsTestHook = SkipCallsTestHook(address(uint160(Hooks.BEFORE_SWAP_FLAG))); function setUp() public { SkipCallsTestHook impl = new SkipCallsTestHook(); @@ -37,12 +34,7 @@ contract SkipCallsTest is Test, Deployers, GasSnapshot { (currency0, currency1) = deployMintAndApprove2Currencies(); (key,) = initPoolAndAddLiquidity( - currency0, - currency1, - IHooks(address(skipCallsTestHook)), - 3000, - SQRT_RATIO_1_1, - ZERO_BYTES + currency0, currency1, IHooks(address(skipCallsTestHook)), 3000, SQRT_RATIO_1_1, ZERO_BYTES ); } From 43c5d976631cf58394bc6d22748abd5699e2be27 Mon Sep 17 00:00:00 2001 From: Diana Kocsis Date: Fri, 15 Mar 2024 16:38:08 -0400 Subject: [PATCH 05/14] re-add forge snapshots --- .forge-snapshots/BitMathLeastSignificantBitMaxUint128.snap | 1 + .forge-snapshots/BitMathLeastSignificantBitMaxUint256.snap | 1 + .forge-snapshots/BitMathLeastSignificantBitSmallNumber.snap | 1 + .forge-snapshots/BitMathMostSignificantBitMaxUint128.snap | 1 + .forge-snapshots/BitMathMostSignificantBitMaxUint256.snap | 1 + .forge-snapshots/BitMathMostSignificantBitSmallNumber.snap | 1 + .forge-snapshots/HooksShouldCallBeforeSwap.snap | 1 + .forge-snapshots/NoDelegateCallOverhead.snap | 1 + .forge-snapshots/SwapMath_oneForZero_exactInCapped.snap | 1 + .forge-snapshots/SwapMath_oneForZero_exactInPartial.snap | 1 + .forge-snapshots/SwapMath_oneForZero_exactOutCapped.snap | 1 + .forge-snapshots/SwapMath_oneForZero_exactOutPartial.snap | 1 + .forge-snapshots/SwapMath_zeroForOne_exactInCapped.snap | 1 + .forge-snapshots/SwapMath_zeroForOne_exactInPartial.snap | 1 + .forge-snapshots/SwapMath_zeroForOne_exactOutCapped.snap | 1 + .forge-snapshots/SwapMath_zeroForOne_exactOutPartial.snap | 1 + .forge-snapshots/addLiquidity with empty hook.snap | 1 + .forge-snapshots/addLiquidity with native token.snap | 1 + .forge-snapshots/addLiquidity.snap | 1 + .forge-snapshots/donate gas with 1 token.snap | 1 + .forge-snapshots/donate gas with 2 tokens.snap | 1 + .forge-snapshots/erc20 collect protocol fees.snap | 1 + ...lipTick_gasCostOfFlippingATickThatResultsInDeletingAWord.snap | 1 + .../flipTick_gasCostOfFlippingFirstTickInWordToInitialized.snap | 1 + .../flipTick_gasCostOfFlippingSecondTickInWordToInitialized.snap | 1 + .../getAmount0Delta_gasCostForAmount0WhereRoundUpIsFalse.snap | 1 + .../getAmount0Delta_gasCostForAmount0WhereRoundUpIsTrue.snap | 1 + .../getAmount1Delta_gasCostForAmount1WhereRoundUpIsFalse.snap | 1 + .../getAmount1Delta_gasCostForAmount1WhereRoundUpIsTrue.snap | 1 + .../getNextSqrtPriceFromInput_zeroForOneEqualsFalseGas.snap | 1 + .../getNextSqrtPriceFromInput_zeroForOneEqualsTrueGas.snap | 1 + .../getNextSqrtPriceFromOutput_zeroForOneEqualsFalseGas.snap | 1 + .../getNextSqrtPriceFromOutput_zeroForOneEqualsTrueGas.snap | 1 + .forge-snapshots/initialize.snap | 1 + .forge-snapshots/native collect protocol fees.snap | 1 + ...itializedTickWithinOneWord_lteFalse_gasCostForEntireWord.snap | 1 + ...lizedTickWithinOneWord_lteFalse_gasCostJustBelowBoundary.snap | 1 + ...tInitializedTickWithinOneWord_lteFalse_gasCostOnBoundary.snap | 1 + ...nitializedTickWithinOneWord_lteTrue_gasCostForEntireWord.snap | 1 + ...alizedTickWithinOneWord_lteTrue_gasCostJustBelowBoundary.snap | 1 + ...xtInitializedTickWithinOneWord_lteTrue_gasCostOnBoundary.snap | 1 + .forge-snapshots/poolManager bytecode size.snap | 1 + .forge-snapshots/removeLiquidity with empty hook.snap | 1 + .forge-snapshots/removeLiquidity with native token.snap | 1 + .forge-snapshots/removeLiquidity.snap | 1 + .forge-snapshots/simple swap with native.snap | 1 + .forge-snapshots/simple swap.snap | 1 + .forge-snapshots/swap against liquidity with native token.snap | 1 + .forge-snapshots/swap against liquidity.snap | 1 + .forge-snapshots/swap burn 6909 for input.snap | 1 + .forge-snapshots/swap burn native 6909 for input.snap | 1 + .forge-snapshots/swap mint native output as 6909.snap | 1 + .forge-snapshots/swap mint output as 6909.snap | 1 + .forge-snapshots/swap with dynamic fee.snap | 1 + .forge-snapshots/swap with hooks.snap | 1 + .../tickSpacingToMaxLiquidityPerTick_gasCost60TickSpacing.snap | 1 + .../tickSpacingToMaxLiquidityPerTick_gasCostMaxTickSpacing.snap | 1 + .../tickSpacingToMaxLiquidityPerTick_gasCostMinTickSpacing.snap | 1 + .forge-snapshots/update dynamic fee in before swap.snap | 1 + 59 files changed, 59 insertions(+) create mode 100644 .forge-snapshots/BitMathLeastSignificantBitMaxUint128.snap create mode 100644 .forge-snapshots/BitMathLeastSignificantBitMaxUint256.snap create mode 100644 .forge-snapshots/BitMathLeastSignificantBitSmallNumber.snap create mode 100644 .forge-snapshots/BitMathMostSignificantBitMaxUint128.snap create mode 100644 .forge-snapshots/BitMathMostSignificantBitMaxUint256.snap create mode 100644 .forge-snapshots/BitMathMostSignificantBitSmallNumber.snap create mode 100644 .forge-snapshots/HooksShouldCallBeforeSwap.snap create mode 100644 .forge-snapshots/NoDelegateCallOverhead.snap create mode 100644 .forge-snapshots/SwapMath_oneForZero_exactInCapped.snap create mode 100644 .forge-snapshots/SwapMath_oneForZero_exactInPartial.snap create mode 100644 .forge-snapshots/SwapMath_oneForZero_exactOutCapped.snap create mode 100644 .forge-snapshots/SwapMath_oneForZero_exactOutPartial.snap create mode 100644 .forge-snapshots/SwapMath_zeroForOne_exactInCapped.snap create mode 100644 .forge-snapshots/SwapMath_zeroForOne_exactInPartial.snap create mode 100644 .forge-snapshots/SwapMath_zeroForOne_exactOutCapped.snap create mode 100644 .forge-snapshots/SwapMath_zeroForOne_exactOutPartial.snap create mode 100644 .forge-snapshots/addLiquidity with empty hook.snap create mode 100644 .forge-snapshots/addLiquidity with native token.snap create mode 100644 .forge-snapshots/addLiquidity.snap create mode 100644 .forge-snapshots/donate gas with 1 token.snap create mode 100644 .forge-snapshots/donate gas with 2 tokens.snap create mode 100644 .forge-snapshots/erc20 collect protocol fees.snap create mode 100644 .forge-snapshots/flipTick_gasCostOfFlippingATickThatResultsInDeletingAWord.snap create mode 100644 .forge-snapshots/flipTick_gasCostOfFlippingFirstTickInWordToInitialized.snap create mode 100644 .forge-snapshots/flipTick_gasCostOfFlippingSecondTickInWordToInitialized.snap create mode 100644 .forge-snapshots/getAmount0Delta_gasCostForAmount0WhereRoundUpIsFalse.snap create mode 100644 .forge-snapshots/getAmount0Delta_gasCostForAmount0WhereRoundUpIsTrue.snap create mode 100644 .forge-snapshots/getAmount1Delta_gasCostForAmount1WhereRoundUpIsFalse.snap create mode 100644 .forge-snapshots/getAmount1Delta_gasCostForAmount1WhereRoundUpIsTrue.snap create mode 100644 .forge-snapshots/getNextSqrtPriceFromInput_zeroForOneEqualsFalseGas.snap create mode 100644 .forge-snapshots/getNextSqrtPriceFromInput_zeroForOneEqualsTrueGas.snap create mode 100644 .forge-snapshots/getNextSqrtPriceFromOutput_zeroForOneEqualsFalseGas.snap create mode 100644 .forge-snapshots/getNextSqrtPriceFromOutput_zeroForOneEqualsTrueGas.snap create mode 100644 .forge-snapshots/initialize.snap create mode 100644 .forge-snapshots/native collect protocol fees.snap create mode 100644 .forge-snapshots/nextInitializedTickWithinOneWord_lteFalse_gasCostForEntireWord.snap create mode 100644 .forge-snapshots/nextInitializedTickWithinOneWord_lteFalse_gasCostJustBelowBoundary.snap create mode 100644 .forge-snapshots/nextInitializedTickWithinOneWord_lteFalse_gasCostOnBoundary.snap create mode 100644 .forge-snapshots/nextInitializedTickWithinOneWord_lteTrue_gasCostForEntireWord.snap create mode 100644 .forge-snapshots/nextInitializedTickWithinOneWord_lteTrue_gasCostJustBelowBoundary.snap create mode 100644 .forge-snapshots/nextInitializedTickWithinOneWord_lteTrue_gasCostOnBoundary.snap create mode 100644 .forge-snapshots/poolManager bytecode size.snap create mode 100644 .forge-snapshots/removeLiquidity with empty hook.snap create mode 100644 .forge-snapshots/removeLiquidity with native token.snap create mode 100644 .forge-snapshots/removeLiquidity.snap create mode 100644 .forge-snapshots/simple swap with native.snap create mode 100644 .forge-snapshots/simple swap.snap create mode 100644 .forge-snapshots/swap against liquidity with native token.snap create mode 100644 .forge-snapshots/swap against liquidity.snap create mode 100644 .forge-snapshots/swap burn 6909 for input.snap create mode 100644 .forge-snapshots/swap burn native 6909 for input.snap create mode 100644 .forge-snapshots/swap mint native output as 6909.snap create mode 100644 .forge-snapshots/swap mint output as 6909.snap create mode 100644 .forge-snapshots/swap with dynamic fee.snap create mode 100644 .forge-snapshots/swap with hooks.snap create mode 100644 .forge-snapshots/tickSpacingToMaxLiquidityPerTick_gasCost60TickSpacing.snap create mode 100644 .forge-snapshots/tickSpacingToMaxLiquidityPerTick_gasCostMaxTickSpacing.snap create mode 100644 .forge-snapshots/tickSpacingToMaxLiquidityPerTick_gasCostMinTickSpacing.snap create mode 100644 .forge-snapshots/update dynamic fee in before swap.snap diff --git a/.forge-snapshots/BitMathLeastSignificantBitMaxUint128.snap b/.forge-snapshots/BitMathLeastSignificantBitMaxUint128.snap new file mode 100644 index 000000000..9d3f41701 --- /dev/null +++ b/.forge-snapshots/BitMathLeastSignificantBitMaxUint128.snap @@ -0,0 +1 @@ +455 \ No newline at end of file diff --git a/.forge-snapshots/BitMathLeastSignificantBitMaxUint256.snap b/.forge-snapshots/BitMathLeastSignificantBitMaxUint256.snap new file mode 100644 index 000000000..2da432533 --- /dev/null +++ b/.forge-snapshots/BitMathLeastSignificantBitMaxUint256.snap @@ -0,0 +1 @@ +457 \ No newline at end of file diff --git a/.forge-snapshots/BitMathLeastSignificantBitSmallNumber.snap b/.forge-snapshots/BitMathLeastSignificantBitSmallNumber.snap new file mode 100644 index 000000000..13ef0a79b --- /dev/null +++ b/.forge-snapshots/BitMathLeastSignificantBitSmallNumber.snap @@ -0,0 +1 @@ +453 \ No newline at end of file diff --git a/.forge-snapshots/BitMathMostSignificantBitMaxUint128.snap b/.forge-snapshots/BitMathMostSignificantBitMaxUint128.snap new file mode 100644 index 000000000..c0db21d80 --- /dev/null +++ b/.forge-snapshots/BitMathMostSignificantBitMaxUint128.snap @@ -0,0 +1 @@ +392 \ No newline at end of file diff --git a/.forge-snapshots/BitMathMostSignificantBitMaxUint256.snap b/.forge-snapshots/BitMathMostSignificantBitMaxUint256.snap new file mode 100644 index 000000000..8d4011ad2 --- /dev/null +++ b/.forge-snapshots/BitMathMostSignificantBitMaxUint256.snap @@ -0,0 +1 @@ +412 \ No newline at end of file diff --git a/.forge-snapshots/BitMathMostSignificantBitSmallNumber.snap b/.forge-snapshots/BitMathMostSignificantBitSmallNumber.snap new file mode 100644 index 000000000..194ba8cc7 --- /dev/null +++ b/.forge-snapshots/BitMathMostSignificantBitSmallNumber.snap @@ -0,0 +1 @@ +320 \ No newline at end of file diff --git a/.forge-snapshots/HooksShouldCallBeforeSwap.snap b/.forge-snapshots/HooksShouldCallBeforeSwap.snap new file mode 100644 index 000000000..c9c41087e --- /dev/null +++ b/.forge-snapshots/HooksShouldCallBeforeSwap.snap @@ -0,0 +1 @@ +114 \ No newline at end of file diff --git a/.forge-snapshots/NoDelegateCallOverhead.snap b/.forge-snapshots/NoDelegateCallOverhead.snap new file mode 100644 index 000000000..aaa6442fe --- /dev/null +++ b/.forge-snapshots/NoDelegateCallOverhead.snap @@ -0,0 +1 @@ +41 \ No newline at end of file diff --git a/.forge-snapshots/SwapMath_oneForZero_exactInCapped.snap b/.forge-snapshots/SwapMath_oneForZero_exactInCapped.snap new file mode 100644 index 000000000..27d48e9a4 --- /dev/null +++ b/.forge-snapshots/SwapMath_oneForZero_exactInCapped.snap @@ -0,0 +1 @@ +1947 \ No newline at end of file diff --git a/.forge-snapshots/SwapMath_oneForZero_exactInPartial.snap b/.forge-snapshots/SwapMath_oneForZero_exactInPartial.snap new file mode 100644 index 000000000..9560ba822 --- /dev/null +++ b/.forge-snapshots/SwapMath_oneForZero_exactInPartial.snap @@ -0,0 +1 @@ +3238 \ No newline at end of file diff --git a/.forge-snapshots/SwapMath_oneForZero_exactOutCapped.snap b/.forge-snapshots/SwapMath_oneForZero_exactOutCapped.snap new file mode 100644 index 000000000..758e03adc --- /dev/null +++ b/.forge-snapshots/SwapMath_oneForZero_exactOutCapped.snap @@ -0,0 +1 @@ +2208 \ No newline at end of file diff --git a/.forge-snapshots/SwapMath_oneForZero_exactOutPartial.snap b/.forge-snapshots/SwapMath_oneForZero_exactOutPartial.snap new file mode 100644 index 000000000..9560ba822 --- /dev/null +++ b/.forge-snapshots/SwapMath_oneForZero_exactOutPartial.snap @@ -0,0 +1 @@ +3238 \ No newline at end of file diff --git a/.forge-snapshots/SwapMath_zeroForOne_exactInCapped.snap b/.forge-snapshots/SwapMath_zeroForOne_exactInCapped.snap new file mode 100644 index 000000000..12057ad70 --- /dev/null +++ b/.forge-snapshots/SwapMath_zeroForOne_exactInCapped.snap @@ -0,0 +1 @@ +1937 \ No newline at end of file diff --git a/.forge-snapshots/SwapMath_zeroForOne_exactInPartial.snap b/.forge-snapshots/SwapMath_zeroForOne_exactInPartial.snap new file mode 100644 index 000000000..c173e591f --- /dev/null +++ b/.forge-snapshots/SwapMath_zeroForOne_exactInPartial.snap @@ -0,0 +1 @@ +2826 \ No newline at end of file diff --git a/.forge-snapshots/SwapMath_zeroForOne_exactOutCapped.snap b/.forge-snapshots/SwapMath_zeroForOne_exactOutCapped.snap new file mode 100644 index 000000000..c802063a0 --- /dev/null +++ b/.forge-snapshots/SwapMath_zeroForOne_exactOutCapped.snap @@ -0,0 +1 @@ +2198 \ No newline at end of file diff --git a/.forge-snapshots/SwapMath_zeroForOne_exactOutPartial.snap b/.forge-snapshots/SwapMath_zeroForOne_exactOutPartial.snap new file mode 100644 index 000000000..c173e591f --- /dev/null +++ b/.forge-snapshots/SwapMath_zeroForOne_exactOutPartial.snap @@ -0,0 +1 @@ +2826 \ No newline at end of file diff --git a/.forge-snapshots/addLiquidity with empty hook.snap b/.forge-snapshots/addLiquidity with empty hook.snap new file mode 100644 index 000000000..93cd08edb --- /dev/null +++ b/.forge-snapshots/addLiquidity with empty hook.snap @@ -0,0 +1 @@ +312221 \ No newline at end of file diff --git a/.forge-snapshots/addLiquidity with native token.snap b/.forge-snapshots/addLiquidity with native token.snap new file mode 100644 index 000000000..03d3edc54 --- /dev/null +++ b/.forge-snapshots/addLiquidity with native token.snap @@ -0,0 +1 @@ +192320 \ No newline at end of file diff --git a/.forge-snapshots/addLiquidity.snap b/.forge-snapshots/addLiquidity.snap new file mode 100644 index 000000000..eb3137756 --- /dev/null +++ b/.forge-snapshots/addLiquidity.snap @@ -0,0 +1 @@ +192301 \ 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 new file mode 100644 index 000000000..bef388da8 --- /dev/null +++ b/.forge-snapshots/donate gas with 1 token.snap @@ -0,0 +1 @@ +132039 \ 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 new file mode 100644 index 000000000..a41d418c7 --- /dev/null +++ b/.forge-snapshots/donate gas with 2 tokens.snap @@ -0,0 +1 @@ +177133 \ No newline at end of file diff --git a/.forge-snapshots/erc20 collect protocol fees.snap b/.forge-snapshots/erc20 collect protocol fees.snap new file mode 100644 index 000000000..7cfa73c37 --- /dev/null +++ b/.forge-snapshots/erc20 collect protocol fees.snap @@ -0,0 +1 @@ +24960 \ No newline at end of file diff --git a/.forge-snapshots/flipTick_gasCostOfFlippingATickThatResultsInDeletingAWord.snap b/.forge-snapshots/flipTick_gasCostOfFlippingATickThatResultsInDeletingAWord.snap new file mode 100644 index 000000000..3819e9389 --- /dev/null +++ b/.forge-snapshots/flipTick_gasCostOfFlippingATickThatResultsInDeletingAWord.snap @@ -0,0 +1 @@ +5409 \ No newline at end of file diff --git a/.forge-snapshots/flipTick_gasCostOfFlippingFirstTickInWordToInitialized.snap b/.forge-snapshots/flipTick_gasCostOfFlippingFirstTickInWordToInitialized.snap new file mode 100644 index 000000000..0cd31fe26 --- /dev/null +++ b/.forge-snapshots/flipTick_gasCostOfFlippingFirstTickInWordToInitialized.snap @@ -0,0 +1 @@ +22506 \ No newline at end of file diff --git a/.forge-snapshots/flipTick_gasCostOfFlippingSecondTickInWordToInitialized.snap b/.forge-snapshots/flipTick_gasCostOfFlippingSecondTickInWordToInitialized.snap new file mode 100644 index 000000000..38966a2c0 --- /dev/null +++ b/.forge-snapshots/flipTick_gasCostOfFlippingSecondTickInWordToInitialized.snap @@ -0,0 +1 @@ +5515 \ No newline at end of file diff --git a/.forge-snapshots/getAmount0Delta_gasCostForAmount0WhereRoundUpIsFalse.snap b/.forge-snapshots/getAmount0Delta_gasCostForAmount0WhereRoundUpIsFalse.snap new file mode 100644 index 000000000..1dd3380cd --- /dev/null +++ b/.forge-snapshots/getAmount0Delta_gasCostForAmount0WhereRoundUpIsFalse.snap @@ -0,0 +1 @@ +516 \ No newline at end of file diff --git a/.forge-snapshots/getAmount0Delta_gasCostForAmount0WhereRoundUpIsTrue.snap b/.forge-snapshots/getAmount0Delta_gasCostForAmount0WhereRoundUpIsTrue.snap new file mode 100644 index 000000000..b7f636c12 --- /dev/null +++ b/.forge-snapshots/getAmount0Delta_gasCostForAmount0WhereRoundUpIsTrue.snap @@ -0,0 +1 @@ +665 \ No newline at end of file diff --git a/.forge-snapshots/getAmount1Delta_gasCostForAmount1WhereRoundUpIsFalse.snap b/.forge-snapshots/getAmount1Delta_gasCostForAmount1WhereRoundUpIsFalse.snap new file mode 100644 index 000000000..1fc188de7 --- /dev/null +++ b/.forge-snapshots/getAmount1Delta_gasCostForAmount1WhereRoundUpIsFalse.snap @@ -0,0 +1 @@ +525 \ No newline at end of file diff --git a/.forge-snapshots/getAmount1Delta_gasCostForAmount1WhereRoundUpIsTrue.snap b/.forge-snapshots/getAmount1Delta_gasCostForAmount1WhereRoundUpIsTrue.snap new file mode 100644 index 000000000..929530e88 --- /dev/null +++ b/.forge-snapshots/getAmount1Delta_gasCostForAmount1WhereRoundUpIsTrue.snap @@ -0,0 +1 @@ +653 \ No newline at end of file diff --git a/.forge-snapshots/getNextSqrtPriceFromInput_zeroForOneEqualsFalseGas.snap b/.forge-snapshots/getNextSqrtPriceFromInput_zeroForOneEqualsFalseGas.snap new file mode 100644 index 000000000..7dfce3516 --- /dev/null +++ b/.forge-snapshots/getNextSqrtPriceFromInput_zeroForOneEqualsFalseGas.snap @@ -0,0 +1 @@ +594 \ No newline at end of file diff --git a/.forge-snapshots/getNextSqrtPriceFromInput_zeroForOneEqualsTrueGas.snap b/.forge-snapshots/getNextSqrtPriceFromInput_zeroForOneEqualsTrueGas.snap new file mode 100644 index 000000000..19e03cffa --- /dev/null +++ b/.forge-snapshots/getNextSqrtPriceFromInput_zeroForOneEqualsTrueGas.snap @@ -0,0 +1 @@ +776 \ No newline at end of file diff --git a/.forge-snapshots/getNextSqrtPriceFromOutput_zeroForOneEqualsFalseGas.snap b/.forge-snapshots/getNextSqrtPriceFromOutput_zeroForOneEqualsFalseGas.snap new file mode 100644 index 000000000..f8f450742 --- /dev/null +++ b/.forge-snapshots/getNextSqrtPriceFromOutput_zeroForOneEqualsFalseGas.snap @@ -0,0 +1 @@ +878 \ No newline at end of file diff --git a/.forge-snapshots/getNextSqrtPriceFromOutput_zeroForOneEqualsTrueGas.snap b/.forge-snapshots/getNextSqrtPriceFromOutput_zeroForOneEqualsTrueGas.snap new file mode 100644 index 000000000..4c9bbbfa9 --- /dev/null +++ b/.forge-snapshots/getNextSqrtPriceFromOutput_zeroForOneEqualsTrueGas.snap @@ -0,0 +1 @@ +468 \ No newline at end of file diff --git a/.forge-snapshots/initialize.snap b/.forge-snapshots/initialize.snap new file mode 100644 index 000000000..7610c108e --- /dev/null +++ b/.forge-snapshots/initialize.snap @@ -0,0 +1 @@ +51816 \ No newline at end of file diff --git a/.forge-snapshots/native collect protocol fees.snap b/.forge-snapshots/native collect protocol fees.snap new file mode 100644 index 000000000..af4d450da --- /dev/null +++ b/.forge-snapshots/native collect protocol fees.snap @@ -0,0 +1 @@ +36633 \ No newline at end of file diff --git a/.forge-snapshots/nextInitializedTickWithinOneWord_lteFalse_gasCostForEntireWord.snap b/.forge-snapshots/nextInitializedTickWithinOneWord_lteFalse_gasCostForEntireWord.snap new file mode 100644 index 000000000..13f668d19 --- /dev/null +++ b/.forge-snapshots/nextInitializedTickWithinOneWord_lteFalse_gasCostForEntireWord.snap @@ -0,0 +1 @@ +2592 \ No newline at end of file diff --git a/.forge-snapshots/nextInitializedTickWithinOneWord_lteFalse_gasCostJustBelowBoundary.snap b/.forge-snapshots/nextInitializedTickWithinOneWord_lteFalse_gasCostJustBelowBoundary.snap new file mode 100644 index 000000000..13f668d19 --- /dev/null +++ b/.forge-snapshots/nextInitializedTickWithinOneWord_lteFalse_gasCostJustBelowBoundary.snap @@ -0,0 +1 @@ +2592 \ No newline at end of file diff --git a/.forge-snapshots/nextInitializedTickWithinOneWord_lteFalse_gasCostOnBoundary.snap b/.forge-snapshots/nextInitializedTickWithinOneWord_lteFalse_gasCostOnBoundary.snap new file mode 100644 index 000000000..13f668d19 --- /dev/null +++ b/.forge-snapshots/nextInitializedTickWithinOneWord_lteFalse_gasCostOnBoundary.snap @@ -0,0 +1 @@ +2592 \ No newline at end of file diff --git a/.forge-snapshots/nextInitializedTickWithinOneWord_lteTrue_gasCostForEntireWord.snap b/.forge-snapshots/nextInitializedTickWithinOneWord_lteTrue_gasCostForEntireWord.snap new file mode 100644 index 000000000..0c52fc6da --- /dev/null +++ b/.forge-snapshots/nextInitializedTickWithinOneWord_lteTrue_gasCostForEntireWord.snap @@ -0,0 +1 @@ +2591 \ No newline at end of file diff --git a/.forge-snapshots/nextInitializedTickWithinOneWord_lteTrue_gasCostJustBelowBoundary.snap b/.forge-snapshots/nextInitializedTickWithinOneWord_lteTrue_gasCostJustBelowBoundary.snap new file mode 100644 index 000000000..7b34ebbf2 --- /dev/null +++ b/.forge-snapshots/nextInitializedTickWithinOneWord_lteTrue_gasCostJustBelowBoundary.snap @@ -0,0 +1 @@ +2900 \ No newline at end of file diff --git a/.forge-snapshots/nextInitializedTickWithinOneWord_lteTrue_gasCostOnBoundary.snap b/.forge-snapshots/nextInitializedTickWithinOneWord_lteTrue_gasCostOnBoundary.snap new file mode 100644 index 000000000..0c52fc6da --- /dev/null +++ b/.forge-snapshots/nextInitializedTickWithinOneWord_lteTrue_gasCostOnBoundary.snap @@ -0,0 +1 @@ +2591 \ No newline at end of file diff --git a/.forge-snapshots/poolManager bytecode size.snap b/.forge-snapshots/poolManager bytecode size.snap new file mode 100644 index 000000000..b83b06ad0 --- /dev/null +++ b/.forge-snapshots/poolManager bytecode size.snap @@ -0,0 +1 @@ +22916 \ No newline at end of file diff --git a/.forge-snapshots/removeLiquidity with empty hook.snap b/.forge-snapshots/removeLiquidity with empty hook.snap new file mode 100644 index 000000000..a6255bf63 --- /dev/null +++ b/.forge-snapshots/removeLiquidity with empty hook.snap @@ -0,0 +1 @@ +98918 \ No newline at end of file diff --git a/.forge-snapshots/removeLiquidity with native token.snap b/.forge-snapshots/removeLiquidity with native token.snap new file mode 100644 index 000000000..237b154b2 --- /dev/null +++ b/.forge-snapshots/removeLiquidity with native token.snap @@ -0,0 +1 @@ +200291 \ No newline at end of file diff --git a/.forge-snapshots/removeLiquidity.snap b/.forge-snapshots/removeLiquidity.snap new file mode 100644 index 000000000..edf9bc61e --- /dev/null +++ b/.forge-snapshots/removeLiquidity.snap @@ -0,0 +1 @@ +196568 \ No newline at end of file diff --git a/.forge-snapshots/simple swap with native.snap b/.forge-snapshots/simple swap with native.snap new file mode 100644 index 000000000..22626207c --- /dev/null +++ b/.forge-snapshots/simple swap with native.snap @@ -0,0 +1 @@ +187059 \ No newline at end of file diff --git a/.forge-snapshots/simple swap.snap b/.forge-snapshots/simple swap.snap new file mode 100644 index 000000000..ed2c28b83 --- /dev/null +++ b/.forge-snapshots/simple swap.snap @@ -0,0 +1 @@ +195599 \ 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 new file mode 100644 index 000000000..b71048c60 --- /dev/null +++ b/.forge-snapshots/swap against liquidity with native token.snap @@ -0,0 +1 @@ +117718 \ No newline at end of file diff --git a/.forge-snapshots/swap against liquidity.snap b/.forge-snapshots/swap against liquidity.snap new file mode 100644 index 000000000..39cc3aede --- /dev/null +++ b/.forge-snapshots/swap against liquidity.snap @@ -0,0 +1 @@ +105185 \ No newline at end of file diff --git a/.forge-snapshots/swap burn 6909 for input.snap b/.forge-snapshots/swap burn 6909 for input.snap new file mode 100644 index 000000000..c0e2b782d --- /dev/null +++ b/.forge-snapshots/swap burn 6909 for input.snap @@ -0,0 +1 @@ +125334 \ No newline at end of file diff --git a/.forge-snapshots/swap burn native 6909 for input.snap b/.forge-snapshots/swap burn native 6909 for input.snap new file mode 100644 index 000000000..ca8255ca2 --- /dev/null +++ b/.forge-snapshots/swap burn native 6909 for input.snap @@ -0,0 +1 @@ +121287 \ No newline at end of file diff --git a/.forge-snapshots/swap mint native output as 6909.snap b/.forge-snapshots/swap mint native output as 6909.snap new file mode 100644 index 000000000..45144a1bf --- /dev/null +++ b/.forge-snapshots/swap mint native output as 6909.snap @@ -0,0 +1 @@ +189617 \ No newline at end of file diff --git a/.forge-snapshots/swap mint output as 6909.snap b/.forge-snapshots/swap mint output as 6909.snap new file mode 100644 index 000000000..da45ee089 --- /dev/null +++ b/.forge-snapshots/swap mint output as 6909.snap @@ -0,0 +1 @@ +206426 \ No newline at end of file diff --git a/.forge-snapshots/swap with dynamic fee.snap b/.forge-snapshots/swap with dynamic fee.snap new file mode 100644 index 000000000..69e707ba9 --- /dev/null +++ b/.forge-snapshots/swap with dynamic fee.snap @@ -0,0 +1 @@ +138490 \ No newline at end of file diff --git a/.forge-snapshots/swap with hooks.snap b/.forge-snapshots/swap with hooks.snap new file mode 100644 index 000000000..57aab8283 --- /dev/null +++ b/.forge-snapshots/swap with hooks.snap @@ -0,0 +1 @@ +105163 \ No newline at end of file diff --git a/.forge-snapshots/tickSpacingToMaxLiquidityPerTick_gasCost60TickSpacing.snap b/.forge-snapshots/tickSpacingToMaxLiquidityPerTick_gasCost60TickSpacing.snap new file mode 100644 index 000000000..681cf043c --- /dev/null +++ b/.forge-snapshots/tickSpacingToMaxLiquidityPerTick_gasCost60TickSpacing.snap @@ -0,0 +1 @@ +192 \ No newline at end of file diff --git a/.forge-snapshots/tickSpacingToMaxLiquidityPerTick_gasCostMaxTickSpacing.snap b/.forge-snapshots/tickSpacingToMaxLiquidityPerTick_gasCostMaxTickSpacing.snap new file mode 100644 index 000000000..681cf043c --- /dev/null +++ b/.forge-snapshots/tickSpacingToMaxLiquidityPerTick_gasCostMaxTickSpacing.snap @@ -0,0 +1 @@ +192 \ No newline at end of file diff --git a/.forge-snapshots/tickSpacingToMaxLiquidityPerTick_gasCostMinTickSpacing.snap b/.forge-snapshots/tickSpacingToMaxLiquidityPerTick_gasCostMinTickSpacing.snap new file mode 100644 index 000000000..681cf043c --- /dev/null +++ b/.forge-snapshots/tickSpacingToMaxLiquidityPerTick_gasCostMinTickSpacing.snap @@ -0,0 +1 @@ +192 \ 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 new file mode 100644 index 000000000..9d47942f6 --- /dev/null +++ b/.forge-snapshots/update dynamic fee in before swap.snap @@ -0,0 +1 @@ +189532 \ No newline at end of file From 4f917fceaa5750b5924e745a3ce92690e7bb1527 Mon Sep 17 00:00:00 2001 From: Diana Kocsis Date: Wed, 20 Mar 2024 16:52:09 -0400 Subject: [PATCH 06/14] switch back to self instead of hook --- src/libraries/Hooks.sol | 102 ++++++++++++++++++++-------------------- 1 file changed, 51 insertions(+), 51 deletions(-) diff --git a/src/libraries/Hooks.sol b/src/libraries/Hooks.sol index cfe1d05af..6fed8bea9 100644 --- a/src/libraries/Hooks.sol +++ b/src/libraries/Hooks.sol @@ -53,51 +53,51 @@ library Hooks { /// the deployed hooks address causes the intended hooks to be called /// @param permissions The hooks that are intended to be called /// @dev permissions param is memory as the function will be called from constructors - function validateHookPermissions(IHooks hook, Permissions memory permissions) internal pure { + function validateHookPermissions(IHooks self, Permissions memory permissions) internal pure { if ( - permissions.beforeInitialize != hook.hasPermission(BEFORE_INITIALIZE_FLAG) - || permissions.afterInitialize != hook.hasPermission(AFTER_INITIALIZE_FLAG) - || permissions.beforeAddLiquidity != hook.hasPermission(BEFORE_ADD_LIQUIDITY_FLAG) - || permissions.afterAddLiquidity != hook.hasPermission(AFTER_ADD_LIQUIDITY_FLAG) - || permissions.beforeRemoveLiquidity != hook.hasPermission(BEFORE_REMOVE_LIQUIDITY_FLAG) - || permissions.afterRemoveLiquidity != hook.hasPermission(AFTER_REMOVE_LIQUIDITY_FLAG) - || permissions.beforeSwap != hook.hasPermission(BEFORE_SWAP_FLAG) - || permissions.afterSwap != hook.hasPermission(AFTER_SWAP_FLAG) - || permissions.beforeDonate != hook.hasPermission(BEFORE_DONATE_FLAG) - || permissions.afterDonate != hook.hasPermission(AFTER_DONATE_FLAG) + permissions.beforeInitialize != self.hasPermission(BEFORE_INITIALIZE_FLAG) + || permissions.afterInitialize != self.hasPermission(AFTER_INITIALIZE_FLAG) + || permissions.beforeAddLiquidity != self.hasPermission(BEFORE_ADD_LIQUIDITY_FLAG) + || permissions.afterAddLiquidity != self.hasPermission(AFTER_ADD_LIQUIDITY_FLAG) + || permissions.beforeRemoveLiquidity != self.hasPermission(BEFORE_REMOVE_LIQUIDITY_FLAG) + || permissions.afterRemoveLiquidity != self.hasPermission(AFTER_REMOVE_LIQUIDITY_FLAG) + || permissions.beforeSwap != self.hasPermission(BEFORE_SWAP_FLAG) + || permissions.afterSwap != self.hasPermission(AFTER_SWAP_FLAG) + || permissions.beforeDonate != self.hasPermission(BEFORE_DONATE_FLAG) + || permissions.afterDonate != self.hasPermission(AFTER_DONATE_FLAG) ) { - revert HookAddressNotValid(address(hook)); + revert HookAddressNotValid(address(self)); } } /// @notice Ensures that the hook address includes at least one hook flag or dynamic fees, or is the 0 address - /// @param hook The hook to verify - function isValidHookAddress(IHooks hook, uint24 fee) internal pure returns (bool) { + /// @param self The hook to verify + function isValidHookAddress(IHooks self, uint24 fee) internal pure returns (bool) { // If there is no hook contract set, then fee cannot be dynamic // If a hook contract is set, it must have at least 1 flag set, or have a dynamic fee - return address(hook) == address(0) + return address(self) == address(0) ? !fee.isDynamicFee() - : (uint160(address(hook)) >= AFTER_DONATE_FLAG || fee.isDynamicFee()); + : (uint160(address(self)) >= AFTER_DONATE_FLAG || fee.isDynamicFee()); } /// @notice performs a hook call using the given calldata on the given hook /// @return expectedSelector The selector that the hook is expected to return /// @return selector The selector that the hook actually returned - function _callHook(IHooks hook, bytes memory data) private returns (bytes4 expectedSelector, bytes4 selector) { + function _callHook(IHooks self, bytes memory data) private returns (bytes4 expectedSelector, bytes4 selector) { assembly { expectedSelector := mload(add(data, 0x20)) } - (bool success, bytes memory result) = address(hook).call(data); + (bool success, bytes memory result) = address(self).call(data); if (!success) _revert(result); selector = abi.decode(result, (bytes4)); } /// @notice performs a hook call using the given calldata on the given hook - function callHook(IHooks hook, bytes memory data) internal { - if (msg.sender == address(hook)) return; - (bytes4 expectedSelector, bytes4 selector) = _callHook(hook, data); + function callHook(IHooks self, bytes memory data) internal { + if (msg.sender == address(self)) return; + (bytes4 expectedSelector, bytes4 selector) = _callHook(self, data); if (selector != expectedSelector) { revert InvalidHookResponse(); @@ -105,22 +105,22 @@ library Hooks { } /// @notice calls beforeInitialize hook if permissioned and validates return value - function beforeInitialize(IHooks hook, PoolKey memory key, uint160 sqrtPriceX96, bytes calldata hookData) + function beforeInitialize(IHooks self, PoolKey memory key, uint160 sqrtPriceX96, bytes calldata hookData) internal { - if (hook.hasPermission(BEFORE_INITIALIZE_FLAG)) { - hook.callHook( + if (self.hasPermission(BEFORE_INITIALIZE_FLAG)) { + self.callHook( abi.encodeWithSelector(IHooks.beforeInitialize.selector, msg.sender, key, sqrtPriceX96, hookData) ); } } /// @notice calls afterInitialize hook if permissioned and validates return value - function afterInitialize(IHooks hook, PoolKey memory key, uint160 sqrtPriceX96, int24 tick, bytes calldata hookData) + function afterInitialize(IHooks self, PoolKey memory key, uint160 sqrtPriceX96, int24 tick, bytes calldata hookData) internal { - if (hook.hasPermission(AFTER_INITIALIZE_FLAG)) { - hook.callHook( + if (self.hasPermission(AFTER_INITIALIZE_FLAG)) { + self.callHook( abi.encodeWithSelector(IHooks.afterInitialize.selector, msg.sender, key, sqrtPriceX96, tick, hookData) ); } @@ -128,15 +128,15 @@ library Hooks { /// @notice calls beforeModifyLiquidity hook if permissioned and validates return value function beforeModifyLiquidity( - IHooks hook, + IHooks self, PoolKey memory key, IPoolManager.ModifyLiquidityParams memory params, bytes calldata hookData ) internal { - if (params.liquidityDelta > 0 && hook.hasPermission(BEFORE_ADD_LIQUIDITY_FLAG)) { - hook.callHook(abi.encodeWithSelector(IHooks.beforeAddLiquidity.selector, msg.sender, key, params, hookData)); - } else if (params.liquidityDelta <= 0 && hook.hasPermission(BEFORE_REMOVE_LIQUIDITY_FLAG)) { - hook.callHook( + if (params.liquidityDelta > 0 && self.hasPermission(BEFORE_ADD_LIQUIDITY_FLAG)) { + self.callHook(abi.encodeWithSelector(IHooks.beforeAddLiquidity.selector, msg.sender, key, params, hookData)); + } else if (params.liquidityDelta <= 0 && self.hasPermission(BEFORE_REMOVE_LIQUIDITY_FLAG)) { + self.callHook( abi.encodeWithSelector(IHooks.beforeRemoveLiquidity.selector, msg.sender, key, params, hookData) ); } @@ -144,69 +144,69 @@ library Hooks { /// @notice calls afterModifyLiquidity hook if permissioned and validates return value function afterModifyLiquidity( - IHooks hook, + IHooks self, PoolKey memory key, IPoolManager.ModifyLiquidityParams memory params, BalanceDelta delta, bytes calldata hookData ) internal { - if (params.liquidityDelta > 0 && hook.hasPermission(AFTER_ADD_LIQUIDITY_FLAG)) { - hook.callHook( + if (params.liquidityDelta > 0 && self.hasPermission(AFTER_ADD_LIQUIDITY_FLAG)) { + self.callHook( abi.encodeWithSelector(IHooks.afterAddLiquidity.selector, msg.sender, key, params, delta, hookData) ); - } else if (params.liquidityDelta <= 0 && hook.hasPermission(AFTER_REMOVE_LIQUIDITY_FLAG)) { - hook.callHook( + } else if (params.liquidityDelta <= 0 && self.hasPermission(AFTER_REMOVE_LIQUIDITY_FLAG)) { + self.callHook( abi.encodeWithSelector(IHooks.afterRemoveLiquidity.selector, msg.sender, key, params, delta, hookData) ); } } /// @notice calls beforeSwap hook if permissioned and validates return value - function beforeSwap(IHooks hook, PoolKey memory key, IPoolManager.SwapParams memory params, bytes calldata hookData) + function beforeSwap(IHooks self, PoolKey memory key, IPoolManager.SwapParams memory params, bytes calldata hookData) internal { - if (hook.hasPermission(BEFORE_SWAP_FLAG)) { - hook.callHook(abi.encodeWithSelector(IHooks.beforeSwap.selector, msg.sender, key, params, hookData)); + if (self.hasPermission(BEFORE_SWAP_FLAG)) { + self.callHook(abi.encodeWithSelector(IHooks.beforeSwap.selector, msg.sender, key, params, hookData)); } } /// @notice calls afterSwap hook if permissioned and validates return value function afterSwap( - IHooks hook, + IHooks self, PoolKey memory key, IPoolManager.SwapParams memory params, BalanceDelta delta, bytes calldata hookData ) internal { - if (hook.hasPermission(AFTER_SWAP_FLAG)) { - hook.callHook(abi.encodeWithSelector(IHooks.afterSwap.selector, msg.sender, key, params, delta, hookData)); + if (self.hasPermission(AFTER_SWAP_FLAG)) { + self.callHook(abi.encodeWithSelector(IHooks.afterSwap.selector, msg.sender, key, params, delta, hookData)); } } /// @notice calls beforeDonate hook if permissioned and validates return value - function beforeDonate(IHooks hook, PoolKey memory key, uint256 amount0, uint256 amount1, bytes calldata hookData) + function beforeDonate(IHooks self, PoolKey memory key, uint256 amount0, uint256 amount1, bytes calldata hookData) internal { - if (hook.hasPermission(BEFORE_DONATE_FLAG)) { - hook.callHook( + if (self.hasPermission(BEFORE_DONATE_FLAG)) { + self.callHook( abi.encodeWithSelector(IHooks.beforeDonate.selector, msg.sender, key, amount0, amount1, hookData) ); } } /// @notice calls afterDonate hook if permissioned and validates return value - function afterDonate(IHooks hook, PoolKey memory key, uint256 amount0, uint256 amount1, bytes calldata hookData) + function afterDonate(IHooks self, PoolKey memory key, uint256 amount0, uint256 amount1, bytes calldata hookData) internal { - if (hook.hasPermission(AFTER_DONATE_FLAG)) { - hook.callHook( + if (self.hasPermission(AFTER_DONATE_FLAG)) { + self.callHook( abi.encodeWithSelector(IHooks.afterDonate.selector, msg.sender, key, amount0, amount1, hookData) ); } } - function hasPermission(IHooks hook, uint256 flag) internal pure returns (bool) { - return uint256(uint160(address(hook))) & flag != 0; + function hasPermission(IHooks self, uint256 flag) internal pure returns (bool) { + return uint256(uint160(address(self))) & flag != 0; } /// @notice bubble up revert if present. Else throw FailedHookCall From 4bf924954fc800fc8496cc44272219af39302eb5 Mon Sep 17 00:00:00 2001 From: Diana Kocsis Date: Fri, 22 Mar 2024 16:07:24 -0400 Subject: [PATCH 07/14] more tests --- .forge-snapshots/donate gas with 1 token.snap | 2 +- .../donate gas with 2 tokens.snap | 2 +- src/test/PoolDonateTest.sol | 12 +- src/test/SkipCallsTestHook.sol | 146 ++++++++++++- test/SkipCallsTestHook.t.sol | 200 +++++++++++++++++- 5 files changed, 343 insertions(+), 19 deletions(-) diff --git a/.forge-snapshots/donate gas with 1 token.snap b/.forge-snapshots/donate gas with 1 token.snap index 522be2b14..846f87e6b 100644 --- a/.forge-snapshots/donate gas with 1 token.snap +++ b/.forge-snapshots/donate gas with 1 token.snap @@ -1 +1 @@ -131119 \ No newline at end of file +131041 \ 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 00283d71e..dd87206ae 100644 --- a/.forge-snapshots/donate gas with 2 tokens.snap +++ b/.forge-snapshots/donate gas with 2 tokens.snap @@ -1 +1 @@ -175942 \ No newline at end of file +175864 \ No newline at end of file diff --git a/src/test/PoolDonateTest.sol b/src/test/PoolDonateTest.sol index 0fad5786b..13fe95b2f 100644 --- a/src/test/PoolDonateTest.sol +++ b/src/test/PoolDonateTest.sol @@ -43,21 +43,17 @@ contract PoolDonateTest is PoolTestBase { CallbackData memory data = abi.decode(rawData, (CallbackData)); - (,, uint256 reserveBefore0, int256 deltaBefore0) = - _fetchBalances(data.key.currency0, data.sender, address(this)); - (,, uint256 reserveBefore1, int256 deltaBefore1) = - _fetchBalances(data.key.currency1, data.sender, address(this)); + (,,, int256 deltaBefore0) = _fetchBalances(data.key.currency0, data.sender, address(this)); + (,,, int256 deltaBefore1) = _fetchBalances(data.key.currency1, data.sender, address(this)); require(deltaBefore0 == 0, "deltaBefore0 is not 0"); require(deltaBefore1 == 0, "deltaBefore1 is not 0"); BalanceDelta delta = manager.donate(data.key, data.amount0, data.amount1, data.hookData); - (,, uint256 reserveAfter0, int256 deltaAfter0) = _fetchBalances(data.key.currency0, data.sender, address(this)); - (,, uint256 reserveAfter1, int256 deltaAfter1) = _fetchBalances(data.key.currency1, data.sender, address(this)); + (,,, int256 deltaAfter0) = _fetchBalances(data.key.currency0, data.sender, address(this)); + (,,, int256 deltaAfter1) = _fetchBalances(data.key.currency1, data.sender, address(this)); - require(reserveBefore0 == reserveAfter0, "reserveBefore0 is not equal to reserveAfter0"); - require(reserveBefore1 == reserveAfter1, "reserveBefore1 is not equal to reserveAfter1"); require(deltaAfter0 == -int256(data.amount0), "deltaAfter0 is not equal to -int256(data.amount0)"); require(deltaAfter1 == -int256(data.amount1), "deltaAfter1 is not equal to -int256(data.amount1)"); diff --git a/src/test/SkipCallsTestHook.sol b/src/test/SkipCallsTestHook.sol index 800d8e84e..ea11ddaab 100644 --- a/src/test/SkipCallsTestHook.sol +++ b/src/test/SkipCallsTestHook.sol @@ -11,6 +11,7 @@ import {PoolId, PoolIdLibrary} from "../types/PoolId.sol"; import {IERC20Minimal} from "../interfaces/external/IERC20Minimal.sol"; import {CurrencyLibrary, Currency} from "../types/Currency.sol"; import {PoolTestBase} from "./PoolTestBase.sol"; +import {Constants} from "../../test/utils/Constants.sol"; import {Test} from "forge-std/Test.sol"; contract SkipCallsTestHook is BaseTestHooks, Test { @@ -19,23 +20,129 @@ contract SkipCallsTestHook is BaseTestHooks, Test { uint256 public counter; IPoolManager manager; - uint24 internal fee; function setManager(IPoolManager _manager) external { manager = _manager; } + function beforeInitialize(address, PoolKey calldata key, uint160 sqrtPriceX96, bytes calldata hookData) + external + override + returns (bytes4) + { + counter++; + _initialize(key, sqrtPriceX96, hookData); + return IHooks.beforeInitialize.selector; + } + + function afterInitialize(address, PoolKey calldata key, uint160 sqrtPriceX96, int24, bytes calldata hookData) + external + override + returns (bytes4) + { + counter++; + _initialize(key, sqrtPriceX96, hookData); + return IHooks.afterInitialize.selector; + } + + function beforeAddLiquidity( + address, + PoolKey calldata key, + IPoolManager.ModifyLiquidityParams calldata, + bytes calldata hookData + ) external override returns (bytes4) { + counter++; + _initialize(key, Constants.SQRT_RATIO_1_1, hookData); + return IHooks.beforeAddLiquidity.selector; + } + + function afterAddLiquidity( + address, + PoolKey calldata key, + IPoolManager.ModifyLiquidityParams calldata, + BalanceDelta, + bytes calldata hookData + ) external override returns (bytes4) { + counter++; + _initialize(key, Constants.SQRT_RATIO_1_1, hookData); + return IHooks.afterAddLiquidity.selector; + } + + function beforeRemoveLiquidity( + address, + PoolKey calldata key, + IPoolManager.ModifyLiquidityParams calldata, + bytes calldata hookData + ) external override returns (bytes4) { + counter++; + IPoolManager.ModifyLiquidityParams memory newParams = + IPoolManager.ModifyLiquidityParams({tickLower: -120, tickUpper: 120, liquidityDelta: 0.1e18}); + _modifyLiquidity(key, newParams, hookData); + return IHooks.beforeRemoveLiquidity.selector; + } + + function afterRemoveLiquidity( + address, + PoolKey calldata key, + IPoolManager.ModifyLiquidityParams calldata, + BalanceDelta, + bytes calldata hookData + ) external override returns (bytes4) { + counter++; + IPoolManager.ModifyLiquidityParams memory newParams = + IPoolManager.ModifyLiquidityParams({tickLower: -120, tickUpper: 120, liquidityDelta: 0.1e18}); + _modifyLiquidity(key, newParams, hookData); + return IHooks.afterRemoveLiquidity.selector; + } + function beforeSwap(address, PoolKey calldata key, IPoolManager.SwapParams calldata params, bytes calldata hookData) external override returns (bytes4) { counter++; - callSwap(key, params, hookData); + _swap(key, params, hookData); return IHooks.beforeSwap.selector; } - function callSwap(PoolKey calldata key, IPoolManager.SwapParams calldata params, bytes calldata hookData) public { + function afterSwap( + address, + PoolKey calldata key, + IPoolManager.SwapParams calldata params, + BalanceDelta, + bytes calldata hookData + ) external override returns (bytes4) { + counter++; + _swap(key, params, hookData); + return IHooks.afterSwap.selector; + } + + function beforeDonate(address, PoolKey calldata key, uint256 amt0, uint256 amt1, bytes calldata hookData) + external + override + returns (bytes4) + { + counter++; + _donate(key, amt0, amt1, hookData); + return IHooks.beforeDonate.selector; + } + + function afterDonate(address, PoolKey calldata key, uint256 amt0, uint256 amt1, bytes calldata hookData) + external + override + returns (bytes4) + { + counter++; + _donate(key, amt0, amt1, hookData); + return IHooks.afterDonate.selector; + } + + function _initialize(PoolKey memory key, uint160 sqrtPriceX96, bytes calldata hookData) public { + key.fee = 2000; + IPoolManager(manager).initialize(key, sqrtPriceX96, hookData); + } + + function _swap(PoolKey calldata key, IPoolManager.SwapParams memory params, bytes calldata hookData) public { IPoolManager(manager).swap(key, params, hookData); address payer = abi.decode(hookData, (address)); int256 delta0 = IPoolManager(manager).currencyDelta(address(this), key.currency0); @@ -46,4 +153,37 @@ contract SkipCallsTestHook is BaseTestHooks, Test { manager.settle(key.currency0); manager.take(key.currency1, payer, uint256(delta1)); } + + function _modifyLiquidity( + PoolKey calldata key, + IPoolManager.ModifyLiquidityParams memory params, + bytes calldata hookData + ) public { + IPoolManager(manager).modifyLiquidity(key, params, hookData); + address payer = abi.decode(hookData, (address)); + int256 delta0 = IPoolManager(manager).currencyDelta(address(this), key.currency0); + int256 delta1 = IPoolManager(manager).currencyDelta(address(this), key.currency1); + if (params.liquidityDelta < 0) { + assert(delta0 > 0 || delta1 > 0); + assert(!(delta0 < 0 || delta1 < 0)); + } else if (params.liquidityDelta > 0) { + assert(delta0 < 0 || delta1 < 0); + assert(!(delta0 > 0 || delta1 > 0)); + } + IERC20Minimal(Currency.unwrap(key.currency0)).transferFrom(payer, address(manager), uint256(-delta0)); + manager.settle(key.currency0); + IERC20Minimal(Currency.unwrap(key.currency1)).transferFrom(payer, address(manager), uint256(-delta1)); + manager.settle(key.currency1); + } + + function _donate(PoolKey calldata key, uint256 amt0, uint256 amt1, bytes calldata hookData) public { + IPoolManager(manager).donate(key, amt0, amt1, hookData); + address payer = abi.decode(hookData, (address)); + int256 delta0 = IPoolManager(manager).currencyDelta(address(this), key.currency0); + int256 delta1 = IPoolManager(manager).currencyDelta(address(this), key.currency1); + IERC20Minimal(Currency.unwrap(key.currency0)).transferFrom(payer, address(manager), uint256(-delta0)); + IERC20Minimal(Currency.unwrap(key.currency1)).transferFrom(payer, address(manager), uint256(-delta1)); + manager.settle(key.currency0); + manager.settle(key.currency1); + } } diff --git a/test/SkipCallsTestHook.t.sol b/test/SkipCallsTestHook.t.sol index d1dfdc3b5..f6e6178d9 100644 --- a/test/SkipCallsTestHook.t.sol +++ b/test/SkipCallsTestHook.t.sol @@ -22,9 +22,13 @@ import {SkipCallsTestHook} from "../src/test/SkipCallsTestHook.sol"; contract SkipCallsTest is Test, Deployers, GasSnapshot { using PoolIdLibrary for PoolKey; - SkipCallsTestHook skipCallsTestHook = SkipCallsTestHook(address(uint160(Hooks.BEFORE_SWAP_FLAG))); + IPoolManager.SwapParams swapParams = + IPoolManager.SwapParams({zeroForOne: true, amountSpecified: -100, sqrtPriceLimitX96: SQRT_RATIO_1_2}); - function setUp() public { + PoolSwapTest.TestSettings testSettings = + PoolSwapTest.TestSettings({withdrawTokens: true, settleUsingTransfer: true, currencyAlreadySent: false}); + + function deploy(SkipCallsTestHook skipCallsTestHook) public { SkipCallsTestHook impl = new SkipCallsTestHook(); vm.etch(address(skipCallsTestHook), address(impl).code); deployFreshManagerAndRouters(); @@ -36,12 +40,152 @@ contract SkipCallsTest is Test, Deployers, GasSnapshot { ); } + function test_beforeInitialize_skipIfCalledByHook() public { + SkipCallsTestHook skipCallsTestHook = SkipCallsTestHook( + address( + uint160(0xFFfFfFffFFfffFFfFFfFFFFFffFFFffffFfFFFfF) + & uint160( + ~Hooks.AFTER_INITIALIZE_FLAG & ~Hooks.BEFORE_ADD_LIQUIDITY_FLAG & ~Hooks.AFTER_ADD_LIQUIDITY_FLAG + & ~Hooks.BEFORE_REMOVE_LIQUIDITY_FLAG & ~Hooks.AFTER_REMOVE_LIQUIDITY_FLAG & ~Hooks.BEFORE_SWAP_FLAG + & ~Hooks.AFTER_SWAP_FLAG & ~Hooks.BEFORE_DONATE_FLAG & ~Hooks.AFTER_DONATE_FLAG + ) + ) + ); + + deploy(skipCallsTestHook); + + assertEq(skipCallsTestHook.counter(), 1); + } + + function test_afterInitialize_skipIfCalledByHook() public { + SkipCallsTestHook skipCallsTestHook = SkipCallsTestHook( + address( + uint160(0xFFfFfFffFFfffFFfFFfFFFFFffFFFffffFfFFFfF) + & uint160( + ~Hooks.BEFORE_INITIALIZE_FLAG & ~Hooks.BEFORE_ADD_LIQUIDITY_FLAG & ~Hooks.AFTER_ADD_LIQUIDITY_FLAG + & ~Hooks.BEFORE_REMOVE_LIQUIDITY_FLAG & ~Hooks.AFTER_REMOVE_LIQUIDITY_FLAG & ~Hooks.BEFORE_SWAP_FLAG + & ~Hooks.AFTER_SWAP_FLAG & ~Hooks.BEFORE_DONATE_FLAG & ~Hooks.AFTER_DONATE_FLAG + ) + ) + ); + + deploy(skipCallsTestHook); + + assertEq(skipCallsTestHook.counter(), 1); + } + + function test_beforeAddLiquidity_skipIfCalledByHook() public { + SkipCallsTestHook skipCallsTestHook = SkipCallsTestHook( + address( + uint160(0xFFfFfFffFFfffFFfFFfFFFFFffFFFffffFfFFFfF) + & uint160( + ~Hooks.BEFORE_INITIALIZE_FLAG & ~Hooks.AFTER_INITIALIZE_FLAG & ~Hooks.AFTER_ADD_LIQUIDITY_FLAG + & ~Hooks.BEFORE_REMOVE_LIQUIDITY_FLAG & ~Hooks.AFTER_REMOVE_LIQUIDITY_FLAG & ~Hooks.BEFORE_SWAP_FLAG + & ~Hooks.AFTER_SWAP_FLAG & ~Hooks.BEFORE_DONATE_FLAG & ~Hooks.AFTER_DONATE_FLAG + ) + ) + ); + + deploy(skipCallsTestHook); + + assertEq(skipCallsTestHook.counter(), 1); + } + + function test_afterAddLiquidity_skipIfCalledByHook() public { + SkipCallsTestHook skipCallsTestHook = SkipCallsTestHook( + address( + uint160(0xFFfFfFffFFfffFFfFFfFFFFFffFFFffffFfFFFfF) + & uint160( + ~Hooks.BEFORE_INITIALIZE_FLAG & ~Hooks.AFTER_INITIALIZE_FLAG & ~Hooks.BEFORE_ADD_LIQUIDITY_FLAG + & ~Hooks.BEFORE_REMOVE_LIQUIDITY_FLAG & ~Hooks.AFTER_REMOVE_LIQUIDITY_FLAG & ~Hooks.BEFORE_SWAP_FLAG + & ~Hooks.AFTER_SWAP_FLAG & ~Hooks.BEFORE_DONATE_FLAG & ~Hooks.AFTER_DONATE_FLAG + ) + ) + ); + + deploy(skipCallsTestHook); + + assertEq(skipCallsTestHook.counter(), 1); + } + + function test_beforeRemoveLiquidity_skipIfCalledByHook() public { + SkipCallsTestHook skipCallsTestHook = SkipCallsTestHook( + address( + uint160(0xFFfFfFffFFfffFFfFFfFFFFFffFFFffffFfFFFfF) + & uint160( + ~Hooks.BEFORE_INITIALIZE_FLAG & ~Hooks.AFTER_INITIALIZE_FLAG & ~Hooks.BEFORE_ADD_LIQUIDITY_FLAG + & ~Hooks.AFTER_ADD_LIQUIDITY_FLAG & ~Hooks.AFTER_REMOVE_LIQUIDITY_FLAG & ~Hooks.BEFORE_SWAP_FLAG + & ~Hooks.AFTER_SWAP_FLAG & ~Hooks.BEFORE_DONATE_FLAG & ~Hooks.AFTER_DONATE_FLAG + ) + ) + ); + + deploy(skipCallsTestHook); + + MockERC20(Currency.unwrap(key.currency0)).approve(address(skipCallsTestHook), Constants.MAX_UINT256); + MockERC20(Currency.unwrap(key.currency1)).approve(address(skipCallsTestHook), Constants.MAX_UINT256); + modifyLiquidityRouter.modifyLiquidity(key, LIQ_PARAMS, ZERO_BYTES); + modifyLiquidityRouter.modifyLiquidity(key, REMOVE_LIQ_PARAMS, abi.encode(address(this))); + assertEq(skipCallsTestHook.counter(), 1); + } + + function test_afterRemoveLiquidity_skipIfCalledByHook() public { + SkipCallsTestHook skipCallsTestHook = SkipCallsTestHook( + address( + uint160(0xFFfFfFffFFfffFFfFFfFFFFFffFFFffffFfFFFfF) + & uint160( + ~Hooks.BEFORE_INITIALIZE_FLAG & ~Hooks.AFTER_INITIALIZE_FLAG & ~Hooks.BEFORE_ADD_LIQUIDITY_FLAG + & ~Hooks.AFTER_ADD_LIQUIDITY_FLAG & ~Hooks.BEFORE_REMOVE_LIQUIDITY_FLAG & ~Hooks.BEFORE_SWAP_FLAG + & ~Hooks.AFTER_SWAP_FLAG & ~Hooks.BEFORE_DONATE_FLAG & ~Hooks.AFTER_DONATE_FLAG + ) + ) + ); + + deploy(skipCallsTestHook); + + MockERC20(Currency.unwrap(key.currency0)).approve(address(skipCallsTestHook), Constants.MAX_UINT256); + MockERC20(Currency.unwrap(key.currency1)).approve(address(skipCallsTestHook), Constants.MAX_UINT256); + modifyLiquidityRouter.modifyLiquidity(key, LIQ_PARAMS, ZERO_BYTES); + modifyLiquidityRouter.modifyLiquidity(key, REMOVE_LIQ_PARAMS, abi.encode(address(this))); + assertEq(skipCallsTestHook.counter(), 1); + } + function test_beforeSwap_skipIfCalledByHook() public { - IPoolManager.SwapParams memory swapParams = - IPoolManager.SwapParams({zeroForOne: true, amountSpecified: -100, sqrtPriceLimitX96: SQRT_RATIO_1_2}); + SkipCallsTestHook skipCallsTestHook = SkipCallsTestHook( + address( + uint160(0xFFfFfFffFFfffFFfFFfFFFFFffFFFffffFfFFFfF) + & uint160( + ~Hooks.BEFORE_INITIALIZE_FLAG & ~Hooks.AFTER_INITIALIZE_FLAG & ~Hooks.BEFORE_ADD_LIQUIDITY_FLAG + & ~Hooks.AFTER_ADD_LIQUIDITY_FLAG & ~Hooks.BEFORE_REMOVE_LIQUIDITY_FLAG + & ~Hooks.AFTER_REMOVE_LIQUIDITY_FLAG & ~Hooks.AFTER_SWAP_FLAG & ~Hooks.BEFORE_DONATE_FLAG + & ~Hooks.AFTER_DONATE_FLAG + ) + ) + ); + + deploy(skipCallsTestHook); + + MockERC20(Currency.unwrap(key.currency0)).approve(address(skipCallsTestHook), Constants.MAX_UINT256); + + assertEq(skipCallsTestHook.counter(), 0); + swapRouter.swap(key, swapParams, testSettings, abi.encode(address(this))); + assertEq(skipCallsTestHook.counter(), 1); + } + + function test_afterSwap_skipIfCalledByHook() public { + SkipCallsTestHook skipCallsTestHook = SkipCallsTestHook( + address( + uint160(0xFFfFfFffFFfffFFfFFfFFFFFffFFFffffFfFFFfF) + & uint160( + ~Hooks.BEFORE_INITIALIZE_FLAG & ~Hooks.AFTER_INITIALIZE_FLAG & ~Hooks.BEFORE_ADD_LIQUIDITY_FLAG + & ~Hooks.AFTER_ADD_LIQUIDITY_FLAG & ~Hooks.BEFORE_REMOVE_LIQUIDITY_FLAG + & ~Hooks.AFTER_REMOVE_LIQUIDITY_FLAG & ~Hooks.BEFORE_SWAP_FLAG & ~Hooks.BEFORE_DONATE_FLAG + & ~Hooks.AFTER_DONATE_FLAG + ) + ) + ); - PoolSwapTest.TestSettings memory testSettings = - PoolSwapTest.TestSettings({withdrawTokens: true, settleUsingTransfer: true, currencyAlreadySent: false}); + deploy(skipCallsTestHook); MockERC20(Currency.unwrap(key.currency0)).approve(address(skipCallsTestHook), Constants.MAX_UINT256); @@ -49,4 +193,48 @@ contract SkipCallsTest is Test, Deployers, GasSnapshot { swapRouter.swap(key, swapParams, testSettings, abi.encode(address(this))); assertEq(skipCallsTestHook.counter(), 1); } + + function test_beforeDonate_skipIfCalledByHook() public { + SkipCallsTestHook skipCallsTestHook = SkipCallsTestHook( + address( + uint160(0xFFfFfFffFFfffFFfFFfFFFFFffFFFffffFfFFFfF) + & uint160( + ~Hooks.BEFORE_INITIALIZE_FLAG & ~Hooks.AFTER_INITIALIZE_FLAG & ~Hooks.BEFORE_ADD_LIQUIDITY_FLAG + & ~Hooks.AFTER_ADD_LIQUIDITY_FLAG & ~Hooks.BEFORE_REMOVE_LIQUIDITY_FLAG + & ~Hooks.AFTER_REMOVE_LIQUIDITY_FLAG & ~Hooks.BEFORE_SWAP_FLAG & ~Hooks.AFTER_SWAP_FLAG + & ~Hooks.AFTER_DONATE_FLAG + ) + ) + ); + + deploy(skipCallsTestHook); + + assertEq(skipCallsTestHook.counter(), 0); + MockERC20(Currency.unwrap(key.currency0)).approve(address(skipCallsTestHook), Constants.MAX_UINT256); + MockERC20(Currency.unwrap(key.currency1)).approve(address(skipCallsTestHook), Constants.MAX_UINT256); + donateRouter.donate(key, 100, 200, abi.encode(address(this))); + assertEq(skipCallsTestHook.counter(), 1); + } + + function test_afterDonate_skipIfCalledByHook() public { + SkipCallsTestHook skipCallsTestHook = SkipCallsTestHook( + address( + uint160(0xFFfFfFffFFfffFFfFFfFFFFFffFFFffffFfFFFfF) + & uint160( + ~Hooks.BEFORE_INITIALIZE_FLAG & ~Hooks.AFTER_INITIALIZE_FLAG & ~Hooks.BEFORE_ADD_LIQUIDITY_FLAG + & ~Hooks.AFTER_ADD_LIQUIDITY_FLAG & ~Hooks.BEFORE_REMOVE_LIQUIDITY_FLAG + & ~Hooks.AFTER_REMOVE_LIQUIDITY_FLAG & ~Hooks.BEFORE_SWAP_FLAG & ~Hooks.AFTER_SWAP_FLAG + & ~Hooks.BEFORE_DONATE_FLAG + ) + ) + ); + + deploy(skipCallsTestHook); + + assertEq(skipCallsTestHook.counter(), 0); + MockERC20(Currency.unwrap(key.currency0)).approve(address(skipCallsTestHook), Constants.MAX_UINT256); + MockERC20(Currency.unwrap(key.currency1)).approve(address(skipCallsTestHook), Constants.MAX_UINT256); + donateRouter.donate(key, 100, 200, abi.encode(address(this))); + assertEq(skipCallsTestHook.counter(), 1); + } } From c399dc1c7798cba4e40c81da85021d3934a7d73c Mon Sep 17 00:00:00 2001 From: Diana Kocsis Date: Wed, 3 Apr 2024 13:14:18 -0400 Subject: [PATCH 08/14] call again and assert counter is 2 --- .forge-snapshots/donate gas with 1 token.snap | 2 +- .../donate gas with 2 tokens.snap | 2 +- src/test/PoolDonateTest.sol | 6 ++---- test/SkipCallsTestHook.t.sol | 19 +++++++++++++++---- 4 files changed, 19 insertions(+), 10 deletions(-) diff --git a/.forge-snapshots/donate gas with 1 token.snap b/.forge-snapshots/donate gas with 1 token.snap index 48bbfec56..e7b535cf2 100644 --- a/.forge-snapshots/donate gas with 1 token.snap +++ b/.forge-snapshots/donate gas with 1 token.snap @@ -1 +1 @@ -125216 \ No newline at end of file +125200 \ 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 dc1b22b81..aa8206a9a 100644 --- a/.forge-snapshots/donate gas with 2 tokens.snap +++ b/.forge-snapshots/donate gas with 2 tokens.snap @@ -1 +1 @@ -172075 \ No newline at end of file +172059 \ No newline at end of file diff --git a/src/test/PoolDonateTest.sol b/src/test/PoolDonateTest.sol index 0777e5a92..55d95c392 100644 --- a/src/test/PoolDonateTest.sol +++ b/src/test/PoolDonateTest.sol @@ -51,10 +51,8 @@ contract PoolDonateTest is PoolTestBase { BalanceDelta delta = manager.donate(data.key, data.amount0, data.amount1, data.hookData); - (, uint256 poolBalanceAfter0, int256 deltaAfter0) = - _fetchBalances(data.key.currency0, data.sender, address(this)); - (, uint256 poolBalanceAfter1, int256 deltaAfter1) = - _fetchBalances(data.key.currency1, data.sender, address(this)); + (,, int256 deltaAfter0) = _fetchBalances(data.key.currency0, data.sender, address(this)); + (,, int256 deltaAfter1) = _fetchBalances(data.key.currency1, data.sender, address(this)); require(deltaAfter0 == -int256(data.amount0), "deltaAfter0 is not equal to -int256(data.amount0)"); require(deltaAfter1 == -int256(data.amount1), "deltaAfter1 is not equal to -int256(data.amount1)"); diff --git a/test/SkipCallsTestHook.t.sol b/test/SkipCallsTestHook.t.sol index f6e6178d9..da0a4a2ae 100644 --- a/test/SkipCallsTestHook.t.sol +++ b/test/SkipCallsTestHook.t.sol @@ -35,6 +35,9 @@ contract SkipCallsTest is Test, Deployers, GasSnapshot { skipCallsTestHook.setManager(IPoolManager(manager)); (currency0, currency1) = deployMintAndApprove2Currencies(); + + assertEq(skipCallsTestHook.counter(), 0); + (key,) = initPoolAndAddLiquidity( currency0, currency1, IHooks(address(skipCallsTestHook)), 3000, SQRT_RATIO_1_1, ZERO_BYTES ); @@ -127,6 +130,8 @@ contract SkipCallsTest is Test, Deployers, GasSnapshot { modifyLiquidityRouter.modifyLiquidity(key, LIQ_PARAMS, ZERO_BYTES); modifyLiquidityRouter.modifyLiquidity(key, REMOVE_LIQ_PARAMS, abi.encode(address(this))); assertEq(skipCallsTestHook.counter(), 1); + modifyLiquidityRouter.modifyLiquidity(key, REMOVE_LIQ_PARAMS, abi.encode(address(this))); + assertEq(skipCallsTestHook.counter(), 2); } function test_afterRemoveLiquidity_skipIfCalledByHook() public { @@ -148,6 +153,8 @@ contract SkipCallsTest is Test, Deployers, GasSnapshot { modifyLiquidityRouter.modifyLiquidity(key, LIQ_PARAMS, ZERO_BYTES); modifyLiquidityRouter.modifyLiquidity(key, REMOVE_LIQ_PARAMS, abi.encode(address(this))); assertEq(skipCallsTestHook.counter(), 1); + modifyLiquidityRouter.modifyLiquidity(key, REMOVE_LIQ_PARAMS, abi.encode(address(this))); + assertEq(skipCallsTestHook.counter(), 2); } function test_beforeSwap_skipIfCalledByHook() public { @@ -167,9 +174,10 @@ contract SkipCallsTest is Test, Deployers, GasSnapshot { MockERC20(Currency.unwrap(key.currency0)).approve(address(skipCallsTestHook), Constants.MAX_UINT256); - assertEq(skipCallsTestHook.counter(), 0); swapRouter.swap(key, swapParams, testSettings, abi.encode(address(this))); assertEq(skipCallsTestHook.counter(), 1); + swapRouter.swap(key, swapParams, testSettings, abi.encode(address(this))); + assertEq(skipCallsTestHook.counter(), 2); } function test_afterSwap_skipIfCalledByHook() public { @@ -189,9 +197,10 @@ contract SkipCallsTest is Test, Deployers, GasSnapshot { MockERC20(Currency.unwrap(key.currency0)).approve(address(skipCallsTestHook), Constants.MAX_UINT256); - assertEq(skipCallsTestHook.counter(), 0); swapRouter.swap(key, swapParams, testSettings, abi.encode(address(this))); assertEq(skipCallsTestHook.counter(), 1); + swapRouter.swap(key, swapParams, testSettings, abi.encode(address(this))); + assertEq(skipCallsTestHook.counter(), 2); } function test_beforeDonate_skipIfCalledByHook() public { @@ -209,11 +218,12 @@ contract SkipCallsTest is Test, Deployers, GasSnapshot { deploy(skipCallsTestHook); - assertEq(skipCallsTestHook.counter(), 0); MockERC20(Currency.unwrap(key.currency0)).approve(address(skipCallsTestHook), Constants.MAX_UINT256); MockERC20(Currency.unwrap(key.currency1)).approve(address(skipCallsTestHook), Constants.MAX_UINT256); donateRouter.donate(key, 100, 200, abi.encode(address(this))); assertEq(skipCallsTestHook.counter(), 1); + donateRouter.donate(key, 100, 200, abi.encode(address(this))); + assertEq(skipCallsTestHook.counter(), 2); } function test_afterDonate_skipIfCalledByHook() public { @@ -231,10 +241,11 @@ contract SkipCallsTest is Test, Deployers, GasSnapshot { deploy(skipCallsTestHook); - assertEq(skipCallsTestHook.counter(), 0); MockERC20(Currency.unwrap(key.currency0)).approve(address(skipCallsTestHook), Constants.MAX_UINT256); MockERC20(Currency.unwrap(key.currency1)).approve(address(skipCallsTestHook), Constants.MAX_UINT256); donateRouter.donate(key, 100, 200, abi.encode(address(this))); assertEq(skipCallsTestHook.counter(), 1); + donateRouter.donate(key, 100, 200, abi.encode(address(this))); + assertEq(skipCallsTestHook.counter(), 2); } } From a55b9c1f7454a47f4ca106ce8b4d77f5c8b65f59 Mon Sep 17 00:00:00 2001 From: Diana Kocsis Date: Wed, 3 Apr 2024 15:37:10 -0400 Subject: [PATCH 09/14] make more clear --- src/test/SkipCallsTestHook.sol | 58 ++++++++++++++++++++++------------ test/SkipCallsTestHook.t.sol | 40 ++++++++++++----------- 2 files changed, 60 insertions(+), 38 deletions(-) diff --git a/src/test/SkipCallsTestHook.sol b/src/test/SkipCallsTestHook.sol index ea11ddaab..0ebc72185 100644 --- a/src/test/SkipCallsTestHook.sol +++ b/src/test/SkipCallsTestHook.sol @@ -48,50 +48,46 @@ contract SkipCallsTestHook is BaseTestHooks, Test { function beforeAddLiquidity( address, PoolKey calldata key, - IPoolManager.ModifyLiquidityParams calldata, + IPoolManager.ModifyLiquidityParams calldata params, bytes calldata hookData ) external override returns (bytes4) { counter++; - _initialize(key, Constants.SQRT_RATIO_1_1, hookData); + _addLiquidity(key, params, hookData); return IHooks.beforeAddLiquidity.selector; } function afterAddLiquidity( address, PoolKey calldata key, - IPoolManager.ModifyLiquidityParams calldata, + IPoolManager.ModifyLiquidityParams calldata params, BalanceDelta, bytes calldata hookData ) external override returns (bytes4) { counter++; - _initialize(key, Constants.SQRT_RATIO_1_1, hookData); + _addLiquidity(key, params, hookData); return IHooks.afterAddLiquidity.selector; } function beforeRemoveLiquidity( address, PoolKey calldata key, - IPoolManager.ModifyLiquidityParams calldata, + IPoolManager.ModifyLiquidityParams calldata params, bytes calldata hookData ) external override returns (bytes4) { counter++; - IPoolManager.ModifyLiquidityParams memory newParams = - IPoolManager.ModifyLiquidityParams({tickLower: -120, tickUpper: 120, liquidityDelta: 0.1e18}); - _modifyLiquidity(key, newParams, hookData); + _removeLiquidity(key, params, hookData); return IHooks.beforeRemoveLiquidity.selector; } function afterRemoveLiquidity( address, PoolKey calldata key, - IPoolManager.ModifyLiquidityParams calldata, + IPoolManager.ModifyLiquidityParams calldata params, BalanceDelta, bytes calldata hookData ) external override returns (bytes4) { counter++; - IPoolManager.ModifyLiquidityParams memory newParams = - IPoolManager.ModifyLiquidityParams({tickLower: -120, tickUpper: 120, liquidityDelta: 0.1e18}); - _modifyLiquidity(key, newParams, hookData); + _removeLiquidity(key, params, hookData); return IHooks.afterRemoveLiquidity.selector; } @@ -138,6 +134,7 @@ contract SkipCallsTestHook is BaseTestHooks, Test { } function _initialize(PoolKey memory key, uint160 sqrtPriceX96, bytes calldata hookData) public { + // initialize a new pool with different fee key.fee = 2000; IPoolManager(manager).initialize(key, sqrtPriceX96, hookData); } @@ -154,7 +151,7 @@ contract SkipCallsTestHook is BaseTestHooks, Test { manager.take(key.currency1, payer, uint256(delta1)); } - function _modifyLiquidity( + function _addLiquidity( PoolKey calldata key, IPoolManager.ModifyLiquidityParams memory params, bytes calldata hookData @@ -163,13 +160,34 @@ contract SkipCallsTestHook is BaseTestHooks, Test { address payer = abi.decode(hookData, (address)); int256 delta0 = IPoolManager(manager).currencyDelta(address(this), key.currency0); int256 delta1 = IPoolManager(manager).currencyDelta(address(this), key.currency1); - if (params.liquidityDelta < 0) { - assert(delta0 > 0 || delta1 > 0); - assert(!(delta0 < 0 || delta1 < 0)); - } else if (params.liquidityDelta > 0) { - assert(delta0 < 0 || delta1 < 0); - assert(!(delta0 > 0 || delta1 > 0)); - } + + assert(delta0 < 0 || delta1 < 0); + assert(!(delta0 > 0 || delta1 > 0)); + + IERC20Minimal(Currency.unwrap(key.currency0)).transferFrom(payer, address(manager), uint256(-delta0)); + manager.settle(key.currency0); + IERC20Minimal(Currency.unwrap(key.currency1)).transferFrom(payer, address(manager), uint256(-delta1)); + manager.settle(key.currency1); + } + + function _removeLiquidity( + PoolKey calldata key, + IPoolManager.ModifyLiquidityParams memory params, + bytes calldata hookData + ) public { + // first hook needs to add liquidity for itself + IPoolManager.ModifyLiquidityParams memory newParams = + IPoolManager.ModifyLiquidityParams({tickLower: -120, tickUpper: 120, liquidityDelta: 1e18}); + IPoolManager(manager).modifyLiquidity(key, newParams, hookData); + // hook removes liquidity + IPoolManager(manager).modifyLiquidity(key, params, hookData); + address payer = abi.decode(hookData, (address)); + int256 delta0 = IPoolManager(manager).currencyDelta(address(this), key.currency0); + int256 delta1 = IPoolManager(manager).currencyDelta(address(this), key.currency1); + + assert(delta0 < 0 || delta1 < 0); + assert(!(delta0 > 0 || delta1 > 0)); + IERC20Minimal(Currency.unwrap(key.currency0)).transferFrom(payer, address(manager), uint256(-delta0)); manager.settle(key.currency0); IERC20Minimal(Currency.unwrap(key.currency1)).transferFrom(payer, address(manager), uint256(-delta1)); diff --git a/test/SkipCallsTestHook.t.sol b/test/SkipCallsTestHook.t.sol index da0a4a2ae..870498422 100644 --- a/test/SkipCallsTestHook.t.sol +++ b/test/SkipCallsTestHook.t.sol @@ -28,7 +28,7 @@ contract SkipCallsTest is Test, Deployers, GasSnapshot { PoolSwapTest.TestSettings testSettings = PoolSwapTest.TestSettings({withdrawTokens: true, settleUsingTransfer: true, currencyAlreadySent: false}); - function deploy(SkipCallsTestHook skipCallsTestHook) public { + function deploy(SkipCallsTestHook skipCallsTestHook) private { SkipCallsTestHook impl = new SkipCallsTestHook(); vm.etch(address(skipCallsTestHook), address(impl).code); deployFreshManagerAndRouters(); @@ -38,9 +38,13 @@ contract SkipCallsTest is Test, Deployers, GasSnapshot { assertEq(skipCallsTestHook.counter(), 0); - (key,) = initPoolAndAddLiquidity( - currency0, currency1, IHooks(address(skipCallsTestHook)), 3000, SQRT_RATIO_1_1, ZERO_BYTES - ); + (key,) = initPool(currency0, currency1, IHooks(address(skipCallsTestHook)), 3000, SQRT_RATIO_1_1, ZERO_BYTES); + } + + function approveAndAddLiquidity(SkipCallsTestHook skipCallsTestHook) private { + MockERC20(Currency.unwrap(key.currency0)).approve(address(skipCallsTestHook), Constants.MAX_UINT256); + MockERC20(Currency.unwrap(key.currency1)).approve(address(skipCallsTestHook), Constants.MAX_UINT256); + modifyLiquidityRouter.modifyLiquidity(key, LIQ_PARAMS, abi.encode(address(this))); } function test_beforeInitialize_skipIfCalledByHook() public { @@ -91,7 +95,10 @@ contract SkipCallsTest is Test, Deployers, GasSnapshot { deploy(skipCallsTestHook); + approveAndAddLiquidity(skipCallsTestHook); assertEq(skipCallsTestHook.counter(), 1); + modifyLiquidityRouter.modifyLiquidity(key, LIQ_PARAMS, abi.encode(address(this))); + assertEq(skipCallsTestHook.counter(), 2); } function test_afterAddLiquidity_skipIfCalledByHook() public { @@ -108,7 +115,10 @@ contract SkipCallsTest is Test, Deployers, GasSnapshot { deploy(skipCallsTestHook); + approveAndAddLiquidity(skipCallsTestHook); assertEq(skipCallsTestHook.counter(), 1); + modifyLiquidityRouter.modifyLiquidity(key, LIQ_PARAMS, abi.encode(address(this))); + assertEq(skipCallsTestHook.counter(), 2); } function test_beforeRemoveLiquidity_skipIfCalledByHook() public { @@ -124,12 +134,11 @@ contract SkipCallsTest is Test, Deployers, GasSnapshot { ); deploy(skipCallsTestHook); + approveAndAddLiquidity(skipCallsTestHook); - MockERC20(Currency.unwrap(key.currency0)).approve(address(skipCallsTestHook), Constants.MAX_UINT256); - MockERC20(Currency.unwrap(key.currency1)).approve(address(skipCallsTestHook), Constants.MAX_UINT256); - modifyLiquidityRouter.modifyLiquidity(key, LIQ_PARAMS, ZERO_BYTES); modifyLiquidityRouter.modifyLiquidity(key, REMOVE_LIQ_PARAMS, abi.encode(address(this))); assertEq(skipCallsTestHook.counter(), 1); + modifyLiquidityRouter.modifyLiquidity(key, LIQ_PARAMS, abi.encode(address(this))); modifyLiquidityRouter.modifyLiquidity(key, REMOVE_LIQ_PARAMS, abi.encode(address(this))); assertEq(skipCallsTestHook.counter(), 2); } @@ -147,12 +156,11 @@ contract SkipCallsTest is Test, Deployers, GasSnapshot { ); deploy(skipCallsTestHook); + approveAndAddLiquidity(skipCallsTestHook); - MockERC20(Currency.unwrap(key.currency0)).approve(address(skipCallsTestHook), Constants.MAX_UINT256); - MockERC20(Currency.unwrap(key.currency1)).approve(address(skipCallsTestHook), Constants.MAX_UINT256); - modifyLiquidityRouter.modifyLiquidity(key, LIQ_PARAMS, ZERO_BYTES); modifyLiquidityRouter.modifyLiquidity(key, REMOVE_LIQ_PARAMS, abi.encode(address(this))); assertEq(skipCallsTestHook.counter(), 1); + modifyLiquidityRouter.modifyLiquidity(key, LIQ_PARAMS, abi.encode(address(this))); modifyLiquidityRouter.modifyLiquidity(key, REMOVE_LIQ_PARAMS, abi.encode(address(this))); assertEq(skipCallsTestHook.counter(), 2); } @@ -171,8 +179,7 @@ contract SkipCallsTest is Test, Deployers, GasSnapshot { ); deploy(skipCallsTestHook); - - MockERC20(Currency.unwrap(key.currency0)).approve(address(skipCallsTestHook), Constants.MAX_UINT256); + approveAndAddLiquidity(skipCallsTestHook); swapRouter.swap(key, swapParams, testSettings, abi.encode(address(this))); assertEq(skipCallsTestHook.counter(), 1); @@ -194,8 +201,7 @@ contract SkipCallsTest is Test, Deployers, GasSnapshot { ); deploy(skipCallsTestHook); - - MockERC20(Currency.unwrap(key.currency0)).approve(address(skipCallsTestHook), Constants.MAX_UINT256); + approveAndAddLiquidity(skipCallsTestHook); swapRouter.swap(key, swapParams, testSettings, abi.encode(address(this))); assertEq(skipCallsTestHook.counter(), 1); @@ -217,9 +223,8 @@ contract SkipCallsTest is Test, Deployers, GasSnapshot { ); deploy(skipCallsTestHook); + approveAndAddLiquidity(skipCallsTestHook); - MockERC20(Currency.unwrap(key.currency0)).approve(address(skipCallsTestHook), Constants.MAX_UINT256); - MockERC20(Currency.unwrap(key.currency1)).approve(address(skipCallsTestHook), Constants.MAX_UINT256); donateRouter.donate(key, 100, 200, abi.encode(address(this))); assertEq(skipCallsTestHook.counter(), 1); donateRouter.donate(key, 100, 200, abi.encode(address(this))); @@ -240,9 +245,8 @@ contract SkipCallsTest is Test, Deployers, GasSnapshot { ); deploy(skipCallsTestHook); + approveAndAddLiquidity(skipCallsTestHook); - MockERC20(Currency.unwrap(key.currency0)).approve(address(skipCallsTestHook), Constants.MAX_UINT256); - MockERC20(Currency.unwrap(key.currency1)).approve(address(skipCallsTestHook), Constants.MAX_UINT256); donateRouter.donate(key, 100, 200, abi.encode(address(this))); assertEq(skipCallsTestHook.counter(), 1); donateRouter.donate(key, 100, 200, abi.encode(address(this))); From aeb2dae533c905e9221e50452eb48b9f8ba58f08 Mon Sep 17 00:00:00 2001 From: Diana Kocsis Date: Thu, 4 Apr 2024 17:53:42 -0400 Subject: [PATCH 10/14] clearAllHookPermisssionsMask --- src/libraries/Hooks.sol | 20 +++--- test/SkipCallsTestHook.t.sol | 119 +++++++---------------------------- 2 files changed, 33 insertions(+), 106 deletions(-) diff --git a/src/libraries/Hooks.sol b/src/libraries/Hooks.sol index 6fed8bea9..fa503fb11 100644 --- a/src/libraries/Hooks.sol +++ b/src/libraries/Hooks.sol @@ -15,16 +15,16 @@ library Hooks { using SwapFeeLibrary for uint24; using Hooks for IHooks; - uint256 internal constant BEFORE_INITIALIZE_FLAG = 1 << 159; - uint256 internal constant AFTER_INITIALIZE_FLAG = 1 << 158; - uint256 internal constant BEFORE_ADD_LIQUIDITY_FLAG = 1 << 157; - uint256 internal constant AFTER_ADD_LIQUIDITY_FLAG = 1 << 156; - uint256 internal constant BEFORE_REMOVE_LIQUIDITY_FLAG = 1 << 155; - uint256 internal constant AFTER_REMOVE_LIQUIDITY_FLAG = 1 << 154; - uint256 internal constant BEFORE_SWAP_FLAG = 1 << 153; - uint256 internal constant AFTER_SWAP_FLAG = 1 << 152; - uint256 internal constant BEFORE_DONATE_FLAG = 1 << 151; - uint256 internal constant AFTER_DONATE_FLAG = 1 << 150; + uint160 internal constant BEFORE_INITIALIZE_FLAG = 1 << 159; + uint160 internal constant AFTER_INITIALIZE_FLAG = 1 << 158; + uint160 internal constant BEFORE_ADD_LIQUIDITY_FLAG = 1 << 157; + uint160 internal constant AFTER_ADD_LIQUIDITY_FLAG = 1 << 156; + uint160 internal constant BEFORE_REMOVE_LIQUIDITY_FLAG = 1 << 155; + uint160 internal constant AFTER_REMOVE_LIQUIDITY_FLAG = 1 << 154; + uint160 internal constant BEFORE_SWAP_FLAG = 1 << 153; + uint160 internal constant AFTER_SWAP_FLAG = 1 << 152; + uint160 internal constant BEFORE_DONATE_FLAG = 1 << 151; + uint160 internal constant AFTER_DONATE_FLAG = 1 << 150; struct Permissions { bool beforeInitialize; diff --git a/test/SkipCallsTestHook.t.sol b/test/SkipCallsTestHook.t.sol index 870498422..8198ac0d2 100644 --- a/test/SkipCallsTestHook.t.sol +++ b/test/SkipCallsTestHook.t.sol @@ -28,6 +28,13 @@ contract SkipCallsTest is Test, Deployers, GasSnapshot { PoolSwapTest.TestSettings testSettings = PoolSwapTest.TestSettings({withdrawTokens: true, settleUsingTransfer: true, currencyAlreadySent: false}); + uint160 clearAllHookPermisssionsMask; + uint256 hookPermissionCount = 10; + + function setUp() public { + clearAllHookPermisssionsMask = ~uint160(0) >> hookPermissionCount; + } + function deploy(SkipCallsTestHook skipCallsTestHook) private { SkipCallsTestHook impl = new SkipCallsTestHook(); vm.etch(address(skipCallsTestHook), address(impl).code); @@ -48,16 +55,8 @@ contract SkipCallsTest is Test, Deployers, GasSnapshot { } function test_beforeInitialize_skipIfCalledByHook() public { - SkipCallsTestHook skipCallsTestHook = SkipCallsTestHook( - address( - uint160(0xFFfFfFffFFfffFFfFFfFFFFFffFFFffffFfFFFfF) - & uint160( - ~Hooks.AFTER_INITIALIZE_FLAG & ~Hooks.BEFORE_ADD_LIQUIDITY_FLAG & ~Hooks.AFTER_ADD_LIQUIDITY_FLAG - & ~Hooks.BEFORE_REMOVE_LIQUIDITY_FLAG & ~Hooks.AFTER_REMOVE_LIQUIDITY_FLAG & ~Hooks.BEFORE_SWAP_FLAG - & ~Hooks.AFTER_SWAP_FLAG & ~Hooks.BEFORE_DONATE_FLAG & ~Hooks.AFTER_DONATE_FLAG - ) - ) - ); + SkipCallsTestHook skipCallsTestHook = + SkipCallsTestHook(address(type(uint160).max & clearAllHookPermisssionsMask | Hooks.BEFORE_INITIALIZE_FLAG)); deploy(skipCallsTestHook); @@ -65,16 +64,8 @@ contract SkipCallsTest is Test, Deployers, GasSnapshot { } function test_afterInitialize_skipIfCalledByHook() public { - SkipCallsTestHook skipCallsTestHook = SkipCallsTestHook( - address( - uint160(0xFFfFfFffFFfffFFfFFfFFFFFffFFFffffFfFFFfF) - & uint160( - ~Hooks.BEFORE_INITIALIZE_FLAG & ~Hooks.BEFORE_ADD_LIQUIDITY_FLAG & ~Hooks.AFTER_ADD_LIQUIDITY_FLAG - & ~Hooks.BEFORE_REMOVE_LIQUIDITY_FLAG & ~Hooks.AFTER_REMOVE_LIQUIDITY_FLAG & ~Hooks.BEFORE_SWAP_FLAG - & ~Hooks.AFTER_SWAP_FLAG & ~Hooks.BEFORE_DONATE_FLAG & ~Hooks.AFTER_DONATE_FLAG - ) - ) - ); + SkipCallsTestHook skipCallsTestHook = + SkipCallsTestHook(address(type(uint160).max & clearAllHookPermisssionsMask | Hooks.AFTER_INITIALIZE_FLAG)); deploy(skipCallsTestHook); @@ -83,14 +74,7 @@ contract SkipCallsTest is Test, Deployers, GasSnapshot { function test_beforeAddLiquidity_skipIfCalledByHook() public { SkipCallsTestHook skipCallsTestHook = SkipCallsTestHook( - address( - uint160(0xFFfFfFffFFfffFFfFFfFFFFFffFFFffffFfFFFfF) - & uint160( - ~Hooks.BEFORE_INITIALIZE_FLAG & ~Hooks.AFTER_INITIALIZE_FLAG & ~Hooks.AFTER_ADD_LIQUIDITY_FLAG - & ~Hooks.BEFORE_REMOVE_LIQUIDITY_FLAG & ~Hooks.AFTER_REMOVE_LIQUIDITY_FLAG & ~Hooks.BEFORE_SWAP_FLAG - & ~Hooks.AFTER_SWAP_FLAG & ~Hooks.BEFORE_DONATE_FLAG & ~Hooks.AFTER_DONATE_FLAG - ) - ) + address(type(uint160).max & clearAllHookPermisssionsMask | Hooks.BEFORE_ADD_LIQUIDITY_FLAG) ); deploy(skipCallsTestHook); @@ -103,14 +87,7 @@ contract SkipCallsTest is Test, Deployers, GasSnapshot { function test_afterAddLiquidity_skipIfCalledByHook() public { SkipCallsTestHook skipCallsTestHook = SkipCallsTestHook( - address( - uint160(0xFFfFfFffFFfffFFfFFfFFFFFffFFFffffFfFFFfF) - & uint160( - ~Hooks.BEFORE_INITIALIZE_FLAG & ~Hooks.AFTER_INITIALIZE_FLAG & ~Hooks.BEFORE_ADD_LIQUIDITY_FLAG - & ~Hooks.BEFORE_REMOVE_LIQUIDITY_FLAG & ~Hooks.AFTER_REMOVE_LIQUIDITY_FLAG & ~Hooks.BEFORE_SWAP_FLAG - & ~Hooks.AFTER_SWAP_FLAG & ~Hooks.BEFORE_DONATE_FLAG & ~Hooks.AFTER_DONATE_FLAG - ) - ) + address(type(uint160).max & clearAllHookPermisssionsMask | Hooks.AFTER_ADD_LIQUIDITY_FLAG) ); deploy(skipCallsTestHook); @@ -123,14 +100,7 @@ contract SkipCallsTest is Test, Deployers, GasSnapshot { function test_beforeRemoveLiquidity_skipIfCalledByHook() public { SkipCallsTestHook skipCallsTestHook = SkipCallsTestHook( - address( - uint160(0xFFfFfFffFFfffFFfFFfFFFFFffFFFffffFfFFFfF) - & uint160( - ~Hooks.BEFORE_INITIALIZE_FLAG & ~Hooks.AFTER_INITIALIZE_FLAG & ~Hooks.BEFORE_ADD_LIQUIDITY_FLAG - & ~Hooks.AFTER_ADD_LIQUIDITY_FLAG & ~Hooks.AFTER_REMOVE_LIQUIDITY_FLAG & ~Hooks.BEFORE_SWAP_FLAG - & ~Hooks.AFTER_SWAP_FLAG & ~Hooks.BEFORE_DONATE_FLAG & ~Hooks.AFTER_DONATE_FLAG - ) - ) + address(type(uint160).max & clearAllHookPermisssionsMask | Hooks.BEFORE_REMOVE_LIQUIDITY_FLAG) ); deploy(skipCallsTestHook); @@ -145,14 +115,7 @@ contract SkipCallsTest is Test, Deployers, GasSnapshot { function test_afterRemoveLiquidity_skipIfCalledByHook() public { SkipCallsTestHook skipCallsTestHook = SkipCallsTestHook( - address( - uint160(0xFFfFfFffFFfffFFfFFfFFFFFffFFFffffFfFFFfF) - & uint160( - ~Hooks.BEFORE_INITIALIZE_FLAG & ~Hooks.AFTER_INITIALIZE_FLAG & ~Hooks.BEFORE_ADD_LIQUIDITY_FLAG - & ~Hooks.AFTER_ADD_LIQUIDITY_FLAG & ~Hooks.BEFORE_REMOVE_LIQUIDITY_FLAG & ~Hooks.BEFORE_SWAP_FLAG - & ~Hooks.AFTER_SWAP_FLAG & ~Hooks.BEFORE_DONATE_FLAG & ~Hooks.AFTER_DONATE_FLAG - ) - ) + address(type(uint160).max & clearAllHookPermisssionsMask | Hooks.AFTER_REMOVE_LIQUIDITY_FLAG) ); deploy(skipCallsTestHook); @@ -166,17 +129,8 @@ contract SkipCallsTest is Test, Deployers, GasSnapshot { } function test_beforeSwap_skipIfCalledByHook() public { - SkipCallsTestHook skipCallsTestHook = SkipCallsTestHook( - address( - uint160(0xFFfFfFffFFfffFFfFFfFFFFFffFFFffffFfFFFfF) - & uint160( - ~Hooks.BEFORE_INITIALIZE_FLAG & ~Hooks.AFTER_INITIALIZE_FLAG & ~Hooks.BEFORE_ADD_LIQUIDITY_FLAG - & ~Hooks.AFTER_ADD_LIQUIDITY_FLAG & ~Hooks.BEFORE_REMOVE_LIQUIDITY_FLAG - & ~Hooks.AFTER_REMOVE_LIQUIDITY_FLAG & ~Hooks.AFTER_SWAP_FLAG & ~Hooks.BEFORE_DONATE_FLAG - & ~Hooks.AFTER_DONATE_FLAG - ) - ) - ); + SkipCallsTestHook skipCallsTestHook = + SkipCallsTestHook(address(type(uint160).max & clearAllHookPermisssionsMask | Hooks.BEFORE_SWAP_FLAG)); deploy(skipCallsTestHook); approveAndAddLiquidity(skipCallsTestHook); @@ -188,17 +142,8 @@ contract SkipCallsTest is Test, Deployers, GasSnapshot { } function test_afterSwap_skipIfCalledByHook() public { - SkipCallsTestHook skipCallsTestHook = SkipCallsTestHook( - address( - uint160(0xFFfFfFffFFfffFFfFFfFFFFFffFFFffffFfFFFfF) - & uint160( - ~Hooks.BEFORE_INITIALIZE_FLAG & ~Hooks.AFTER_INITIALIZE_FLAG & ~Hooks.BEFORE_ADD_LIQUIDITY_FLAG - & ~Hooks.AFTER_ADD_LIQUIDITY_FLAG & ~Hooks.BEFORE_REMOVE_LIQUIDITY_FLAG - & ~Hooks.AFTER_REMOVE_LIQUIDITY_FLAG & ~Hooks.BEFORE_SWAP_FLAG & ~Hooks.BEFORE_DONATE_FLAG - & ~Hooks.AFTER_DONATE_FLAG - ) - ) - ); + SkipCallsTestHook skipCallsTestHook = + SkipCallsTestHook(address(type(uint160).max & clearAllHookPermisssionsMask | Hooks.AFTER_SWAP_FLAG)); deploy(skipCallsTestHook); approveAndAddLiquidity(skipCallsTestHook); @@ -210,17 +155,8 @@ contract SkipCallsTest is Test, Deployers, GasSnapshot { } function test_beforeDonate_skipIfCalledByHook() public { - SkipCallsTestHook skipCallsTestHook = SkipCallsTestHook( - address( - uint160(0xFFfFfFffFFfffFFfFFfFFFFFffFFFffffFfFFFfF) - & uint160( - ~Hooks.BEFORE_INITIALIZE_FLAG & ~Hooks.AFTER_INITIALIZE_FLAG & ~Hooks.BEFORE_ADD_LIQUIDITY_FLAG - & ~Hooks.AFTER_ADD_LIQUIDITY_FLAG & ~Hooks.BEFORE_REMOVE_LIQUIDITY_FLAG - & ~Hooks.AFTER_REMOVE_LIQUIDITY_FLAG & ~Hooks.BEFORE_SWAP_FLAG & ~Hooks.AFTER_SWAP_FLAG - & ~Hooks.AFTER_DONATE_FLAG - ) - ) - ); + SkipCallsTestHook skipCallsTestHook = + SkipCallsTestHook(address(type(uint160).max & clearAllHookPermisssionsMask | Hooks.BEFORE_DONATE_FLAG)); deploy(skipCallsTestHook); approveAndAddLiquidity(skipCallsTestHook); @@ -232,17 +168,8 @@ contract SkipCallsTest is Test, Deployers, GasSnapshot { } function test_afterDonate_skipIfCalledByHook() public { - SkipCallsTestHook skipCallsTestHook = SkipCallsTestHook( - address( - uint160(0xFFfFfFffFFfffFFfFFfFFFFFffFFFffffFfFFFfF) - & uint160( - ~Hooks.BEFORE_INITIALIZE_FLAG & ~Hooks.AFTER_INITIALIZE_FLAG & ~Hooks.BEFORE_ADD_LIQUIDITY_FLAG - & ~Hooks.AFTER_ADD_LIQUIDITY_FLAG & ~Hooks.BEFORE_REMOVE_LIQUIDITY_FLAG - & ~Hooks.AFTER_REMOVE_LIQUIDITY_FLAG & ~Hooks.BEFORE_SWAP_FLAG & ~Hooks.AFTER_SWAP_FLAG - & ~Hooks.BEFORE_DONATE_FLAG - ) - ) - ); + SkipCallsTestHook skipCallsTestHook = + SkipCallsTestHook(address(type(uint160).max & clearAllHookPermisssionsMask | Hooks.AFTER_DONATE_FLAG)); deploy(skipCallsTestHook); approveAndAddLiquidity(skipCallsTestHook); From 6a7251d208dbf2126a6aa969115356b0ced0a6cf Mon Sep 17 00:00:00 2001 From: Diana Kocsis Date: Fri, 5 Apr 2024 11:27:27 -0400 Subject: [PATCH 11/14] add comments and switch back to uint256 for now --- src/libraries/Hooks.sol | 20 +++++------ test/SkipCallsTestHook.t.sol | 69 ++++++++++++++++++++++++++---------- 2 files changed, 60 insertions(+), 29 deletions(-) diff --git a/src/libraries/Hooks.sol b/src/libraries/Hooks.sol index fa503fb11..6fed8bea9 100644 --- a/src/libraries/Hooks.sol +++ b/src/libraries/Hooks.sol @@ -15,16 +15,16 @@ library Hooks { using SwapFeeLibrary for uint24; using Hooks for IHooks; - uint160 internal constant BEFORE_INITIALIZE_FLAG = 1 << 159; - uint160 internal constant AFTER_INITIALIZE_FLAG = 1 << 158; - uint160 internal constant BEFORE_ADD_LIQUIDITY_FLAG = 1 << 157; - uint160 internal constant AFTER_ADD_LIQUIDITY_FLAG = 1 << 156; - uint160 internal constant BEFORE_REMOVE_LIQUIDITY_FLAG = 1 << 155; - uint160 internal constant AFTER_REMOVE_LIQUIDITY_FLAG = 1 << 154; - uint160 internal constant BEFORE_SWAP_FLAG = 1 << 153; - uint160 internal constant AFTER_SWAP_FLAG = 1 << 152; - uint160 internal constant BEFORE_DONATE_FLAG = 1 << 151; - uint160 internal constant AFTER_DONATE_FLAG = 1 << 150; + uint256 internal constant BEFORE_INITIALIZE_FLAG = 1 << 159; + uint256 internal constant AFTER_INITIALIZE_FLAG = 1 << 158; + uint256 internal constant BEFORE_ADD_LIQUIDITY_FLAG = 1 << 157; + uint256 internal constant AFTER_ADD_LIQUIDITY_FLAG = 1 << 156; + uint256 internal constant BEFORE_REMOVE_LIQUIDITY_FLAG = 1 << 155; + uint256 internal constant AFTER_REMOVE_LIQUIDITY_FLAG = 1 << 154; + uint256 internal constant BEFORE_SWAP_FLAG = 1 << 153; + uint256 internal constant AFTER_SWAP_FLAG = 1 << 152; + uint256 internal constant BEFORE_DONATE_FLAG = 1 << 151; + uint256 internal constant AFTER_DONATE_FLAG = 1 << 150; struct Permissions { bool beforeInitialize; diff --git a/test/SkipCallsTestHook.t.sol b/test/SkipCallsTestHook.t.sol index 8198ac0d2..d12609b0f 100644 --- a/test/SkipCallsTestHook.t.sol +++ b/test/SkipCallsTestHook.t.sol @@ -40,7 +40,6 @@ contract SkipCallsTest is Test, Deployers, GasSnapshot { vm.etch(address(skipCallsTestHook), address(impl).code); deployFreshManagerAndRouters(); skipCallsTestHook.setManager(IPoolManager(manager)); - (currency0, currency1) = deployMintAndApprove2Currencies(); assertEq(skipCallsTestHook.counter(), 0); @@ -55,127 +54,159 @@ contract SkipCallsTest is Test, Deployers, GasSnapshot { } function test_beforeInitialize_skipIfCalledByHook() public { - SkipCallsTestHook skipCallsTestHook = - SkipCallsTestHook(address(type(uint160).max & clearAllHookPermisssionsMask | Hooks.BEFORE_INITIALIZE_FLAG)); + SkipCallsTestHook skipCallsTestHook = SkipCallsTestHook( + address(uint160(type(uint160).max & clearAllHookPermisssionsMask | Hooks.BEFORE_INITIALIZE_FLAG)) + ); + // initializes pool and increments counter deploy(skipCallsTestHook); - assertEq(skipCallsTestHook.counter(), 1); } function test_afterInitialize_skipIfCalledByHook() public { - SkipCallsTestHook skipCallsTestHook = - SkipCallsTestHook(address(type(uint160).max & clearAllHookPermisssionsMask | Hooks.AFTER_INITIALIZE_FLAG)); + SkipCallsTestHook skipCallsTestHook = SkipCallsTestHook( + address(uint160(type(uint160).max & clearAllHookPermisssionsMask | Hooks.AFTER_INITIALIZE_FLAG)) + ); + // initializes pool and increments counter deploy(skipCallsTestHook); - assertEq(skipCallsTestHook.counter(), 1); } function test_beforeAddLiquidity_skipIfCalledByHook() public { SkipCallsTestHook skipCallsTestHook = SkipCallsTestHook( - address(type(uint160).max & clearAllHookPermisssionsMask | Hooks.BEFORE_ADD_LIQUIDITY_FLAG) + address(uint160(type(uint160).max & clearAllHookPermisssionsMask | Hooks.BEFORE_ADD_LIQUIDITY_FLAG)) ); deploy(skipCallsTestHook); + assertEq(skipCallsTestHook.counter(), 0); + // adds liquidity and increments counter approveAndAddLiquidity(skipCallsTestHook); assertEq(skipCallsTestHook.counter(), 1); + // adds liquidity again and increments counter modifyLiquidityRouter.modifyLiquidity(key, LIQ_PARAMS, abi.encode(address(this))); assertEq(skipCallsTestHook.counter(), 2); } function test_afterAddLiquidity_skipIfCalledByHook() public { SkipCallsTestHook skipCallsTestHook = SkipCallsTestHook( - address(type(uint160).max & clearAllHookPermisssionsMask | Hooks.AFTER_ADD_LIQUIDITY_FLAG) + address(uint160(type(uint160).max & clearAllHookPermisssionsMask | Hooks.AFTER_ADD_LIQUIDITY_FLAG)) ); deploy(skipCallsTestHook); + assertEq(skipCallsTestHook.counter(), 0); + // adds liquidity and increments counter approveAndAddLiquidity(skipCallsTestHook); assertEq(skipCallsTestHook.counter(), 1); + // adds liquidity and increments counter again modifyLiquidityRouter.modifyLiquidity(key, LIQ_PARAMS, abi.encode(address(this))); assertEq(skipCallsTestHook.counter(), 2); } function test_beforeRemoveLiquidity_skipIfCalledByHook() public { SkipCallsTestHook skipCallsTestHook = SkipCallsTestHook( - address(type(uint160).max & clearAllHookPermisssionsMask | Hooks.BEFORE_REMOVE_LIQUIDITY_FLAG) + address(uint160(type(uint160).max & clearAllHookPermisssionsMask | Hooks.BEFORE_REMOVE_LIQUIDITY_FLAG)) ); deploy(skipCallsTestHook); approveAndAddLiquidity(skipCallsTestHook); + assertEq(skipCallsTestHook.counter(), 0); + // removes liquidity and increments counter modifyLiquidityRouter.modifyLiquidity(key, REMOVE_LIQ_PARAMS, abi.encode(address(this))); assertEq(skipCallsTestHook.counter(), 1); + // adds liquidity again modifyLiquidityRouter.modifyLiquidity(key, LIQ_PARAMS, abi.encode(address(this))); + // removes liquidity again and increments counter modifyLiquidityRouter.modifyLiquidity(key, REMOVE_LIQ_PARAMS, abi.encode(address(this))); assertEq(skipCallsTestHook.counter(), 2); } function test_afterRemoveLiquidity_skipIfCalledByHook() public { SkipCallsTestHook skipCallsTestHook = SkipCallsTestHook( - address(type(uint160).max & clearAllHookPermisssionsMask | Hooks.AFTER_REMOVE_LIQUIDITY_FLAG) + address(uint160(type(uint160).max & clearAllHookPermisssionsMask | Hooks.AFTER_REMOVE_LIQUIDITY_FLAG)) ); deploy(skipCallsTestHook); approveAndAddLiquidity(skipCallsTestHook); + assertEq(skipCallsTestHook.counter(), 0); + // removes liquidity and increments counter modifyLiquidityRouter.modifyLiquidity(key, REMOVE_LIQ_PARAMS, abi.encode(address(this))); assertEq(skipCallsTestHook.counter(), 1); + // adds liquidity again modifyLiquidityRouter.modifyLiquidity(key, LIQ_PARAMS, abi.encode(address(this))); + // removes liquidity again and increments counter modifyLiquidityRouter.modifyLiquidity(key, REMOVE_LIQ_PARAMS, abi.encode(address(this))); assertEq(skipCallsTestHook.counter(), 2); } function test_beforeSwap_skipIfCalledByHook() public { - SkipCallsTestHook skipCallsTestHook = - SkipCallsTestHook(address(type(uint160).max & clearAllHookPermisssionsMask | Hooks.BEFORE_SWAP_FLAG)); + SkipCallsTestHook skipCallsTestHook = SkipCallsTestHook( + address(uint160(type(uint160).max & clearAllHookPermisssionsMask | Hooks.BEFORE_SWAP_FLAG)) + ); deploy(skipCallsTestHook); approveAndAddLiquidity(skipCallsTestHook); + assertEq(skipCallsTestHook.counter(), 0); + // swaps and increments counter swapRouter.swap(key, swapParams, testSettings, abi.encode(address(this))); assertEq(skipCallsTestHook.counter(), 1); + // swaps again and increments counter swapRouter.swap(key, swapParams, testSettings, abi.encode(address(this))); assertEq(skipCallsTestHook.counter(), 2); } function test_afterSwap_skipIfCalledByHook() public { - SkipCallsTestHook skipCallsTestHook = - SkipCallsTestHook(address(type(uint160).max & clearAllHookPermisssionsMask | Hooks.AFTER_SWAP_FLAG)); + SkipCallsTestHook skipCallsTestHook = SkipCallsTestHook( + address(uint160(type(uint160).max & clearAllHookPermisssionsMask | Hooks.AFTER_SWAP_FLAG)) + ); deploy(skipCallsTestHook); approveAndAddLiquidity(skipCallsTestHook); + assertEq(skipCallsTestHook.counter(), 0); + // swaps and increments counter swapRouter.swap(key, swapParams, testSettings, abi.encode(address(this))); assertEq(skipCallsTestHook.counter(), 1); + // swaps again and increments counter swapRouter.swap(key, swapParams, testSettings, abi.encode(address(this))); assertEq(skipCallsTestHook.counter(), 2); } function test_beforeDonate_skipIfCalledByHook() public { - SkipCallsTestHook skipCallsTestHook = - SkipCallsTestHook(address(type(uint160).max & clearAllHookPermisssionsMask | Hooks.BEFORE_DONATE_FLAG)); + SkipCallsTestHook skipCallsTestHook = SkipCallsTestHook( + address(uint160(type(uint160).max & clearAllHookPermisssionsMask | Hooks.BEFORE_DONATE_FLAG)) + ); deploy(skipCallsTestHook); approveAndAddLiquidity(skipCallsTestHook); + assertEq(skipCallsTestHook.counter(), 0); + // donates and increments counter donateRouter.donate(key, 100, 200, abi.encode(address(this))); assertEq(skipCallsTestHook.counter(), 1); + // donates again and increments counter donateRouter.donate(key, 100, 200, abi.encode(address(this))); assertEq(skipCallsTestHook.counter(), 2); } function test_afterDonate_skipIfCalledByHook() public { - SkipCallsTestHook skipCallsTestHook = - SkipCallsTestHook(address(type(uint160).max & clearAllHookPermisssionsMask | Hooks.AFTER_DONATE_FLAG)); + SkipCallsTestHook skipCallsTestHook = SkipCallsTestHook( + address(uint160(type(uint160).max & clearAllHookPermisssionsMask | Hooks.AFTER_DONATE_FLAG)) + ); deploy(skipCallsTestHook); approveAndAddLiquidity(skipCallsTestHook); + assertEq(skipCallsTestHook.counter(), 0); + // donates and increments counter donateRouter.donate(key, 100, 200, abi.encode(address(this))); assertEq(skipCallsTestHook.counter(), 1); + // donates again and increments counter donateRouter.donate(key, 100, 200, abi.encode(address(this))); assertEq(skipCallsTestHook.counter(), 2); } From 6db559ee32d201f412fffe732307b3979c2f0b61 Mon Sep 17 00:00:00 2001 From: Diana Kocsis Date: Fri, 5 Apr 2024 12:15:06 -0400 Subject: [PATCH 12/14] allowance does not get decremented if the sender address is the contract address --- test/ERC6909Claims.t.sol | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/test/ERC6909Claims.t.sol b/test/ERC6909Claims.t.sol index fc01cde5a..909a9ab20 100644 --- a/test/ERC6909Claims.t.sol +++ b/test/ERC6909Claims.t.sol @@ -228,7 +228,7 @@ contract ERC6909ClaimsTest is Test { vm.prank(sender); token.transfer(receiver, id, transferAmount); - if (sender == receiver) { + if (sender == receiver || sender == address(this)) { assertEq(token.balanceOf(sender, id), mintAmount); } else { assertEq(token.balanceOf(sender, id), mintAmount - transferAmount); @@ -258,7 +258,7 @@ contract ERC6909ClaimsTest is Test { assertEq(token.allowance(sender, address(this), id), mintAmount - transferAmount); } - if (sender == receiver) { + if (sender == receiver || sender == address(this)) { assertEq(token.balanceOf(sender, id), mintAmount); } else { assertEq(token.balanceOf(sender, id), mintAmount - transferAmount); @@ -284,7 +284,7 @@ contract ERC6909ClaimsTest is Test { assertEq(token.allowance(sender, address(this), id), type(uint256).max); - if (sender == receiver) { + if (sender == receiver || sender == address(this)) { assertEq(token.balanceOf(sender, id), mintAmount); } else { assertEq(token.balanceOf(sender, id), mintAmount - transferAmount); @@ -308,7 +308,7 @@ contract ERC6909ClaimsTest is Test { token.transferFrom(sender, receiver, id, transferAmount); - if (sender == receiver) { + if (sender == receiver || sender == address(this)) { assertEq(token.balanceOf(sender, id), mintAmount); } else { assertEq(token.balanceOf(sender, id), mintAmount - transferAmount); From 794104602f832e5f24bc432fb985ce7fb2f7cd0f Mon Sep 17 00:00:00 2001 From: Diana Kocsis Date: Fri, 5 Apr 2024 13:09:47 -0400 Subject: [PATCH 13/14] fix claims --- test/ERC6909Claims.t.sol | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/test/ERC6909Claims.t.sol b/test/ERC6909Claims.t.sol index 909a9ab20..a88fc41f5 100644 --- a/test/ERC6909Claims.t.sol +++ b/test/ERC6909Claims.t.sol @@ -4,6 +4,7 @@ pragma solidity ^0.8.15; import {Test} from "forge-std/Test.sol"; import {CurrencyLibrary, Currency} from "../src/types/Currency.sol"; import {MockERC6909Claims} from "../src/test/MockERC6909Claims.sol"; +import "forge-std/console.sol"; contract ERC6909ClaimsTest is Test { using CurrencyLibrary for Currency; @@ -31,7 +32,11 @@ contract ERC6909ClaimsTest is Test { if (mintAmount == type(uint256).max) { assertEq(token.allowance(sender, address(this), id), type(uint256).max); } else { - assertEq(token.allowance(sender, address(this), id), mintAmount - transferAmount); + if (sender != address(this)) { + assertEq(token.allowance(sender, address(this), id), mintAmount - transferAmount); + } else { + assertEq(token.allowance(sender, address(this), id), mintAmount); + } } assertEq(token.balanceOf(sender, id), mintAmount - transferAmount); } @@ -228,7 +233,7 @@ contract ERC6909ClaimsTest is Test { vm.prank(sender); token.transfer(receiver, id, transferAmount); - if (sender == receiver || sender == address(this)) { + if (sender == receiver) { assertEq(token.balanceOf(sender, id), mintAmount); } else { assertEq(token.balanceOf(sender, id), mintAmount - transferAmount); @@ -255,10 +260,14 @@ contract ERC6909ClaimsTest is Test { if (mintAmount == type(uint256).max) { assertEq(token.allowance(sender, address(this), id), type(uint256).max); } else { - assertEq(token.allowance(sender, address(this), id), mintAmount - transferAmount); + if (sender != address(this)) { + assertEq(token.allowance(sender, address(this), id), mintAmount - transferAmount); + } else { + assertEq(token.allowance(sender, address(this), id), mintAmount); + } } - if (sender == receiver || sender == address(this)) { + if (sender == receiver) { assertEq(token.balanceOf(sender, id), mintAmount); } else { assertEq(token.balanceOf(sender, id), mintAmount - transferAmount); @@ -284,7 +293,7 @@ contract ERC6909ClaimsTest is Test { assertEq(token.allowance(sender, address(this), id), type(uint256).max); - if (sender == receiver || sender == address(this)) { + if (sender == receiver) { assertEq(token.balanceOf(sender, id), mintAmount); } else { assertEq(token.balanceOf(sender, id), mintAmount - transferAmount); @@ -308,7 +317,7 @@ contract ERC6909ClaimsTest is Test { token.transferFrom(sender, receiver, id, transferAmount); - if (sender == receiver || sender == address(this)) { + if (sender == receiver) { assertEq(token.balanceOf(sender, id), mintAmount); } else { assertEq(token.balanceOf(sender, id), mintAmount - transferAmount); @@ -367,6 +376,7 @@ contract ERC6909ClaimsTest is Test { token.mint(sender, id, amount); + vm.assume(sender != address(this)); token.transferFrom(sender, receiver, id, amount); } } From 632c546f200364817d000b3d8bc360bd6203f1de Mon Sep 17 00:00:00 2001 From: Diana Kocsis Date: Fri, 5 Apr 2024 14:10:10 -0400 Subject: [PATCH 14/14] remove import console.sol --- test/ERC6909Claims.t.sol | 1 - 1 file changed, 1 deletion(-) diff --git a/test/ERC6909Claims.t.sol b/test/ERC6909Claims.t.sol index a88fc41f5..dbf3dc478 100644 --- a/test/ERC6909Claims.t.sol +++ b/test/ERC6909Claims.t.sol @@ -4,7 +4,6 @@ pragma solidity ^0.8.15; import {Test} from "forge-std/Test.sol"; import {CurrencyLibrary, Currency} from "../src/types/Currency.sol"; import {MockERC6909Claims} from "../src/test/MockERC6909Claims.sol"; -import "forge-std/console.sol"; contract ERC6909ClaimsTest is Test { using CurrencyLibrary for Currency;