diff --git a/test/libraries/Pool.t.sol b/test/libraries/Pool.t.sol index e93e9f1df..ad54c9a76 100644 --- a/test/libraries/Pool.t.sol +++ b/test/libraries/Pool.t.sol @@ -170,6 +170,22 @@ contract PoolTest is Test { } } + function test_swap_exactInputZeroForOneAccruesOnlyToken0Fees() public { + _assertSwapFeeGrowthDirection(true, -1 ether); + } + + function test_swap_exactOutputZeroForOneAccruesOnlyToken0Fees() public { + _assertSwapFeeGrowthDirection(true, 1 ether); + } + + function test_swap_exactInputOneForZeroAccruesOnlyToken1Fees() public { + _assertSwapFeeGrowthDirection(false, -1 ether); + } + + function test_swap_exactOutputOneForZeroAccruesOnlyToken1Fees() public { + _assertSwapFeeGrowthDirection(false, 1 ether); + } + function test_fuzz_tickSpacingToMaxLiquidityPerTick(int24 tickSpacing) public pure { tickSpacing = int24(bound(tickSpacing, TickMath.MIN_TICK_SPACING, TickMath.MAX_TICK_SPACING)); // v3 math @@ -179,4 +195,40 @@ contract PoolTest is Test { // assert that the result is the same as the v3 math or lower assertGe(type(uint128).max / numTicks, Pool.tickSpacingToMaxLiquidityPerTick(tickSpacing)); } + + function _assertSwapFeeGrowthDirection(bool zeroForOne, int256 amountSpecified) internal { + _initializeWithLiquidity(); + + state.swap( + Pool.SwapParams({ + amountSpecified: amountSpecified, + tickSpacing: 60, + zeroForOne: zeroForOne, + sqrtPriceLimitX96: zeroForOne ? Constants.SQRT_PRICE_1_2 : Constants.SQRT_PRICE_2_1, + lpFeeOverride: 0 + }) + ); + + if (zeroForOne) { + assertGt(state.feeGrowthGlobal0X128, 0); + assertEq(state.feeGrowthGlobal1X128, 0); + } else { + assertEq(state.feeGrowthGlobal0X128, 0); + assertGt(state.feeGrowthGlobal1X128, 0); + } + } + + function _initializeWithLiquidity() internal { + state.initialize(Constants.SQRT_PRICE_1_1, 3000); + state.modifyLiquidity( + Pool.ModifyLiquidityParams({ + owner: address(this), + tickLower: -120, + tickUpper: 120, + liquidityDelta: 10_000 ether, + tickSpacing: 60, + salt: 0 + }) + ); + } }