diff --git a/.forge-snapshots/BinPoolSwapTest#testGas_exactOutputMultipleBin_WithEmptyBins.snap b/.forge-snapshots/BinPoolSwapTest#testGas_exactOutputMultipleBin_WithEmptyBins.snap new file mode 100644 index 0000000..63c4f90 --- /dev/null +++ b/.forge-snapshots/BinPoolSwapTest#testGas_exactOutputMultipleBin_WithEmptyBins.snap @@ -0,0 +1 @@ +109014 \ No newline at end of file diff --git a/.forge-snapshots/BinPoolSwapTest#test_exactInputMultipleBin.snap b/.forge-snapshots/BinPoolSwapTest#test_exactInputMultipleBin.snap new file mode 100644 index 0000000..39325ac --- /dev/null +++ b/.forge-snapshots/BinPoolSwapTest#test_exactInputMultipleBin.snap @@ -0,0 +1 @@ +156553 \ No newline at end of file diff --git a/.forge-snapshots/BinPoolSwapTest#test_exactInputSingleBin_SwapForX.snap b/.forge-snapshots/BinPoolSwapTest#test_exactInputSingleBin_SwapForX.snap new file mode 100644 index 0000000..5582f03 --- /dev/null +++ b/.forge-snapshots/BinPoolSwapTest#test_exactInputSingleBin_SwapForX.snap @@ -0,0 +1 @@ +62453 \ No newline at end of file diff --git a/.forge-snapshots/BinPoolSwapTest#test_exactInputSingleBin_SwapForY.snap b/.forge-snapshots/BinPoolSwapTest#test_exactInputSingleBin_SwapForY.snap new file mode 100644 index 0000000..e53603b --- /dev/null +++ b/.forge-snapshots/BinPoolSwapTest#test_exactInputSingleBin_SwapForY.snap @@ -0,0 +1 @@ +62422 \ No newline at end of file diff --git a/.forge-snapshots/BinPoolSwapTest#test_exactOutputMultipleBin.snap b/.forge-snapshots/BinPoolSwapTest#test_exactOutputMultipleBin.snap new file mode 100644 index 0000000..73413f1 --- /dev/null +++ b/.forge-snapshots/BinPoolSwapTest#test_exactOutputMultipleBin.snap @@ -0,0 +1 @@ +151090 \ No newline at end of file diff --git a/.forge-snapshots/BinPoolSwapTest#test_exactOutputSingleBin_SwapForX.snap b/.forge-snapshots/BinPoolSwapTest#test_exactOutputSingleBin_SwapForX.snap new file mode 100644 index 0000000..61be61b --- /dev/null +++ b/.forge-snapshots/BinPoolSwapTest#test_exactOutputSingleBin_SwapForX.snap @@ -0,0 +1 @@ +56810 \ No newline at end of file diff --git a/.forge-snapshots/BinPoolSwapTest#test_exactOutputSingleBin_SwapForY.snap b/.forge-snapshots/BinPoolSwapTest#test_exactOutputSingleBin_SwapForY.snap new file mode 100644 index 0000000..e27b20c --- /dev/null +++ b/.forge-snapshots/BinPoolSwapTest#test_exactOutputSingleBin_SwapForY.snap @@ -0,0 +1 @@ +56825 \ No newline at end of file diff --git a/test/pool-bin/libraries/BinPoolSwap.t.sol b/test/pool-bin/libraries/BinPoolSwap.t.sol index 8849d24..f40109a 100644 --- a/test/pool-bin/libraries/BinPoolSwap.t.sol +++ b/test/pool-bin/libraries/BinPoolSwap.t.sol @@ -18,8 +18,9 @@ import {BinPoolParametersHelper} from "../../../src/pool-bin/libraries/BinPoolPa import {BinTestHelper} from "../helpers/BinTestHelper.sol"; import {IProtocolFeeController} from "../../../src/interfaces/IProtocolFeeController.sol"; import {MockProtocolFeeController} from "../../../src/test/fee/MockProtocolFeeController.sol"; +import {GasSnapshot} from "forge-gas-snapshot/GasSnapshot.sol"; -contract BinPoolSwapTest is BinTestHelper { +contract BinPoolSwapTest is BinTestHelper, GasSnapshot { using PackedUint128Math for bytes32; using BinPoolParametersHelper for bytes32; using SafeCast for uint256; @@ -56,7 +57,9 @@ contract BinPoolSwapTest is BinTestHelper { poolManager.initialize(key, activeId); addLiquidityToBin(key, poolManager, bob, activeId, 1e18, 1e18, 1e18, 1e18, ""); + snapStart("BinPoolSwapTest#test_exactInputSingleBin_SwapForY"); BalanceDelta delta = poolManager.swap(key, true, -int128(1e18), ""); + snapEnd(); assertEq(delta.amount0(), -int128(1e18)); assertEq(delta.amount1(), 997000000000000000); } @@ -65,7 +68,9 @@ contract BinPoolSwapTest is BinTestHelper { poolManager.initialize(key, activeId); addLiquidityToBin(key, poolManager, bob, activeId, 1e18, 1e18, 1e18, 1e18, ""); + snapStart("BinPoolSwapTest#test_exactInputSingleBin_SwapForX"); BalanceDelta delta = poolManager.swap(key, false, -int128(1e18), ""); + snapEnd(); assertEq(delta.amount0(), 997000000000000000); assertEq(delta.amount1(), -1e18); } @@ -74,7 +79,9 @@ contract BinPoolSwapTest is BinTestHelper { poolManager.initialize(key, activeId); addLiquidityToBin(key, poolManager, bob, activeId, 1e18, 1e18, 1e18, 1e18, ""); + snapStart("BinPoolSwapTest#test_exactOutputSingleBin_SwapForY"); BalanceDelta delta = poolManager.swap(key, true, 1e18, ""); + snapEnd(); assertEq(delta.amount0(), -1003009027081243732); assertEq(delta.amount1(), 1e18); } @@ -83,7 +90,9 @@ contract BinPoolSwapTest is BinTestHelper { poolManager.initialize(key, activeId); addLiquidityToBin(key, poolManager, bob, activeId, 1e18, 1e18, 1e18, 1e18, ""); + snapStart("BinPoolSwapTest#test_exactOutputSingleBin_SwapForX"); BalanceDelta delta = poolManager.swap(key, false, 1e18, ""); + snapEnd(); assertEq(delta.amount0(), 1e18); assertEq(delta.amount1(), -1003009027081243732); } @@ -92,7 +101,9 @@ contract BinPoolSwapTest is BinTestHelper { poolManager.initialize(key, activeId); addLiquidity(key, poolManager, bob, activeId, 1e18, 1e18, 10, 10); + snapStart("BinPoolSwapTest#test_exactInputMultipleBin"); BalanceDelta delta = poolManager.swap(key, true, -1e18, ""); + snapEnd(); assertEq(delta.amount0(), -1e18); assertEq(delta.amount1(), 992555250358834498); } @@ -101,11 +112,35 @@ contract BinPoolSwapTest is BinTestHelper { poolManager.initialize(key, activeId); addLiquidity(key, poolManager, bob, activeId, 1e18, 1e18, 10, 10); + snapStart("BinPoolSwapTest#test_exactOutputMultipleBin"); BalanceDelta delta = poolManager.swap(key, true, 1e18, ""); + snapEnd(); assertEq(delta.amount0(), -1007534624899920784); assertEq(delta.amount1(), 1e18); } + /// @dev Attempt to swap with scenario that a bin has 0 liquidity (add/remove liqudiity) + /// however the bin might still be in TreeMath due to min share locked up + function testGas_exactOutputMultipleBin_WithEmptyBins() public { + poolManager.initialize(key, activeId); + // add liquidity to 10 bins + addLiquidity(key, poolManager, bob, activeId, 2e18, 2e18, 10, 10); + uint256 bobBal; + + /// remove 3 bin of liquidity from left and right + for (uint24 i = 1; i < 4; i++) { + bobBal = poolManager.getPosition(key.toId(), bob, activeId + i, 0).share; + removeLiquidityFromBin(key, poolManager, bob, activeId + i, bobBal, ""); + + bobBal = poolManager.getPosition(key.toId(), bob, activeId - i, 0).share; + removeLiquidityFromBin(key, poolManager, bob, activeId - i, bobBal, ""); + } + + snapStart("BinPoolSwapTest#testGas_exactOutputMultipleBin_WithEmptyBins"); + poolManager.swap(key, true, 1e18, ""); + snapEnd(); + } + function test_SwapWithProtocolFee_ExactIn_SwapForY() public { // Pre-req: set protocol fee at 0.1% for token0 and 0.05% for token1 MockProtocolFeeController feeController = new MockProtocolFeeController(); @@ -151,7 +186,7 @@ contract BinPoolSwapTest is BinTestHelper { assertEq(delta.amount0(), 996501000000000000); assertEq(delta.amount1(), -1e18); - // // after swap, verify 0.05% fee + // after swap, verify 0.05% fee assertEq(poolManager.protocolFeesAccrued(key.currency0), 0); assertEq(poolManager.protocolFeesAccrued(key.currency1), 0.0005 * 1e18); }