diff --git a/.forge-snapshots/BinPoolSwapTest#test_exactInputSingleBin_SwapForX.snap b/.forge-snapshots/BinPoolSwapTest#test_exactInputSingleBin_SwapForX.snap index 08fa717e..a1399c20 100644 --- a/.forge-snapshots/BinPoolSwapTest#test_exactInputSingleBin_SwapForX.snap +++ b/.forge-snapshots/BinPoolSwapTest#test_exactInputSingleBin_SwapForX.snap @@ -1 +1 @@ -63109 \ No newline at end of file +63178 \ No newline at end of file diff --git a/.forge-snapshots/BinPoolSwapTest#test_exactInputSingleBin_SwapForY.snap b/.forge-snapshots/BinPoolSwapTest#test_exactInputSingleBin_SwapForY.snap index ae3b9b1b..a2b6ed1d 100644 --- a/.forge-snapshots/BinPoolSwapTest#test_exactInputSingleBin_SwapForY.snap +++ b/.forge-snapshots/BinPoolSwapTest#test_exactInputSingleBin_SwapForY.snap @@ -1 +1 @@ -63078 \ No newline at end of file +63147 \ No newline at end of file diff --git a/.forge-snapshots/BinPoolSwapTest#test_exactOutputSingleBin_SwapForX.snap b/.forge-snapshots/BinPoolSwapTest#test_exactOutputSingleBin_SwapForX.snap index 7411cb30..e5b3213f 100644 --- a/.forge-snapshots/BinPoolSwapTest#test_exactOutputSingleBin_SwapForX.snap +++ b/.forge-snapshots/BinPoolSwapTest#test_exactOutputSingleBin_SwapForX.snap @@ -1 +1 @@ -57403 \ No newline at end of file +57469 \ No newline at end of file diff --git a/.forge-snapshots/CLPoolManagerTest#swap_runOutOfLiquidity.snap b/.forge-snapshots/CLPoolManagerTest#swap_runOutOfLiquidity.snap index f6f255f4..7e778e33 100644 --- a/.forge-snapshots/CLPoolManagerTest#swap_runOutOfLiquidity.snap +++ b/.forge-snapshots/CLPoolManagerTest#swap_runOutOfLiquidity.snap @@ -1 +1 @@ -148676 \ No newline at end of file +148674 \ No newline at end of file diff --git a/.github/workflows/coverage.yml b/.github/workflows/coverage.yml index 8fdf9af4..b1049428 100644 --- a/.github/workflows/coverage.yml +++ b/.github/workflows/coverage.yml @@ -15,7 +15,7 @@ jobs: - name: Install Foundry uses: foundry-rs/foundry-toolchain@v1 with: - version: nightly + version: stable # install dependency - uses: actions/setup-node@v3 diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index 5b0a7d1b..8f22de38 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -27,7 +27,7 @@ jobs: - name: Install Foundry uses: foundry-rs/foundry-toolchain@v1 with: - version: nightly + version: stable - name: Compile run: yarn prettier-check diff --git a/lib/forge-std b/lib/forge-std index 52715a21..726a6ee5 160000 --- a/lib/forge-std +++ b/lib/forge-std @@ -1 +1 @@ -Subproject commit 52715a217dc51d0de15877878ab8213f6cbbbab5 +Subproject commit 726a6ee5fc8427a0013d6f624e486c9130c0e336 diff --git a/snapshots/BinPoolManagerTest.json b/snapshots/BinPoolManagerTest.json new file mode 100644 index 00000000..df31df1e --- /dev/null +++ b/snapshots/BinPoolManagerTest.json @@ -0,0 +1,3 @@ +{ + "binPoolManager initcode hash (without constructor params, as uint256)": "73425840329377707764016122574450195738786283045901954729586336840188059167782" +} \ No newline at end of file diff --git a/snapshots/CLPoolManagerTest.json b/snapshots/CLPoolManagerTest.json new file mode 100644 index 00000000..2ae2f814 --- /dev/null +++ b/snapshots/CLPoolManagerTest.json @@ -0,0 +1,3 @@ +{ + "clPoolManager initcode hash (without constructor params, as uint256)": "43498189724800683414039944409888665118981458752163755806370462274516389565331" +} \ No newline at end of file diff --git a/snapshots/VaultTest.json b/snapshots/VaultTest.json new file mode 100644 index 00000000..e21c1dfb --- /dev/null +++ b/snapshots/VaultTest.json @@ -0,0 +1,3 @@ +{ + "Vault initcode hash (without constructor params, as uint256)": "42285739453326546745334574088065442781095713906976306156700703402717362931041" +} \ No newline at end of file diff --git a/src/pool-cl/interfaces/ICLPoolManager.sol b/src/pool-cl/interfaces/ICLPoolManager.sol index 055d6bef..0505caa9 100644 --- a/src/pool-cl/interfaces/ICLPoolManager.sol +++ b/src/pool-cl/interfaces/ICLPoolManager.sol @@ -108,6 +108,11 @@ interface ICLPoolManager is IProtocolFees, IPoolManager, IExtsload { function getPoolBitmapInfo(PoolId id, int16 word) external view returns (uint256 tickBitmap); /// @notice Get the fee growth global for the given pool + /// @return feeGrowthGlobal0x128 The global fee growth for token0 + /// @return feeGrowthGlobal1x128 The global fee growth for token1 + /// @dev feeGrowthGlobal can be artificially inflated by a malicious actor and integrators should be careful using the value + /// For pools with a single liquidity position, actors can donate to themselves to freely inflate feeGrowthGlobal + /// atomically donating and collecting fees in the same lockAcquired callback may make the inflated value more extreme function getFeeGrowthGlobals(PoolId id) external view @@ -135,6 +140,9 @@ interface ICLPoolManager is IProtocolFees, IPoolManager, IExtsload { /// @notice Modify the position for the given pool /// @return delta The total balance delta of the caller of modifyLiquidity. /// @return feeDelta The balance delta of the fees generated in the liquidity range. + /// @dev feeDelta can be artificially inflated by a malicious actor and integrators should be careful using the value + /// For pools with a single liquidity position, actors can donate to themselves to inflate feeGrowthGlobal (and consequently feeDelta) + /// atomically donating and collecting fees in the same lockAcquired callback may make the inflated value more extreme function modifyLiquidity(PoolKey memory key, ModifyLiquidityParams memory params, bytes calldata hookData) external returns (BalanceDelta delta, BalanceDelta feeDelta); diff --git a/src/pool-cl/libraries/CLPool.sol b/src/pool-cl/libraries/CLPool.sol index 29e71d0f..73a4bd89 100644 --- a/src/pool-cl/libraries/CLPool.sol +++ b/src/pool-cl/libraries/CLPool.sol @@ -48,6 +48,10 @@ library CLPool { /// @notice Thrown by donate if there is currently 0 liquidity, since the fees will not go to any liquidity providers error NoLiquidityToReceiveFees(); + /// @notice The state of a pool + /// @dev feeGrowthGlobal can be artificially inflated + /// For pools with a single liquidity position, actors can donate to themselves to freely inflate feeGrowthGlobal + /// atomically donating and collecting fees in the same lockAcquired callback may make the inflated value more extreme struct State { CLSlot0 slot0; /// @dev accumulated lp fees diff --git a/test/pool-bin/BinPoolManager.t.sol b/test/pool-bin/BinPoolManager.t.sol index 48897b46..423aaec5 100644 --- a/test/pool-bin/BinPoolManager.t.sol +++ b/test/pool-bin/BinPoolManager.t.sol @@ -120,6 +120,13 @@ contract BinPoolManagerTest is Test, GasSnapshot, BinTestHelper { } } + function test_initcodeHash() public { + vm.snapshotValue( + "binPoolManager initcode hash (without constructor params, as uint256)", + uint256(keccak256(type(BinPoolManager).creationCode)) + ); + } + function testInitialize_gasCheck_withoutHooks() public { snapStart("BinPoolManagerTest#testInitialize_gasCheck_withoutHooks"); poolManager.initialize(key, activeId); diff --git a/test/pool-cl/CLPoolManager.t.sol b/test/pool-cl/CLPoolManager.t.sol index 7c3b856a..27f4b04a 100644 --- a/test/pool-cl/CLPoolManager.t.sol +++ b/test/pool-cl/CLPoolManager.t.sol @@ -82,6 +82,13 @@ contract CLPoolManagerTest is Test, NoIsolate, Deployers, TokenFixture, GasSnaps } } + function test_initcodeHash() public { + vm.snapshotValue( + "clPoolManager initcode hash (without constructor params, as uint256)", + uint256(keccak256(type(CLPoolManager).creationCode)) + ); + } + // ************** *************** // // ************** initialize *************** // // ************** *************** // @@ -1811,9 +1818,6 @@ contract CLPoolManagerTest is Test, NoIsolate, Deployers, TokenFixture, GasSnaps "" ); snapEnd(); - - console2.log("token0 balance: ", IERC20(Currency.unwrap(currency0)).balanceOf(address(vault))); - console2.log("token1 balance: ", IERC20(Currency.unwrap(currency1)).balanceOf(address(vault))); } function testSwap_failsIfNotInitialized(uint160 sqrtPriceX96) public { diff --git a/test/vault/Vault.t.sol b/test/vault/Vault.t.sol index ee6f9592..01ca1ac5 100644 --- a/test/vault/Vault.t.sol +++ b/test/vault/Vault.t.sol @@ -88,6 +88,12 @@ contract VaultTest is Test, NoIsolate, GasSnapshot, TokenFixture { } } + function test_initcodeHash() public { + vm.snapshotValue( + "Vault initcode hash (without constructor params, as uint256)", uint256(keccak256(type(Vault).creationCode)) + ); + } + function testRegisterPoolManager() public { assertEq(vault.isAppRegistered(address(unRegPoolManager)), false); assertEq(vault.isAppRegistered(address(poolManager1)), true);