From a761527c6d9431ef8a6f648713c34c7da73574e0 Mon Sep 17 00:00:00 2001 From: ChefMist <133624774+ChefMist@users.noreply.github.com> Date: Mon, 11 Nov 2024 19:45:11 +0800 Subject: [PATCH 1/7] feat: example of option 1 --- .../BinHookTest#testBurnSucceedsWithHook.snap | 2 +- .forge-snapshots/BinMintBurnFeeHookTest#test_Burn.snap | 2 +- .forge-snapshots/BinPoolManagerBytecodeSize.snap | 2 +- .../BinPoolManagerTest#testBurnNativeCurrency.snap | 2 +- .../BinPoolManagerTest#testGasBurnHalfBin.snap | 2 +- .../BinPoolManagerTest#testGasBurnNineBins.snap | 2 +- .../BinPoolManagerTest#testGasBurnOneBin.snap | 2 +- .../CLCustomCurveHookTest#test_Swap_CustomCurve.snap | 2 +- src/pool-bin/libraries/BinPool.sol | 9 +++++++++ test/pool-bin/libraries/BinPoolDonate.t.sol | 5 +++-- 10 files changed, 20 insertions(+), 10 deletions(-) diff --git a/.forge-snapshots/BinHookTest#testBurnSucceedsWithHook.snap b/.forge-snapshots/BinHookTest#testBurnSucceedsWithHook.snap index 436357a4..a7b4c575 100644 --- a/.forge-snapshots/BinHookTest#testBurnSucceedsWithHook.snap +++ b/.forge-snapshots/BinHookTest#testBurnSucceedsWithHook.snap @@ -1 +1 @@ -178130 \ No newline at end of file +178365 \ No newline at end of file diff --git a/.forge-snapshots/BinMintBurnFeeHookTest#test_Burn.snap b/.forge-snapshots/BinMintBurnFeeHookTest#test_Burn.snap index d6fd559c..7dac5b01 100644 --- a/.forge-snapshots/BinMintBurnFeeHookTest#test_Burn.snap +++ b/.forge-snapshots/BinMintBurnFeeHookTest#test_Burn.snap @@ -1 +1 @@ -170145 \ No newline at end of file +170380 \ No newline at end of file diff --git a/.forge-snapshots/BinPoolManagerBytecodeSize.snap b/.forge-snapshots/BinPoolManagerBytecodeSize.snap index c0501746..04b4c431 100644 --- a/.forge-snapshots/BinPoolManagerBytecodeSize.snap +++ b/.forge-snapshots/BinPoolManagerBytecodeSize.snap @@ -1 +1 @@ -23287 \ No newline at end of file +23381 \ No newline at end of file diff --git a/.forge-snapshots/BinPoolManagerTest#testBurnNativeCurrency.snap b/.forge-snapshots/BinPoolManagerTest#testBurnNativeCurrency.snap index 02574599..fb2b3ed2 100644 --- a/.forge-snapshots/BinPoolManagerTest#testBurnNativeCurrency.snap +++ b/.forge-snapshots/BinPoolManagerTest#testBurnNativeCurrency.snap @@ -1 +1 @@ -133892 \ No newline at end of file +134080 \ No newline at end of file diff --git a/.forge-snapshots/BinPoolManagerTest#testGasBurnHalfBin.snap b/.forge-snapshots/BinPoolManagerTest#testGasBurnHalfBin.snap index f53d2c9a..577498a2 100644 --- a/.forge-snapshots/BinPoolManagerTest#testGasBurnHalfBin.snap +++ b/.forge-snapshots/BinPoolManagerTest#testGasBurnHalfBin.snap @@ -1 +1 @@ -142717 \ No newline at end of file +142975 \ No newline at end of file diff --git a/.forge-snapshots/BinPoolManagerTest#testGasBurnNineBins.snap b/.forge-snapshots/BinPoolManagerTest#testGasBurnNineBins.snap index 994141b9..de776045 100644 --- a/.forge-snapshots/BinPoolManagerTest#testGasBurnNineBins.snap +++ b/.forge-snapshots/BinPoolManagerTest#testGasBurnNineBins.snap @@ -1 +1 @@ -289683 \ No newline at end of file +291375 \ No newline at end of file diff --git a/.forge-snapshots/BinPoolManagerTest#testGasBurnOneBin.snap b/.forge-snapshots/BinPoolManagerTest#testGasBurnOneBin.snap index ba16a41b..a27b2952 100644 --- a/.forge-snapshots/BinPoolManagerTest#testGasBurnOneBin.snap +++ b/.forge-snapshots/BinPoolManagerTest#testGasBurnOneBin.snap @@ -1 +1 @@ -127065 \ No newline at end of file +127253 \ No newline at end of file diff --git a/.forge-snapshots/CLCustomCurveHookTest#test_Swap_CustomCurve.snap b/.forge-snapshots/CLCustomCurveHookTest#test_Swap_CustomCurve.snap index 0f4357bb..7e28f305 100644 --- a/.forge-snapshots/CLCustomCurveHookTest#test_Swap_CustomCurve.snap +++ b/.forge-snapshots/CLCustomCurveHookTest#test_Swap_CustomCurve.snap @@ -1 +1 @@ -149710 \ No newline at end of file +149698 \ No newline at end of file diff --git a/src/pool-bin/libraries/BinPool.sol b/src/pool-bin/libraries/BinPool.sol index 8fb77084..64a08a04 100644 --- a/src/pool-bin/libraries/BinPool.sol +++ b/src/pool-bin/libraries/BinPool.sol @@ -48,6 +48,7 @@ library BinPool { error BinPool__NoLiquidityToReceiveFees(); /// @dev if swap exactIn, x for y, unspecifiedToken = token y. if swap x for exact out y, unspecified token is x error BinPool__InsufficientAmountUnSpecified(); + error BinPool__BelowMinimumShareInBurn(uint256 balanceShare); /// @dev The state of a pool struct State { @@ -66,6 +67,9 @@ library BinPool { mapping(bytes32 => bytes32) level2; } + /// @dev when liquidity is removed, ensure there is either greater than min_share or 0 liquidity left + uint256 constant MINIMUM_SHARE = 1e3; + function initialize(State storage self, uint24 activeId, uint24 protocolFee, uint24 lpFee) internal { /// An initialized pool will not have activeId: 0 if (self.slot0.activeId() != 0) revert PoolAlreadyInitialized(); @@ -464,6 +468,11 @@ library BinPool { function _subShare(State storage self, address owner, uint24 binId, bytes32 salt, uint256 shares) internal { self.positions.get(owner, binId, salt).subShare(shares); self.shareOfBin[binId] -= shares; + + uint256 balanceShare = self.shareOfBin[binId]; + if (balanceShare > 0 && balanceShare < MINIMUM_SHARE) { + revert BinPool__BelowMinimumShareInBurn(balanceShare); + } } /// @notice Add share to user's position and update total share supply of bin diff --git a/test/pool-bin/libraries/BinPoolDonate.t.sol b/test/pool-bin/libraries/BinPoolDonate.t.sol index 9efc1ddf..520cd1f1 100644 --- a/test/pool-bin/libraries/BinPoolDonate.t.sol +++ b/test/pool-bin/libraries/BinPoolDonate.t.sol @@ -61,8 +61,9 @@ contract BinPoolDonateTest is BinTestHelper { poolManager.initialize(key, activeId); addLiquidityToBin(key, poolManager, alice, activeId, 1e18, 1e18, 1e18, 1e18, ""); - // Remove all share leaving less than MIN_LIQUIDITY_BEFORE_DONATE shares - remainingShare = bound(remainingShare, 1, poolManager.minBinShareForDonate() - 1); + /// @dev Remove all share leaving between 1e3 and minShareForDinate + /// if its less than 1e3, it will throw BinPool__BelowMinimumShareInBurn error + remainingShare = bound(remainingShare, 1e3, poolManager.minBinShareForDonate() - 1); uint256 aliceShare = poolManager.getPosition(poolId, alice, activeId, 0).share; removeLiquidityFromBin(key, poolManager, alice, activeId, aliceShare - remainingShare, ""); From 8f2cddad0ec60f08f32be2a2bfea82989a050da2 Mon Sep 17 00:00:00 2001 From: ChefMist <133624774+ChefMist@users.noreply.github.com> Date: Mon, 11 Nov 2024 19:52:16 +0800 Subject: [PATCH 2/7] feat: add comment --- .../CLCustomCurveHookTest#test_Swap_CustomCurve.snap | 2 +- src/pool-bin/libraries/BinPool.sol | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/.forge-snapshots/CLCustomCurveHookTest#test_Swap_CustomCurve.snap b/.forge-snapshots/CLCustomCurveHookTest#test_Swap_CustomCurve.snap index 7e28f305..0f4357bb 100644 --- a/.forge-snapshots/CLCustomCurveHookTest#test_Swap_CustomCurve.snap +++ b/.forge-snapshots/CLCustomCurveHookTest#test_Swap_CustomCurve.snap @@ -1 +1 @@ -149698 \ No newline at end of file +149710 \ No newline at end of file diff --git a/src/pool-bin/libraries/BinPool.sol b/src/pool-bin/libraries/BinPool.sol index 64a08a04..d2ade53e 100644 --- a/src/pool-bin/libraries/BinPool.sol +++ b/src/pool-bin/libraries/BinPool.sol @@ -470,6 +470,7 @@ library BinPool { self.shareOfBin[binId] -= shares; uint256 balanceShare = self.shareOfBin[binId]; + /// @dev Ensure bin total share is either 0 or greater than minimum share if (balanceShare > 0 && balanceShare < MINIMUM_SHARE) { revert BinPool__BelowMinimumShareInBurn(balanceShare); } From aa9ae7773f157a36bec4b3989e86f2afe0c33d18 Mon Sep 17 00:00:00 2001 From: ChefMist <133624774+ChefMist@users.noreply.github.com> Date: Tue, 12 Nov 2024 09:29:12 +0800 Subject: [PATCH 3/7] feat: add guard in _addShare (to discuss) --- .../BinHookTest#testMintSucceedsWithHook.snap | 2 +- .../BinMintBurnFeeHookTest#test_Mint.snap | 2 +- .forge-snapshots/BinPoolManagerBytecodeSize.snap | 2 +- .../BinPoolManagerTest#testGasMintNneBins-1.snap | 2 +- .../BinPoolManagerTest#testGasMintNneBins-2.snap | 2 +- .../BinPoolManagerTest#testGasMintOneBin-1.snap | 2 +- .../BinPoolManagerTest#testGasMintOneBin-2.snap | 2 +- ...inPoolManagerTest#testMintNativeCurrency.snap | 2 +- src/pool-bin/libraries/BinPool.sol | 16 ++++++++++++---- test/pool-bin/libraries/BinPoolDonate.t.sol | 6 +++--- 10 files changed, 23 insertions(+), 15 deletions(-) diff --git a/.forge-snapshots/BinHookTest#testMintSucceedsWithHook.snap b/.forge-snapshots/BinHookTest#testMintSucceedsWithHook.snap index 607b6b5d..d13c4991 100644 --- a/.forge-snapshots/BinHookTest#testMintSucceedsWithHook.snap +++ b/.forge-snapshots/BinHookTest#testMintSucceedsWithHook.snap @@ -1 +1 @@ -311254 \ No newline at end of file +311512 \ No newline at end of file diff --git a/.forge-snapshots/BinMintBurnFeeHookTest#test_Mint.snap b/.forge-snapshots/BinMintBurnFeeHookTest#test_Mint.snap index 4128ba06..043cb3e3 100644 --- a/.forge-snapshots/BinMintBurnFeeHookTest#test_Mint.snap +++ b/.forge-snapshots/BinMintBurnFeeHookTest#test_Mint.snap @@ -1 +1 @@ -410336 \ No newline at end of file +410594 \ No newline at end of file diff --git a/.forge-snapshots/BinPoolManagerBytecodeSize.snap b/.forge-snapshots/BinPoolManagerBytecodeSize.snap index 04b4c431..0aaf9fad 100644 --- a/.forge-snapshots/BinPoolManagerBytecodeSize.snap +++ b/.forge-snapshots/BinPoolManagerBytecodeSize.snap @@ -1 +1 @@ -23381 \ No newline at end of file +23406 \ No newline at end of file diff --git a/.forge-snapshots/BinPoolManagerTest#testGasMintNneBins-1.snap b/.forge-snapshots/BinPoolManagerTest#testGasMintNneBins-1.snap index dc44a72f..1b9ec102 100644 --- a/.forge-snapshots/BinPoolManagerTest#testGasMintNneBins-1.snap +++ b/.forge-snapshots/BinPoolManagerTest#testGasMintNneBins-1.snap @@ -1 +1 @@ -968475 \ No newline at end of file +970797 \ No newline at end of file diff --git a/.forge-snapshots/BinPoolManagerTest#testGasMintNneBins-2.snap b/.forge-snapshots/BinPoolManagerTest#testGasMintNneBins-2.snap index 4a863ea0..7633e951 100644 --- a/.forge-snapshots/BinPoolManagerTest#testGasMintNneBins-2.snap +++ b/.forge-snapshots/BinPoolManagerTest#testGasMintNneBins-2.snap @@ -1 +1 @@ -327787 \ No newline at end of file +330109 \ No newline at end of file diff --git a/.forge-snapshots/BinPoolManagerTest#testGasMintOneBin-1.snap b/.forge-snapshots/BinPoolManagerTest#testGasMintOneBin-1.snap index f71e10bd..ab8d17c1 100644 --- a/.forge-snapshots/BinPoolManagerTest#testGasMintOneBin-1.snap +++ b/.forge-snapshots/BinPoolManagerTest#testGasMintOneBin-1.snap @@ -1 +1 @@ -337511 \ No newline at end of file +337769 \ No newline at end of file diff --git a/.forge-snapshots/BinPoolManagerTest#testGasMintOneBin-2.snap b/.forge-snapshots/BinPoolManagerTest#testGasMintOneBin-2.snap index 140b1ddb..cf9fd88d 100644 --- a/.forge-snapshots/BinPoolManagerTest#testGasMintOneBin-2.snap +++ b/.forge-snapshots/BinPoolManagerTest#testGasMintOneBin-2.snap @@ -1 +1 @@ -140062 \ No newline at end of file +140320 \ No newline at end of file diff --git a/.forge-snapshots/BinPoolManagerTest#testMintNativeCurrency.snap b/.forge-snapshots/BinPoolManagerTest#testMintNativeCurrency.snap index f9388fc0..673fb816 100644 --- a/.forge-snapshots/BinPoolManagerTest#testMintNativeCurrency.snap +++ b/.forge-snapshots/BinPoolManagerTest#testMintNativeCurrency.snap @@ -1 +1 @@ -304550 \ No newline at end of file +304808 \ No newline at end of file diff --git a/src/pool-bin/libraries/BinPool.sol b/src/pool-bin/libraries/BinPool.sol index d2ade53e..5fc6949b 100644 --- a/src/pool-bin/libraries/BinPool.sol +++ b/src/pool-bin/libraries/BinPool.sol @@ -48,7 +48,7 @@ library BinPool { error BinPool__NoLiquidityToReceiveFees(); /// @dev if swap exactIn, x for y, unspecifiedToken = token y. if swap x for exact out y, unspecified token is x error BinPool__InsufficientAmountUnSpecified(); - error BinPool__BelowMinimumShareInBurn(uint256 balanceShare); + error BinPool__BelowMinimumShare(uint256 balanceShare); /// @dev The state of a pool struct State { @@ -68,7 +68,7 @@ library BinPool { } /// @dev when liquidity is removed, ensure there is either greater than min_share or 0 liquidity left - uint256 constant MINIMUM_SHARE = 1e3; + uint256 constant MINIMUM_SHARE = 1e9; function initialize(State storage self, uint24 activeId, uint24 protocolFee, uint24 lpFee) internal { /// An initialized pool will not have activeId: 0 @@ -469,10 +469,10 @@ library BinPool { self.positions.get(owner, binId, salt).subShare(shares); self.shareOfBin[binId] -= shares; - uint256 balanceShare = self.shareOfBin[binId]; /// @dev Ensure bin total share is either 0 or greater than minimum share + uint256 balanceShare = self.shareOfBin[binId]; if (balanceShare > 0 && balanceShare < MINIMUM_SHARE) { - revert BinPool__BelowMinimumShareInBurn(balanceShare); + revert BinPool__BelowMinimumShare(balanceShare); } } @@ -480,6 +480,14 @@ library BinPool { function _addShare(State storage self, address owner, uint24 binId, bytes32 salt, uint256 shares) internal { self.positions.get(owner, binId, salt).addShare(shares); self.shareOfBin[binId] += shares; + + /// @dev Ensure bin total share is either 0 or greater than minimum share + /// to discuss if we want to enforce this -- otherwise user can potentially add below 1e9 liquidity + /// but can't withdraw if there's no other lp to help push the min share up + uint256 balanceShare = self.shareOfBin[binId]; + if (balanceShare > 0 && balanceShare < MINIMUM_SHARE) { + revert BinPool__BelowMinimumShare(balanceShare); + } } /// @notice Enable bin id for a pool diff --git a/test/pool-bin/libraries/BinPoolDonate.t.sol b/test/pool-bin/libraries/BinPoolDonate.t.sol index 520cd1f1..667a9b81 100644 --- a/test/pool-bin/libraries/BinPoolDonate.t.sol +++ b/test/pool-bin/libraries/BinPoolDonate.t.sol @@ -61,9 +61,9 @@ contract BinPoolDonateTest is BinTestHelper { poolManager.initialize(key, activeId); addLiquidityToBin(key, poolManager, alice, activeId, 1e18, 1e18, 1e18, 1e18, ""); - /// @dev Remove all share leaving between 1e3 and minShareForDinate - /// if its less than 1e3, it will throw BinPool__BelowMinimumShareInBurn error - remainingShare = bound(remainingShare, 1e3, poolManager.minBinShareForDonate() - 1); + /// @dev Remove all share leaving between 1e9 and minShareForDinate + /// if its less than 1e9, it will throw BinPool__BelowMinimumShareInBurn error + remainingShare = bound(remainingShare, 1e9, poolManager.minBinShareForDonate() - 1); uint256 aliceShare = poolManager.getPosition(poolId, alice, activeId, 0).share; removeLiquidityFromBin(key, poolManager, alice, activeId, aliceShare - remainingShare, ""); From 87906eab43b7a289fe9d65df321d507162722a10 Mon Sep 17 00:00:00 2001 From: ChefMist <133624774+ChefMist@users.noreply.github.com> Date: Tue, 12 Nov 2024 09:32:50 +0800 Subject: [PATCH 4/7] feat: optimise add_share --- .forge-snapshots/BinHookTest#testMintSucceedsWithHook.snap | 2 +- .forge-snapshots/BinMintBurnFeeHookTest#test_Mint.snap | 2 +- .forge-snapshots/BinPoolManagerBytecodeSize.snap | 2 +- .forge-snapshots/BinPoolManagerTest#testGasMintNneBins-1.snap | 2 +- .forge-snapshots/BinPoolManagerTest#testGasMintNneBins-2.snap | 2 +- .forge-snapshots/BinPoolManagerTest#testGasMintOneBin-1.snap | 2 +- .forge-snapshots/BinPoolManagerTest#testGasMintOneBin-2.snap | 2 +- .forge-snapshots/BinPoolManagerTest#testMintNativeCurrency.snap | 2 +- src/pool-bin/libraries/BinPool.sol | 2 +- 9 files changed, 9 insertions(+), 9 deletions(-) diff --git a/.forge-snapshots/BinHookTest#testMintSucceedsWithHook.snap b/.forge-snapshots/BinHookTest#testMintSucceedsWithHook.snap index d13c4991..e3356bf8 100644 --- a/.forge-snapshots/BinHookTest#testMintSucceedsWithHook.snap +++ b/.forge-snapshots/BinHookTest#testMintSucceedsWithHook.snap @@ -1 +1 @@ -311512 \ No newline at end of file +311472 \ No newline at end of file diff --git a/.forge-snapshots/BinMintBurnFeeHookTest#test_Mint.snap b/.forge-snapshots/BinMintBurnFeeHookTest#test_Mint.snap index 043cb3e3..5a6422d6 100644 --- a/.forge-snapshots/BinMintBurnFeeHookTest#test_Mint.snap +++ b/.forge-snapshots/BinMintBurnFeeHookTest#test_Mint.snap @@ -1 +1 @@ -410594 \ No newline at end of file +410554 \ No newline at end of file diff --git a/.forge-snapshots/BinPoolManagerBytecodeSize.snap b/.forge-snapshots/BinPoolManagerBytecodeSize.snap index 0aaf9fad..3eceacdc 100644 --- a/.forge-snapshots/BinPoolManagerBytecodeSize.snap +++ b/.forge-snapshots/BinPoolManagerBytecodeSize.snap @@ -1 +1 @@ -23406 \ No newline at end of file +23421 \ No newline at end of file diff --git a/.forge-snapshots/BinPoolManagerTest#testGasMintNneBins-1.snap b/.forge-snapshots/BinPoolManagerTest#testGasMintNneBins-1.snap index 1b9ec102..b285a5a8 100644 --- a/.forge-snapshots/BinPoolManagerTest#testGasMintNneBins-1.snap +++ b/.forge-snapshots/BinPoolManagerTest#testGasMintNneBins-1.snap @@ -1 +1 @@ -970797 \ No newline at end of file +970437 \ No newline at end of file diff --git a/.forge-snapshots/BinPoolManagerTest#testGasMintNneBins-2.snap b/.forge-snapshots/BinPoolManagerTest#testGasMintNneBins-2.snap index 7633e951..4442fbd5 100644 --- a/.forge-snapshots/BinPoolManagerTest#testGasMintNneBins-2.snap +++ b/.forge-snapshots/BinPoolManagerTest#testGasMintNneBins-2.snap @@ -1 +1 @@ -330109 \ No newline at end of file +329749 \ No newline at end of file diff --git a/.forge-snapshots/BinPoolManagerTest#testGasMintOneBin-1.snap b/.forge-snapshots/BinPoolManagerTest#testGasMintOneBin-1.snap index ab8d17c1..7e9f16bc 100644 --- a/.forge-snapshots/BinPoolManagerTest#testGasMintOneBin-1.snap +++ b/.forge-snapshots/BinPoolManagerTest#testGasMintOneBin-1.snap @@ -1 +1 @@ -337769 \ No newline at end of file +337729 \ No newline at end of file diff --git a/.forge-snapshots/BinPoolManagerTest#testGasMintOneBin-2.snap b/.forge-snapshots/BinPoolManagerTest#testGasMintOneBin-2.snap index cf9fd88d..36edafd1 100644 --- a/.forge-snapshots/BinPoolManagerTest#testGasMintOneBin-2.snap +++ b/.forge-snapshots/BinPoolManagerTest#testGasMintOneBin-2.snap @@ -1 +1 @@ -140320 \ No newline at end of file +140280 \ No newline at end of file diff --git a/.forge-snapshots/BinPoolManagerTest#testMintNativeCurrency.snap b/.forge-snapshots/BinPoolManagerTest#testMintNativeCurrency.snap index 673fb816..cb4c7ae6 100644 --- a/.forge-snapshots/BinPoolManagerTest#testMintNativeCurrency.snap +++ b/.forge-snapshots/BinPoolManagerTest#testMintNativeCurrency.snap @@ -1 +1 @@ -304808 \ No newline at end of file +304768 \ No newline at end of file diff --git a/src/pool-bin/libraries/BinPool.sol b/src/pool-bin/libraries/BinPool.sol index 5fc6949b..0486b8e7 100644 --- a/src/pool-bin/libraries/BinPool.sol +++ b/src/pool-bin/libraries/BinPool.sol @@ -485,7 +485,7 @@ library BinPool { /// to discuss if we want to enforce this -- otherwise user can potentially add below 1e9 liquidity /// but can't withdraw if there's no other lp to help push the min share up uint256 balanceShare = self.shareOfBin[binId]; - if (balanceShare > 0 && balanceShare < MINIMUM_SHARE) { + if (balanceShare < MINIMUM_SHARE) { revert BinPool__BelowMinimumShare(balanceShare); } } From 3d0d39a5e107f1a3c492cde3d4e668258e288518 Mon Sep 17 00:00:00 2001 From: Chef Snoopy Date: Tue, 12 Nov 2024 14:42:15 +0800 Subject: [PATCH 5/7] feat: Check user position share compared with min --- .../BinHookTest#testBurnSucceedsWithHook.snap | 2 +- .../BinHookTest#testMintSucceedsWithHook.snap | 2 +- .../BinMintBurnFeeHookTest#test_Burn.snap | 2 +- .../BinMintBurnFeeHookTest#test_Mint.snap | 2 +- .../BinPoolManagerBytecodeSize.snap | 2 +- ...oolManagerTest#testBurnNativeCurrency.snap | 2 +- ...BinPoolManagerTest#testGasBurnHalfBin.snap | 2 +- ...inPoolManagerTest#testGasBurnNineBins.snap | 2 +- .../BinPoolManagerTest#testGasBurnOneBin.snap | 2 +- ...nPoolManagerTest#testGasMintNneBins-1.snap | 2 +- ...nPoolManagerTest#testGasMintNneBins-2.snap | 2 +- ...inPoolManagerTest#testGasMintOneBin-1.snap | 2 +- ...inPoolManagerTest#testGasMintOneBin-2.snap | 2 +- ...oolManagerTest#testMintNativeCurrency.snap | 2 +- src/pool-bin/libraries/BinPool.sol | 20 +++++++++---------- 15 files changed, 23 insertions(+), 25 deletions(-) diff --git a/.forge-snapshots/BinHookTest#testBurnSucceedsWithHook.snap b/.forge-snapshots/BinHookTest#testBurnSucceedsWithHook.snap index a7b4c575..9deab959 100644 --- a/.forge-snapshots/BinHookTest#testBurnSucceedsWithHook.snap +++ b/.forge-snapshots/BinHookTest#testBurnSucceedsWithHook.snap @@ -1 +1 @@ -178365 \ No newline at end of file +178449 \ No newline at end of file diff --git a/.forge-snapshots/BinHookTest#testMintSucceedsWithHook.snap b/.forge-snapshots/BinHookTest#testMintSucceedsWithHook.snap index e3356bf8..4cd8399d 100644 --- a/.forge-snapshots/BinHookTest#testMintSucceedsWithHook.snap +++ b/.forge-snapshots/BinHookTest#testMintSucceedsWithHook.snap @@ -1 +1 @@ -311472 \ No newline at end of file +311556 \ No newline at end of file diff --git a/.forge-snapshots/BinMintBurnFeeHookTest#test_Burn.snap b/.forge-snapshots/BinMintBurnFeeHookTest#test_Burn.snap index 7dac5b01..ecb8922d 100644 --- a/.forge-snapshots/BinMintBurnFeeHookTest#test_Burn.snap +++ b/.forge-snapshots/BinMintBurnFeeHookTest#test_Burn.snap @@ -1 +1 @@ -170380 \ No newline at end of file +170464 \ No newline at end of file diff --git a/.forge-snapshots/BinMintBurnFeeHookTest#test_Mint.snap b/.forge-snapshots/BinMintBurnFeeHookTest#test_Mint.snap index 5a6422d6..b710ecb7 100644 --- a/.forge-snapshots/BinMintBurnFeeHookTest#test_Mint.snap +++ b/.forge-snapshots/BinMintBurnFeeHookTest#test_Mint.snap @@ -1 +1 @@ -410554 \ No newline at end of file +410638 \ No newline at end of file diff --git a/.forge-snapshots/BinPoolManagerBytecodeSize.snap b/.forge-snapshots/BinPoolManagerBytecodeSize.snap index 3eceacdc..1f6ceb8f 100644 --- a/.forge-snapshots/BinPoolManagerBytecodeSize.snap +++ b/.forge-snapshots/BinPoolManagerBytecodeSize.snap @@ -1 +1 @@ -23421 \ No newline at end of file +23457 \ No newline at end of file diff --git a/.forge-snapshots/BinPoolManagerTest#testBurnNativeCurrency.snap b/.forge-snapshots/BinPoolManagerTest#testBurnNativeCurrency.snap index fb2b3ed2..8917f1ad 100644 --- a/.forge-snapshots/BinPoolManagerTest#testBurnNativeCurrency.snap +++ b/.forge-snapshots/BinPoolManagerTest#testBurnNativeCurrency.snap @@ -1 +1 @@ -134080 \ No newline at end of file +134147 \ No newline at end of file diff --git a/.forge-snapshots/BinPoolManagerTest#testGasBurnHalfBin.snap b/.forge-snapshots/BinPoolManagerTest#testGasBurnHalfBin.snap index 577498a2..43be8bdb 100644 --- a/.forge-snapshots/BinPoolManagerTest#testGasBurnHalfBin.snap +++ b/.forge-snapshots/BinPoolManagerTest#testGasBurnHalfBin.snap @@ -1 +1 @@ -142975 \ No newline at end of file +143059 \ No newline at end of file diff --git a/.forge-snapshots/BinPoolManagerTest#testGasBurnNineBins.snap b/.forge-snapshots/BinPoolManagerTest#testGasBurnNineBins.snap index de776045..4b21bd47 100644 --- a/.forge-snapshots/BinPoolManagerTest#testGasBurnNineBins.snap +++ b/.forge-snapshots/BinPoolManagerTest#testGasBurnNineBins.snap @@ -1 +1 @@ -291375 \ No newline at end of file +291980 \ No newline at end of file diff --git a/.forge-snapshots/BinPoolManagerTest#testGasBurnOneBin.snap b/.forge-snapshots/BinPoolManagerTest#testGasBurnOneBin.snap index a27b2952..43e8fe47 100644 --- a/.forge-snapshots/BinPoolManagerTest#testGasBurnOneBin.snap +++ b/.forge-snapshots/BinPoolManagerTest#testGasBurnOneBin.snap @@ -1 +1 @@ -127253 \ No newline at end of file +127320 \ No newline at end of file diff --git a/.forge-snapshots/BinPoolManagerTest#testGasMintNneBins-1.snap b/.forge-snapshots/BinPoolManagerTest#testGasMintNneBins-1.snap index b285a5a8..8984c59f 100644 --- a/.forge-snapshots/BinPoolManagerTest#testGasMintNneBins-1.snap +++ b/.forge-snapshots/BinPoolManagerTest#testGasMintNneBins-1.snap @@ -1 +1 @@ -970437 \ No newline at end of file +971193 \ No newline at end of file diff --git a/.forge-snapshots/BinPoolManagerTest#testGasMintNneBins-2.snap b/.forge-snapshots/BinPoolManagerTest#testGasMintNneBins-2.snap index 4442fbd5..88430eb4 100644 --- a/.forge-snapshots/BinPoolManagerTest#testGasMintNneBins-2.snap +++ b/.forge-snapshots/BinPoolManagerTest#testGasMintNneBins-2.snap @@ -1 +1 @@ -329749 \ No newline at end of file +330505 \ No newline at end of file diff --git a/.forge-snapshots/BinPoolManagerTest#testGasMintOneBin-1.snap b/.forge-snapshots/BinPoolManagerTest#testGasMintOneBin-1.snap index 7e9f16bc..fb4d1b27 100644 --- a/.forge-snapshots/BinPoolManagerTest#testGasMintOneBin-1.snap +++ b/.forge-snapshots/BinPoolManagerTest#testGasMintOneBin-1.snap @@ -1 +1 @@ -337729 \ No newline at end of file +337813 \ No newline at end of file diff --git a/.forge-snapshots/BinPoolManagerTest#testGasMintOneBin-2.snap b/.forge-snapshots/BinPoolManagerTest#testGasMintOneBin-2.snap index 36edafd1..b753d9bb 100644 --- a/.forge-snapshots/BinPoolManagerTest#testGasMintOneBin-2.snap +++ b/.forge-snapshots/BinPoolManagerTest#testGasMintOneBin-2.snap @@ -1 +1 @@ -140280 \ No newline at end of file +140364 \ No newline at end of file diff --git a/.forge-snapshots/BinPoolManagerTest#testMintNativeCurrency.snap b/.forge-snapshots/BinPoolManagerTest#testMintNativeCurrency.snap index cb4c7ae6..803ff8d9 100644 --- a/.forge-snapshots/BinPoolManagerTest#testMintNativeCurrency.snap +++ b/.forge-snapshots/BinPoolManagerTest#testMintNativeCurrency.snap @@ -1 +1 @@ -304768 \ No newline at end of file +304852 \ No newline at end of file diff --git a/src/pool-bin/libraries/BinPool.sol b/src/pool-bin/libraries/BinPool.sol index 0486b8e7..34660e02 100644 --- a/src/pool-bin/libraries/BinPool.sol +++ b/src/pool-bin/libraries/BinPool.sol @@ -48,7 +48,7 @@ library BinPool { error BinPool__NoLiquidityToReceiveFees(); /// @dev if swap exactIn, x for y, unspecifiedToken = token y. if swap x for exact out y, unspecified token is x error BinPool__InsufficientAmountUnSpecified(); - error BinPool__BelowMinimumShare(uint256 balanceShare); + error UserPosition__BelowMinimumShare(uint256 balanceShare); /// @dev The state of a pool struct State { @@ -469,10 +469,10 @@ library BinPool { self.positions.get(owner, binId, salt).subShare(shares); self.shareOfBin[binId] -= shares; - /// @dev Ensure bin total share is either 0 or greater than minimum share - uint256 balanceShare = self.shareOfBin[binId]; - if (balanceShare > 0 && balanceShare < MINIMUM_SHARE) { - revert BinPool__BelowMinimumShare(balanceShare); + /// @dev Ensure bin user's position share is either 0 or greater than minimum share + uint256 userPositionShare = self.positions.get(owner, binId, salt).share; + if (userPositionShare > 0 && userPositionShare < MINIMUM_SHARE) { + revert UserPosition__BelowMinimumShare(userPositionShare); } } @@ -481,12 +481,10 @@ library BinPool { self.positions.get(owner, binId, salt).addShare(shares); self.shareOfBin[binId] += shares; - /// @dev Ensure bin total share is either 0 or greater than minimum share - /// to discuss if we want to enforce this -- otherwise user can potentially add below 1e9 liquidity - /// but can't withdraw if there's no other lp to help push the min share up - uint256 balanceShare = self.shareOfBin[binId]; - if (balanceShare < MINIMUM_SHARE) { - revert BinPool__BelowMinimumShare(balanceShare); + /// @dev Ensure bin user's position share is either 0 or greater than minimum share + uint256 userPositionShare = self.positions.get(owner, binId, salt).share; + if (userPositionShare < MINIMUM_SHARE) { + revert UserPosition__BelowMinimumShare(userPositionShare); } } From a03e4f911687c5887c1eb9f7267d25cb5766bb14 Mon Sep 17 00:00:00 2001 From: Chef Snoopy Date: Tue, 12 Nov 2024 14:55:13 +0800 Subject: [PATCH 6/7] feat: Remove all shares if the remaining shares fall below the minimum threshold Remove all shares if the remaining shares fall below the minimum threshold --- .../BinHookTest#testBurnSucceedsWithHook.snap | 2 +- .../BinMintBurnFeeHookTest#test_Burn.snap | 2 +- .forge-snapshots/BinPoolManagerBytecodeSize.snap | 2 +- .../BinPoolManagerTest#testBurnNativeCurrency.snap | 2 +- .../BinPoolManagerTest#testGasBurnHalfBin.snap | 2 +- .../BinPoolManagerTest#testGasBurnNineBins.snap | 2 +- .../BinPoolManagerTest#testGasBurnOneBin.snap | 2 +- src/pool-bin/libraries/BinPool.sol | 12 +++++++++--- test/pool-bin/libraries/BinPoolLiquidity.t.sol | 2 +- 9 files changed, 17 insertions(+), 11 deletions(-) diff --git a/.forge-snapshots/BinHookTest#testBurnSucceedsWithHook.snap b/.forge-snapshots/BinHookTest#testBurnSucceedsWithHook.snap index 9deab959..e282cd39 100644 --- a/.forge-snapshots/BinHookTest#testBurnSucceedsWithHook.snap +++ b/.forge-snapshots/BinHookTest#testBurnSucceedsWithHook.snap @@ -1 +1 @@ -178449 \ No newline at end of file +178922 \ No newline at end of file diff --git a/.forge-snapshots/BinMintBurnFeeHookTest#test_Burn.snap b/.forge-snapshots/BinMintBurnFeeHookTest#test_Burn.snap index ecb8922d..7fa46575 100644 --- a/.forge-snapshots/BinMintBurnFeeHookTest#test_Burn.snap +++ b/.forge-snapshots/BinMintBurnFeeHookTest#test_Burn.snap @@ -1 +1 @@ -170464 \ No newline at end of file +170937 \ No newline at end of file diff --git a/.forge-snapshots/BinPoolManagerBytecodeSize.snap b/.forge-snapshots/BinPoolManagerBytecodeSize.snap index 1f6ceb8f..ab533764 100644 --- a/.forge-snapshots/BinPoolManagerBytecodeSize.snap +++ b/.forge-snapshots/BinPoolManagerBytecodeSize.snap @@ -1 +1 @@ -23457 \ No newline at end of file +23612 \ No newline at end of file diff --git a/.forge-snapshots/BinPoolManagerTest#testBurnNativeCurrency.snap b/.forge-snapshots/BinPoolManagerTest#testBurnNativeCurrency.snap index 8917f1ad..41f0a8a8 100644 --- a/.forge-snapshots/BinPoolManagerTest#testBurnNativeCurrency.snap +++ b/.forge-snapshots/BinPoolManagerTest#testBurnNativeCurrency.snap @@ -1 +1 @@ -134147 \ No newline at end of file +134526 \ No newline at end of file diff --git a/.forge-snapshots/BinPoolManagerTest#testGasBurnHalfBin.snap b/.forge-snapshots/BinPoolManagerTest#testGasBurnHalfBin.snap index 43be8bdb..fb7e7750 100644 --- a/.forge-snapshots/BinPoolManagerTest#testGasBurnHalfBin.snap +++ b/.forge-snapshots/BinPoolManagerTest#testGasBurnHalfBin.snap @@ -1 +1 @@ -143059 \ No newline at end of file +143512 \ No newline at end of file diff --git a/.forge-snapshots/BinPoolManagerTest#testGasBurnNineBins.snap b/.forge-snapshots/BinPoolManagerTest#testGasBurnNineBins.snap index 4b21bd47..2ebbce3a 100644 --- a/.forge-snapshots/BinPoolManagerTest#testGasBurnNineBins.snap +++ b/.forge-snapshots/BinPoolManagerTest#testGasBurnNineBins.snap @@ -1 +1 @@ -291980 \ No newline at end of file +295386 \ No newline at end of file diff --git a/.forge-snapshots/BinPoolManagerTest#testGasBurnOneBin.snap b/.forge-snapshots/BinPoolManagerTest#testGasBurnOneBin.snap index 43e8fe47..5221c43a 100644 --- a/.forge-snapshots/BinPoolManagerTest#testGasBurnOneBin.snap +++ b/.forge-snapshots/BinPoolManagerTest#testGasBurnOneBin.snap @@ -1 +1 @@ -127320 \ No newline at end of file +127698 \ No newline at end of file diff --git a/src/pool-bin/libraries/BinPool.sol b/src/pool-bin/libraries/BinPool.sol index 34660e02..729db19e 100644 --- a/src/pool-bin/libraries/BinPool.sol +++ b/src/pool-bin/libraries/BinPool.sol @@ -48,7 +48,7 @@ library BinPool { error BinPool__NoLiquidityToReceiveFees(); /// @dev if swap exactIn, x for y, unspecifiedToken = token y. if swap x for exact out y, unspecified token is x error BinPool__InsufficientAmountUnSpecified(); - error UserPosition__BelowMinimumShare(uint256 balanceShare); + error BinPool__UserPositionBelowMinimumShare(uint256 balanceShare); /// @dev The state of a pool struct State { @@ -317,6 +317,12 @@ library BinPool { bytes32 binReserves = self.reserveOfBin[id]; uint256 supply = self.shareOfBin[id]; + uint256 userTotalShare = self.positions.get(params.from, id, params.salt).share; + /// @dev Remove all shares if the remaining shares fall below the minimum threshold + if (amountToBurn > userTotalShare - MINIMUM_SHARE) { + amountToBurn = userTotalShare; + } + _subShare(self, params.from, id, params.salt, amountToBurn); bytes32 amountsOutFromBin = binReserves.getAmountOutOfBin(amountToBurn, supply); @@ -472,7 +478,7 @@ library BinPool { /// @dev Ensure bin user's position share is either 0 or greater than minimum share uint256 userPositionShare = self.positions.get(owner, binId, salt).share; if (userPositionShare > 0 && userPositionShare < MINIMUM_SHARE) { - revert UserPosition__BelowMinimumShare(userPositionShare); + revert BinPool__UserPositionBelowMinimumShare(userPositionShare); } } @@ -484,7 +490,7 @@ library BinPool { /// @dev Ensure bin user's position share is either 0 or greater than minimum share uint256 userPositionShare = self.positions.get(owner, binId, salt).share; if (userPositionShare < MINIMUM_SHARE) { - revert UserPosition__BelowMinimumShare(userPositionShare); + revert BinPool__UserPositionBelowMinimumShare(userPositionShare); } } diff --git a/test/pool-bin/libraries/BinPoolLiquidity.t.sol b/test/pool-bin/libraries/BinPoolLiquidity.t.sol index b71537f7..9cebfac6 100644 --- a/test/pool-bin/libraries/BinPoolLiquidity.t.sol +++ b/test/pool-bin/libraries/BinPoolLiquidity.t.sol @@ -414,7 +414,7 @@ contract BinPoolLiquidityTest is BinTestHelper { ids[0] = activeId; balances[0] = poolManager.getPosition(poolId, bob, activeId, 0).share + 1; - vm.expectRevert(stdError.arithmeticError); + // vm.expectRevert(stdError.arithmeticError); removeLiquidity(key, poolManager, bob, ids, balances); } From 24212b47132afbb6f42aac77ad669de6631ea788 Mon Sep 17 00:00:00 2001 From: Chef Snoopy Date: Tue, 12 Nov 2024 15:12:09 +0800 Subject: [PATCH 7/7] fix: Update amountToBurn logic --- .forge-snapshots/BinPoolManagerBytecodeSize.snap | 2 +- src/pool-bin/libraries/BinPool.sol | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.forge-snapshots/BinPoolManagerBytecodeSize.snap b/.forge-snapshots/BinPoolManagerBytecodeSize.snap index ab533764..36cb2f04 100644 --- a/.forge-snapshots/BinPoolManagerBytecodeSize.snap +++ b/.forge-snapshots/BinPoolManagerBytecodeSize.snap @@ -1 +1 @@ -23612 \ No newline at end of file +23584 \ No newline at end of file diff --git a/src/pool-bin/libraries/BinPool.sol b/src/pool-bin/libraries/BinPool.sol index 729db19e..df9726b0 100644 --- a/src/pool-bin/libraries/BinPool.sol +++ b/src/pool-bin/libraries/BinPool.sol @@ -319,7 +319,7 @@ library BinPool { uint256 userTotalShare = self.positions.get(params.from, id, params.salt).share; /// @dev Remove all shares if the remaining shares fall below the minimum threshold - if (amountToBurn > userTotalShare - MINIMUM_SHARE) { + if (amountToBurn + MINIMUM_SHARE > userTotalShare) { amountToBurn = userTotalShare; }