From 6b2f835b997fd0ff97dba9a8bd63064fd8b74b44 Mon Sep 17 00:00:00 2001 From: Chef Snoopy Date: Tue, 6 Aug 2024 11:34:00 +0800 Subject: [PATCH 1/8] feat: Support modifyLiquidities --- ...ddLiquidityOutsideActiveId_ExistingId.snap | 2 +- ...testAddLiquidityOutsideActiveId_NewId.snap | 2 +- ...dityTest#testAddLiquidityWithActiveId.snap | 2 +- ...testAddLiquidityWithActiveId_WithHook.snap | 2 +- ...oveLiquidityOutsideActiveId_ThreeBins.snap | 2 +- ...RemoveLiquidityWithActiveId_ThreeBins.snap | 2 +- ...iquidityTest#testRemoveLiquidity_Half.snap | 2 +- ...V2Test#testMigrateFromV2IncludingInit.snap | 2 +- ...apV2Test#testMigrateFromV2WithoutInit.snap | 2 +- ...t#testMigrateFromV2WithoutNativeToken.snap | 2 +- ...V3Test#testMigrateFromV3IncludingInit.snap | 2 +- ...apV3Test#testMigrateFromV3WithoutInit.snap | 2 +- ...t#testMigrateFromV3WithoutNativeToken.snap | 2 +- ...V2Test#testMigrateFromV2IncludingInit.snap | 2 +- ...apV2Test#testMigrateFromV2WithoutInit.snap | 2 +- ...t#testMigrateFromV2WithoutNativeToken.snap | 2 +- ...V3Test#testMigrateFromV3IncludingInit.snap | 2 +- ...apV3Test#testMigrateFromV3WithoutInit.snap | 2 +- ...t#testMigrateFromV3WithoutNativeToken.snap | 2 +- ...batchMintIncreaseAndDecreaseLiquidity.snap | 2 +- src/pool-bin/BinFungiblePositionManager.sol | 240 +++++++++++------- src/pool-bin/BinFungibleToken.sol | 6 + .../IBinFungiblePositionManager.sol | 15 ++ 23 files changed, 190 insertions(+), 111 deletions(-) diff --git a/.forge-snapshots/BinFungiblePositionManager_AddLiquidityTest#testAddLiquidityOutsideActiveId_ExistingId.snap b/.forge-snapshots/BinFungiblePositionManager_AddLiquidityTest#testAddLiquidityOutsideActiveId_ExistingId.snap index e67a084..f9564c9 100644 --- a/.forge-snapshots/BinFungiblePositionManager_AddLiquidityTest#testAddLiquidityOutsideActiveId_ExistingId.snap +++ b/.forge-snapshots/BinFungiblePositionManager_AddLiquidityTest#testAddLiquidityOutsideActiveId_ExistingId.snap @@ -1 +1 @@ -180160 \ No newline at end of file +181075 \ No newline at end of file diff --git a/.forge-snapshots/BinFungiblePositionManager_AddLiquidityTest#testAddLiquidityOutsideActiveId_NewId.snap b/.forge-snapshots/BinFungiblePositionManager_AddLiquidityTest#testAddLiquidityOutsideActiveId_NewId.snap index ddab7ba..623566e 100644 --- a/.forge-snapshots/BinFungiblePositionManager_AddLiquidityTest#testAddLiquidityOutsideActiveId_NewId.snap +++ b/.forge-snapshots/BinFungiblePositionManager_AddLiquidityTest#testAddLiquidityOutsideActiveId_NewId.snap @@ -1 +1 @@ -634347 \ No newline at end of file +635263 \ No newline at end of file diff --git a/.forge-snapshots/BinFungiblePositionManager_AddLiquidityTest#testAddLiquidityWithActiveId.snap b/.forge-snapshots/BinFungiblePositionManager_AddLiquidityTest#testAddLiquidityWithActiveId.snap index 10afbd6..622aac6 100644 --- a/.forge-snapshots/BinFungiblePositionManager_AddLiquidityTest#testAddLiquidityWithActiveId.snap +++ b/.forge-snapshots/BinFungiblePositionManager_AddLiquidityTest#testAddLiquidityWithActiveId.snap @@ -1 +1 @@ -901398 \ No newline at end of file +902346 \ No newline at end of file diff --git a/.forge-snapshots/BinFungiblePositionManager_AddLiquidityTest#testAddLiquidityWithActiveId_WithHook.snap b/.forge-snapshots/BinFungiblePositionManager_AddLiquidityTest#testAddLiquidityWithActiveId_WithHook.snap index 20dab9e..12dc6d8 100644 --- a/.forge-snapshots/BinFungiblePositionManager_AddLiquidityTest#testAddLiquidityWithActiveId_WithHook.snap +++ b/.forge-snapshots/BinFungiblePositionManager_AddLiquidityTest#testAddLiquidityWithActiveId_WithHook.snap @@ -1 +1 @@ -1267731 \ No newline at end of file +1268770 \ No newline at end of file diff --git a/.forge-snapshots/BinFungiblePositionManager_RemoveLiquidityTest#testRemoveLiquidityOutsideActiveId_ThreeBins.snap b/.forge-snapshots/BinFungiblePositionManager_RemoveLiquidityTest#testRemoveLiquidityOutsideActiveId_ThreeBins.snap index 7d3e342..cd6eb2c 100644 --- a/.forge-snapshots/BinFungiblePositionManager_RemoveLiquidityTest#testRemoveLiquidityOutsideActiveId_ThreeBins.snap +++ b/.forge-snapshots/BinFungiblePositionManager_RemoveLiquidityTest#testRemoveLiquidityOutsideActiveId_ThreeBins.snap @@ -1 +1 @@ -145917 \ No newline at end of file +146776 \ No newline at end of file diff --git a/.forge-snapshots/BinFungiblePositionManager_RemoveLiquidityTest#testRemoveLiquidityWithActiveId_ThreeBins.snap b/.forge-snapshots/BinFungiblePositionManager_RemoveLiquidityTest#testRemoveLiquidityWithActiveId_ThreeBins.snap index 09cf27e..d279e99 100644 --- a/.forge-snapshots/BinFungiblePositionManager_RemoveLiquidityTest#testRemoveLiquidityWithActiveId_ThreeBins.snap +++ b/.forge-snapshots/BinFungiblePositionManager_RemoveLiquidityTest#testRemoveLiquidityWithActiveId_ThreeBins.snap @@ -1 +1 @@ -212278 \ No newline at end of file +213159 \ No newline at end of file diff --git a/.forge-snapshots/BinFungiblePositionManager_RemoveLiquidityTest#testRemoveLiquidity_Half.snap b/.forge-snapshots/BinFungiblePositionManager_RemoveLiquidityTest#testRemoveLiquidity_Half.snap index c16fb44..bf69b0d 100644 --- a/.forge-snapshots/BinFungiblePositionManager_RemoveLiquidityTest#testRemoveLiquidity_Half.snap +++ b/.forge-snapshots/BinFungiblePositionManager_RemoveLiquidityTest#testRemoveLiquidity_Half.snap @@ -1 +1 @@ -237173 \ No newline at end of file +238274 \ No newline at end of file diff --git a/.forge-snapshots/BinMigratorFromPancakeswapV2Test#testMigrateFromV2IncludingInit.snap b/.forge-snapshots/BinMigratorFromPancakeswapV2Test#testMigrateFromV2IncludingInit.snap index 4cf2c96..2a10ace 100644 --- a/.forge-snapshots/BinMigratorFromPancakeswapV2Test#testMigrateFromV2IncludingInit.snap +++ b/.forge-snapshots/BinMigratorFromPancakeswapV2Test#testMigrateFromV2IncludingInit.snap @@ -1 +1 @@ -1014388 \ No newline at end of file +1015374 \ No newline at end of file diff --git a/.forge-snapshots/BinMigratorFromPancakeswapV2Test#testMigrateFromV2WithoutInit.snap b/.forge-snapshots/BinMigratorFromPancakeswapV2Test#testMigrateFromV2WithoutInit.snap index fe7df4b..d154ea6 100644 --- a/.forge-snapshots/BinMigratorFromPancakeswapV2Test#testMigrateFromV2WithoutInit.snap +++ b/.forge-snapshots/BinMigratorFromPancakeswapV2Test#testMigrateFromV2WithoutInit.snap @@ -1 +1 @@ -974603 \ No newline at end of file +975551 \ No newline at end of file diff --git a/.forge-snapshots/BinMigratorFromPancakeswapV2Test#testMigrateFromV2WithoutNativeToken.snap b/.forge-snapshots/BinMigratorFromPancakeswapV2Test#testMigrateFromV2WithoutNativeToken.snap index f2eb15e..29c271a 100644 --- a/.forge-snapshots/BinMigratorFromPancakeswapV2Test#testMigrateFromV2WithoutNativeToken.snap +++ b/.forge-snapshots/BinMigratorFromPancakeswapV2Test#testMigrateFromV2WithoutNativeToken.snap @@ -1 +1 @@ -1018858 \ No newline at end of file +1019806 \ No newline at end of file diff --git a/.forge-snapshots/BinMigratorFromPancakeswapV3Test#testMigrateFromV3IncludingInit.snap b/.forge-snapshots/BinMigratorFromPancakeswapV3Test#testMigrateFromV3IncludingInit.snap index aa040fb..c1e424f 100644 --- a/.forge-snapshots/BinMigratorFromPancakeswapV3Test#testMigrateFromV3IncludingInit.snap +++ b/.forge-snapshots/BinMigratorFromPancakeswapV3Test#testMigrateFromV3IncludingInit.snap @@ -1 +1 @@ -1093305 \ No newline at end of file +1094291 \ No newline at end of file diff --git a/.forge-snapshots/BinMigratorFromPancakeswapV3Test#testMigrateFromV3WithoutInit.snap b/.forge-snapshots/BinMigratorFromPancakeswapV3Test#testMigrateFromV3WithoutInit.snap index e6425b8..0735420 100644 --- a/.forge-snapshots/BinMigratorFromPancakeswapV3Test#testMigrateFromV3WithoutInit.snap +++ b/.forge-snapshots/BinMigratorFromPancakeswapV3Test#testMigrateFromV3WithoutInit.snap @@ -1 +1 @@ -1053572 \ No newline at end of file +1054520 \ No newline at end of file diff --git a/.forge-snapshots/BinMigratorFromPancakeswapV3Test#testMigrateFromV3WithoutNativeToken.snap b/.forge-snapshots/BinMigratorFromPancakeswapV3Test#testMigrateFromV3WithoutNativeToken.snap index 826bef2..20d98ea 100644 --- a/.forge-snapshots/BinMigratorFromPancakeswapV3Test#testMigrateFromV3WithoutNativeToken.snap +++ b/.forge-snapshots/BinMigratorFromPancakeswapV3Test#testMigrateFromV3WithoutNativeToken.snap @@ -1 +1 @@ -1091207 \ No newline at end of file +1092155 \ No newline at end of file diff --git a/.forge-snapshots/BinMigratorFromUniswapV2Test#testMigrateFromV2IncludingInit.snap b/.forge-snapshots/BinMigratorFromUniswapV2Test#testMigrateFromV2IncludingInit.snap index 69d1d84..bf40e69 100644 --- a/.forge-snapshots/BinMigratorFromUniswapV2Test#testMigrateFromV2IncludingInit.snap +++ b/.forge-snapshots/BinMigratorFromUniswapV2Test#testMigrateFromV2IncludingInit.snap @@ -1 +1 @@ -1014400 \ No newline at end of file +1015386 \ No newline at end of file diff --git a/.forge-snapshots/BinMigratorFromUniswapV2Test#testMigrateFromV2WithoutInit.snap b/.forge-snapshots/BinMigratorFromUniswapV2Test#testMigrateFromV2WithoutInit.snap index 5a381e7..810f7a9 100644 --- a/.forge-snapshots/BinMigratorFromUniswapV2Test#testMigrateFromV2WithoutInit.snap +++ b/.forge-snapshots/BinMigratorFromUniswapV2Test#testMigrateFromV2WithoutInit.snap @@ -1 +1 @@ -974615 \ No newline at end of file +975563 \ No newline at end of file diff --git a/.forge-snapshots/BinMigratorFromUniswapV2Test#testMigrateFromV2WithoutNativeToken.snap b/.forge-snapshots/BinMigratorFromUniswapV2Test#testMigrateFromV2WithoutNativeToken.snap index 1805b0c..734f9b9 100644 --- a/.forge-snapshots/BinMigratorFromUniswapV2Test#testMigrateFromV2WithoutNativeToken.snap +++ b/.forge-snapshots/BinMigratorFromUniswapV2Test#testMigrateFromV2WithoutNativeToken.snap @@ -1 +1 @@ -1018855 \ No newline at end of file +1019803 \ No newline at end of file diff --git a/.forge-snapshots/BinMigratorFromUniswapV3Test#testMigrateFromV3IncludingInit.snap b/.forge-snapshots/BinMigratorFromUniswapV3Test#testMigrateFromV3IncludingInit.snap index 138b605..8083e83 100644 --- a/.forge-snapshots/BinMigratorFromUniswapV3Test#testMigrateFromV3IncludingInit.snap +++ b/.forge-snapshots/BinMigratorFromUniswapV3Test#testMigrateFromV3IncludingInit.snap @@ -1 +1 @@ -1091287 \ No newline at end of file +1092273 \ No newline at end of file diff --git a/.forge-snapshots/BinMigratorFromUniswapV3Test#testMigrateFromV3WithoutInit.snap b/.forge-snapshots/BinMigratorFromUniswapV3Test#testMigrateFromV3WithoutInit.snap index 3ca4d06..f31f146 100644 --- a/.forge-snapshots/BinMigratorFromUniswapV3Test#testMigrateFromV3WithoutInit.snap +++ b/.forge-snapshots/BinMigratorFromUniswapV3Test#testMigrateFromV3WithoutInit.snap @@ -1 +1 @@ -1051554 \ No newline at end of file +1052502 \ No newline at end of file diff --git a/.forge-snapshots/BinMigratorFromUniswapV3Test#testMigrateFromV3WithoutNativeToken.snap b/.forge-snapshots/BinMigratorFromUniswapV3Test#testMigrateFromV3WithoutNativeToken.snap index 3e4917f..f6d976a 100644 --- a/.forge-snapshots/BinMigratorFromUniswapV3Test#testMigrateFromV3WithoutNativeToken.snap +++ b/.forge-snapshots/BinMigratorFromUniswapV3Test#testMigrateFromV3WithoutNativeToken.snap @@ -1 +1 @@ -1089185 \ No newline at end of file +1090133 \ No newline at end of file diff --git a/.forge-snapshots/NonFungiblePositionManagerBatch#batchMintIncreaseAndDecreaseLiquidity.snap b/.forge-snapshots/NonFungiblePositionManagerBatch#batchMintIncreaseAndDecreaseLiquidity.snap index a924f0b..f697a1a 100644 --- a/.forge-snapshots/NonFungiblePositionManagerBatch#batchMintIncreaseAndDecreaseLiquidity.snap +++ b/.forge-snapshots/NonFungiblePositionManagerBatch#batchMintIncreaseAndDecreaseLiquidity.snap @@ -1 +1 @@ -719013 \ No newline at end of file +718653 \ No newline at end of file diff --git a/src/pool-bin/BinFungiblePositionManager.sol b/src/pool-bin/BinFungiblePositionManager.sol index 7991f2a..14e7b0f 100644 --- a/src/pool-bin/BinFungiblePositionManager.sol +++ b/src/pool-bin/BinFungiblePositionManager.sol @@ -86,6 +86,16 @@ contract BinFungiblePositionManager is poolManager.initialize(poolKey, activeId, hookData); } + /// @inheritdoc IBinFungiblePositionManager + function modifyLiquidities(bytes calldata lockData, uint256 deadline) + external + payable + checkDeadline(deadline) + returns (bytes[] memory) + { + return abi.decode(vault.lock(abi.encode(msg.sender, false, lockData)), (bytes[])); + } + /// @inheritdoc IBinFungiblePositionManager function addLiquidity(AddLiquidityParams calldata params) external @@ -94,20 +104,11 @@ contract BinFungiblePositionManager is checkDeadline(params.deadline) returns (uint128 amount0, uint128 amount1, uint256[] memory tokenIds, uint256[] memory liquidityMinted) { - if ( - params.deltaIds.length != params.distributionX.length - || params.deltaIds.length != params.distributionY.length - ) { - revert InputLengthMismatch(); - } - - if (params.activeIdDesired > type(uint24).max || params.idSlippage > type(uint24).max) { - revert AddLiquidityInputActiveIdMismath(); - } + bytes memory addLiquidityData = + abi.encode(CallbackData(msg.sender, CallbackDataType.AddLiquidity, abi.encode(params))); (amount0, amount1, tokenIds, liquidityMinted) = abi.decode( - vault.lock(abi.encode(CallbackData(msg.sender, CallbackDataType.AddLiquidity, abi.encode(params)))), - (uint128, uint128, uint256[], uint256[]) + vault.lock(abi.encode(msg.sender, true, addLiquidityData)), (uint128, uint128, uint256[], uint256[]) ); emit TransferBatch(msg.sender, address(0), params.to, tokenIds, liquidityMinted); @@ -119,15 +120,18 @@ contract BinFungiblePositionManager is payable override checkDeadline(params.deadline) - checkApproval(params.from, msg.sender) - returns (uint128 amount0, uint128 amount1, uint256[] memory tokenIds) + returns ( + // checkApproval(params.from, msg.sender) + uint128 amount0, + uint128 amount1, + uint256[] memory tokenIds + ) { - if (params.ids.length != params.amounts.length) revert InputLengthMismatch(); + bytes memory removeLiquidityData = + abi.encode(CallbackData(msg.sender, CallbackDataType.RemoveLiquidity, abi.encode(params))); - (amount0, amount1, tokenIds) = abi.decode( - vault.lock(abi.encode(CallbackData(msg.sender, CallbackDataType.RemoveLiquidity, abi.encode(params)))), - (uint128, uint128, uint256[]) - ); + (amount0, amount1, tokenIds) = + abi.decode(vault.lock(abi.encode(msg.sender, true, removeLiquidityData)), (uint128, uint128, uint256[])); emit TransferBatch(msg.sender, params.from, address(0), tokenIds, params.amounts); } @@ -135,100 +139,154 @@ contract BinFungiblePositionManager is function lockAcquired(bytes calldata rawData) external override returns (bytes memory returnData) { if (msg.sender != address(vault)) revert OnlyVaultCaller(); - CallbackData memory data = abi.decode(rawData, (CallbackData)); + (address sender, bool isSingle, bytes memory lockData) = abi.decode(rawData, (address, bool, bytes)); + if (isSingle) { + CallbackData memory data = abi.decode(lockData, (CallbackData)); + return _handleSingleAction(data, sender, true); + } else { + bytes[] memory params = abi.decode(lockData, (bytes[])); + return _dispatch(params, sender); + } + } + + function _dispatch(bytes[] memory params, address sender) internal returns (bytes memory returnDataArrayBytes) { + uint256 length = params.length; + bytes[] memory returnData = new bytes[](length); + // In order to save gas, we will set the settle flag to true if only one liquidity modification + bool shouldSettle = length == 1; + for (uint256 i; i < length; i++) { + CallbackData memory data = abi.decode(params[i], (CallbackData)); + returnData[i] = _handleSingleAction(data, sender, shouldSettle); + } + + return abi.encode(returnData); + } + function _handleSingleAction(CallbackData memory data, address sender, bool shouldSettle) + internal + returns (bytes memory) + { if (data.callbackDataType == CallbackDataType.AddLiquidity) { - AddLiquidityParams memory params = abi.decode(data.params, (AddLiquidityParams)); - - /// @dev Checks if the activeId is within slippage before calling mint. If user mint to activeId and there - // was a swap in hook.beforeMint() which changes the activeId, user txn will fail - (uint24 activeId,,) = poolManager.getSlot0(params.poolKey.toId()); - if ( - params.activeIdDesired + params.idSlippage < activeId - || params.activeIdDesired - params.idSlippage > activeId - ) { - revert IdDesiredOverflows(activeId); - } + return _handleIncreaseLiquidity(data, sender, shouldSettle); + } else if (data.callbackDataType == CallbackDataType.RemoveLiquidity) { + return _handleDecreaseLiquidity(data, sender, shouldSettle); + } else { + revert InvalidCalldataType(); + } + } - bytes32[] memory liquidityConfigs = new bytes32[](params.deltaIds.length); - for (uint256 i; i < liquidityConfigs.length;) { - int256 _id = int256(uint256(activeId)) + params.deltaIds[i]; - if (_id < 0 || uint256(_id) > type(uint24).max) revert IdOverflows(_id); + function _handleIncreaseLiquidity(CallbackData memory data, address sender, bool shouldSettle) + internal + returns (bytes memory) + { + AddLiquidityParams memory params = abi.decode(data.params, (AddLiquidityParams)); - liquidityConfigs[i] = LiquidityConfigurations.encodeParams( - uint64(params.distributionX[i]), uint64(params.distributionY[i]), uint24(uint256(_id)) - ); + if ( + params.deltaIds.length != params.distributionX.length + || params.deltaIds.length != params.distributionY.length + ) { + revert InputLengthMismatch(); + } - unchecked { - ++i; - } - } + if (params.activeIdDesired > type(uint24).max || params.idSlippage > type(uint24).max) { + revert AddLiquidityInputActiveIdMismath(); + } - bytes32 amountIn = params.amount0.encode(params.amount1); - (BalanceDelta delta, BinPool.MintArrays memory mintArray) = poolManager.mint( - params.poolKey, - IBinPoolManager.MintParams({liquidityConfigs: liquidityConfigs, amountIn: amountIn, salt: bytes32(0)}), - ZERO_BYTES + /// @dev Checks if the activeId is within slippage before calling mint. If user mint to activeId and there + // was a swap in hook.beforeMint() which changes the activeId, user txn will fail + (uint24 activeId,,) = poolManager.getSlot0(params.poolKey.toId()); + if ( + params.activeIdDesired + params.idSlippage < activeId + || params.activeIdDesired - params.idSlippage > activeId + ) { + revert IdDesiredOverflows(activeId); + } + + bytes32[] memory liquidityConfigs = new bytes32[](params.deltaIds.length); + for (uint256 i; i < liquidityConfigs.length;) { + int256 _id = int256(uint256(activeId)) + params.deltaIds[i]; + if (_id < 0 || uint256(_id) > type(uint24).max) revert IdOverflows(_id); + + liquidityConfigs[i] = LiquidityConfigurations.encodeParams( + uint64(params.distributionX[i]), uint64(params.distributionY[i]), uint24(uint256(_id)) ); - // delta amt0/amt1 will always be negative in mint case - if (delta.amount0() > 0 || delta.amount1() > 0) revert IncorrectOutputAmount(); - if (uint128(-delta.amount0()) < params.amount0Min || uint128(-delta.amount1()) < params.amount1Min) { - revert OutputAmountSlippage(); + unchecked { + ++i; } + } - _settleDeltas(data.sender, params.poolKey, delta); + bytes32 amountIn = params.amount0.encode(params.amount1); + (BalanceDelta delta, BinPool.MintArrays memory mintArray) = poolManager.mint( + params.poolKey, + IBinPoolManager.MintParams({liquidityConfigs: liquidityConfigs, amountIn: amountIn, salt: bytes32(0)}), + ZERO_BYTES + ); - // mint - PoolId poolId = cachePoolKey(params.poolKey); - uint256[] memory tokenIds = new uint256[](mintArray.ids.length); - for (uint256 i; i < mintArray.ids.length;) { - uint256 tokenId = poolId.toTokenId(mintArray.ids[i]); - _mint(params.to, tokenId, mintArray.liquidityMinted[i]); + // delta amt0/amt1 will always be negative in mint case + if (delta.amount0() > 0 || delta.amount1() > 0) revert IncorrectOutputAmount(); + if (uint128(-delta.amount0()) < params.amount0Min || uint128(-delta.amount1()) < params.amount1Min) { + revert OutputAmountSlippage(); + } - if (_positions[tokenId].binId == 0) { - _positions[tokenId] = TokenPosition({poolId: poolId, binId: uint24(mintArray.ids[i])}); - } + if (shouldSettle) _settleDeltas(sender, params.poolKey, delta); - tokenIds[i] = tokenId; - unchecked { - ++i; - } + // mint + PoolId poolId = cachePoolKey(params.poolKey); + uint256[] memory tokenIds = new uint256[](mintArray.ids.length); + for (uint256 i; i < mintArray.ids.length;) { + uint256 tokenId = poolId.toTokenId(mintArray.ids[i]); + _mint(params.to, tokenId, mintArray.liquidityMinted[i]); + + if (_positions[tokenId].binId == 0) { + _positions[tokenId] = TokenPosition({poolId: poolId, binId: uint24(mintArray.ids[i])}); } - return abi.encode(uint128(-delta.amount0()), uint128(-delta.amount1()), tokenIds, mintArray.liquidityMinted); - } else if (data.callbackDataType == CallbackDataType.RemoveLiquidity) { - RemoveLiquidityParams memory params = abi.decode(data.params, (RemoveLiquidityParams)); + tokenIds[i] = tokenId; + unchecked { + ++i; + } + } - BalanceDelta delta = poolManager.burn( - params.poolKey, - IBinPoolManager.BurnParams({ids: params.ids, amountsToBurn: params.amounts, salt: bytes32(0)}), - ZERO_BYTES - ); + return abi.encode(uint128(-delta.amount0()), uint128(-delta.amount1()), tokenIds, mintArray.liquidityMinted); + } - // delta amt0/amt1 will either be 0 or positive in removing liquidity - if (delta.amount0() < 0 || delta.amount1() < 0) revert IncorrectOutputAmount(); - if (uint128(delta.amount0()) < params.amount0Min || uint128(delta.amount1()) < params.amount1Min) { - revert OutputAmountSlippage(); - } + function _handleDecreaseLiquidity(CallbackData memory data, address sender, bool shouldSettle) + internal + returns (bytes memory) + { + RemoveLiquidityParams memory params = abi.decode(data.params, (RemoveLiquidityParams)); + if (params.ids.length != params.amounts.length) revert InputLengthMismatch(); + _checkApproval(params.from, sender); - _settleDeltas(params.to, params.poolKey, delta); + BalanceDelta delta = poolManager.burn( + params.poolKey, + IBinPoolManager.BurnParams({ids: params.ids, amountsToBurn: params.amounts, salt: bytes32(0)}), + ZERO_BYTES + ); - // Burn NFT - PoolId poolId = params.poolKey.toId(); - uint256[] memory tokenIds = new uint256[](params.ids.length); - for (uint256 i; i < params.ids.length;) { - uint256 tokenId = poolId.toTokenId(params.ids[i]); - _burn(params.from, tokenId, params.amounts[i]); + // delta amt0/amt1 will either be 0 or positive in removing liquidity + if (delta.amount0() < 0 || delta.amount1() < 0) revert IncorrectOutputAmount(); + if (uint128(delta.amount0()) < params.amount0Min || uint128(delta.amount1()) < params.amount1Min) { + revert OutputAmountSlippage(); + } - tokenIds[i] = tokenId; - unchecked { - ++i; - } - } + if (shouldSettle) _settleDeltas(params.to, params.poolKey, delta); - return abi.encode(delta.amount0(), delta.amount1(), tokenIds); + // Burn NFT + PoolId poolId = params.poolKey.toId(); + uint256[] memory tokenIds = new uint256[](params.ids.length); + for (uint256 i; i < params.ids.length;) { + uint256 tokenId = poolId.toTokenId(params.ids[i]); + _burn(params.from, tokenId, params.amounts[i]); + + tokenIds[i] = tokenId; + unchecked { + ++i; + } } + + return abi.encode(delta.amount0(), delta.amount1(), tokenIds); } /// @notice Transfer token from user to vault. If the currency is native, assume ETH is on contract diff --git a/src/pool-bin/BinFungibleToken.sol b/src/pool-bin/BinFungibleToken.sol index 3391352..a499890 100644 --- a/src/pool-bin/BinFungibleToken.sol +++ b/src/pool-bin/BinFungibleToken.sol @@ -29,6 +29,12 @@ abstract contract BinFungibleToken is IBinFungibleToken { _; } + function _checkApproval(address from, address spender) internal view { + if (!(spender == from || isApprovedForAll[from][spender])) { + revert BinFungibleToken_SpenderNotApproved(from, spender); + } + } + /*////////////////////////////////////////////////////////////// LOGIC //////////////////////////////////////////////////////////////*/ diff --git a/src/pool-bin/interfaces/IBinFungiblePositionManager.sol b/src/pool-bin/interfaces/IBinFungiblePositionManager.sol index 4a6a2b6..0e3dccc 100644 --- a/src/pool-bin/interfaces/IBinFungiblePositionManager.sol +++ b/src/pool-bin/interfaces/IBinFungiblePositionManager.sol @@ -23,6 +23,7 @@ interface IBinFungiblePositionManager is IBinFungibleToken, IPeripheryPayments, error OutputAmountSlippage(); error IncorrectOutputAmount(); error InvalidTokenID(); + error InvalidCalldataType(); /// @notice AddLiquidityParams /// - amount0: Amount to send for token0 @@ -102,6 +103,20 @@ interface IBinFungiblePositionManager is IBinFungibleToken, IPeripheryPayments, /// @param hookData Hook data for the pool function initialize(PoolKey memory poolKey, uint24 activeId, bytes calldata hookData) external; + /// @notice Batches many liquidity modification calls to pool manager + /// @param payload is an encoding of actions, and parameters for those actions + /// @dev The payload is a byte array that represents the encoded form of the CallbackData struct + /// for example to add liquidity, the payload would be: + /// bytes[] memory payloadArray = new bytes[](1); + /// bytes memory addliquidityData = abi.encode(IBinFungiblePositionManager.CallbackData( + /// IBinFungiblePositionManager.CallbackDataType.AddLiquidity, abi.encode(IBinFungiblePositionManager.AddLiquidityParams({...})) + /// )) + /// payloadArray[0] = addliquidityData; + /// bytes memory payload = abi.encode(payloadArray); + /// @param deadline is the deadline for the batched actions to be executed + /// @return returnData is the endocing of each actions return information + function modifyLiquidities(bytes calldata payload, uint256 deadline) external payable returns (bytes[] memory); + /// @notice Add liquidity, user will receive ERC1155 tokens as receipt of bin share ownership. /// @dev The ID of the ERC11155 token is keccak256(abi.encode(poolkey.toId, binId)) /// @return amount0 Amount of token0 added From b904638b686a631c1f6608a04e8877733411edb0 Mon Sep 17 00:00:00 2001 From: Chef Snoopy Date: Tue, 6 Aug 2024 11:48:22 +0800 Subject: [PATCH 2/8] feat: Add _settleOrTake --- ...ddLiquidityOutsideActiveId_ExistingId.snap | 2 +- ...testAddLiquidityOutsideActiveId_NewId.snap | 2 +- ...dityTest#testAddLiquidityWithActiveId.snap | 2 +- ...testAddLiquidityWithActiveId_WithHook.snap | 2 +- ...oveLiquidityOutsideActiveId_ThreeBins.snap | 2 +- ...RemoveLiquidityWithActiveId_ThreeBins.snap | 2 +- ...iquidityTest#testRemoveLiquidity_Half.snap | 2 +- ...V2Test#testMigrateFromV2IncludingInit.snap | 2 +- ...apV2Test#testMigrateFromV2WithoutInit.snap | 2 +- ...t#testMigrateFromV2WithoutNativeToken.snap | 2 +- ...V3Test#testMigrateFromV3IncludingInit.snap | 2 +- ...apV3Test#testMigrateFromV3WithoutInit.snap | 2 +- ...t#testMigrateFromV3WithoutNativeToken.snap | 2 +- ...V2Test#testMigrateFromV2IncludingInit.snap | 2 +- ...apV2Test#testMigrateFromV2WithoutInit.snap | 2 +- ...t#testMigrateFromV2WithoutNativeToken.snap | 2 +- ...V3Test#testMigrateFromV3IncludingInit.snap | 2 +- ...apV3Test#testMigrateFromV3WithoutInit.snap | 2 +- ...t#testMigrateFromV3WithoutNativeToken.snap | 2 +- ...batchMintIncreaseAndDecreaseLiquidity.snap | 2 +- src/pool-bin/BinFungiblePositionManager.sol | 31 +++++++------------ 21 files changed, 32 insertions(+), 39 deletions(-) diff --git a/.forge-snapshots/BinFungiblePositionManager_AddLiquidityTest#testAddLiquidityOutsideActiveId_ExistingId.snap b/.forge-snapshots/BinFungiblePositionManager_AddLiquidityTest#testAddLiquidityOutsideActiveId_ExistingId.snap index f9564c9..235b49f 100644 --- a/.forge-snapshots/BinFungiblePositionManager_AddLiquidityTest#testAddLiquidityOutsideActiveId_ExistingId.snap +++ b/.forge-snapshots/BinFungiblePositionManager_AddLiquidityTest#testAddLiquidityOutsideActiveId_ExistingId.snap @@ -1 +1 @@ -181075 \ No newline at end of file +180967 \ No newline at end of file diff --git a/.forge-snapshots/BinFungiblePositionManager_AddLiquidityTest#testAddLiquidityOutsideActiveId_NewId.snap b/.forge-snapshots/BinFungiblePositionManager_AddLiquidityTest#testAddLiquidityOutsideActiveId_NewId.snap index 623566e..a9bb2a6 100644 --- a/.forge-snapshots/BinFungiblePositionManager_AddLiquidityTest#testAddLiquidityOutsideActiveId_NewId.snap +++ b/.forge-snapshots/BinFungiblePositionManager_AddLiquidityTest#testAddLiquidityOutsideActiveId_NewId.snap @@ -1 +1 @@ -635263 \ No newline at end of file +635155 \ No newline at end of file diff --git a/.forge-snapshots/BinFungiblePositionManager_AddLiquidityTest#testAddLiquidityWithActiveId.snap b/.forge-snapshots/BinFungiblePositionManager_AddLiquidityTest#testAddLiquidityWithActiveId.snap index 622aac6..a24d8f8 100644 --- a/.forge-snapshots/BinFungiblePositionManager_AddLiquidityTest#testAddLiquidityWithActiveId.snap +++ b/.forge-snapshots/BinFungiblePositionManager_AddLiquidityTest#testAddLiquidityWithActiveId.snap @@ -1 +1 @@ -902346 \ No newline at end of file +902071 \ No newline at end of file diff --git a/.forge-snapshots/BinFungiblePositionManager_AddLiquidityTest#testAddLiquidityWithActiveId_WithHook.snap b/.forge-snapshots/BinFungiblePositionManager_AddLiquidityTest#testAddLiquidityWithActiveId_WithHook.snap index 12dc6d8..fa44967 100644 --- a/.forge-snapshots/BinFungiblePositionManager_AddLiquidityTest#testAddLiquidityWithActiveId_WithHook.snap +++ b/.forge-snapshots/BinFungiblePositionManager_AddLiquidityTest#testAddLiquidityWithActiveId_WithHook.snap @@ -1 +1 @@ -1268770 \ No newline at end of file +1268495 \ No newline at end of file diff --git a/.forge-snapshots/BinFungiblePositionManager_RemoveLiquidityTest#testRemoveLiquidityOutsideActiveId_ThreeBins.snap b/.forge-snapshots/BinFungiblePositionManager_RemoveLiquidityTest#testRemoveLiquidityOutsideActiveId_ThreeBins.snap index cd6eb2c..973d926 100644 --- a/.forge-snapshots/BinFungiblePositionManager_RemoveLiquidityTest#testRemoveLiquidityOutsideActiveId_ThreeBins.snap +++ b/.forge-snapshots/BinFungiblePositionManager_RemoveLiquidityTest#testRemoveLiquidityOutsideActiveId_ThreeBins.snap @@ -1 +1 @@ -146776 \ No newline at end of file +146822 \ No newline at end of file diff --git a/.forge-snapshots/BinFungiblePositionManager_RemoveLiquidityTest#testRemoveLiquidityWithActiveId_ThreeBins.snap b/.forge-snapshots/BinFungiblePositionManager_RemoveLiquidityTest#testRemoveLiquidityWithActiveId_ThreeBins.snap index d279e99..464957b 100644 --- a/.forge-snapshots/BinFungiblePositionManager_RemoveLiquidityTest#testRemoveLiquidityWithActiveId_ThreeBins.snap +++ b/.forge-snapshots/BinFungiblePositionManager_RemoveLiquidityTest#testRemoveLiquidityWithActiveId_ThreeBins.snap @@ -1 +1 @@ -213159 \ No newline at end of file +213142 \ No newline at end of file diff --git a/.forge-snapshots/BinFungiblePositionManager_RemoveLiquidityTest#testRemoveLiquidity_Half.snap b/.forge-snapshots/BinFungiblePositionManager_RemoveLiquidityTest#testRemoveLiquidity_Half.snap index bf69b0d..ce4f8ab 100644 --- a/.forge-snapshots/BinFungiblePositionManager_RemoveLiquidityTest#testRemoveLiquidity_Half.snap +++ b/.forge-snapshots/BinFungiblePositionManager_RemoveLiquidityTest#testRemoveLiquidity_Half.snap @@ -1 +1 @@ -238274 \ No newline at end of file +238253 \ No newline at end of file diff --git a/.forge-snapshots/BinMigratorFromPancakeswapV2Test#testMigrateFromV2IncludingInit.snap b/.forge-snapshots/BinMigratorFromPancakeswapV2Test#testMigrateFromV2IncludingInit.snap index 2a10ace..6bd92fd 100644 --- a/.forge-snapshots/BinMigratorFromPancakeswapV2Test#testMigrateFromV2IncludingInit.snap +++ b/.forge-snapshots/BinMigratorFromPancakeswapV2Test#testMigrateFromV2IncludingInit.snap @@ -1 +1 @@ -1015374 \ No newline at end of file +1015212 \ No newline at end of file diff --git a/.forge-snapshots/BinMigratorFromPancakeswapV2Test#testMigrateFromV2WithoutInit.snap b/.forge-snapshots/BinMigratorFromPancakeswapV2Test#testMigrateFromV2WithoutInit.snap index d154ea6..fb9f350 100644 --- a/.forge-snapshots/BinMigratorFromPancakeswapV2Test#testMigrateFromV2WithoutInit.snap +++ b/.forge-snapshots/BinMigratorFromPancakeswapV2Test#testMigrateFromV2WithoutInit.snap @@ -1 +1 @@ -975551 \ No newline at end of file +975389 \ No newline at end of file diff --git a/.forge-snapshots/BinMigratorFromPancakeswapV2Test#testMigrateFromV2WithoutNativeToken.snap b/.forge-snapshots/BinMigratorFromPancakeswapV2Test#testMigrateFromV2WithoutNativeToken.snap index 29c271a..1f4231f 100644 --- a/.forge-snapshots/BinMigratorFromPancakeswapV2Test#testMigrateFromV2WithoutNativeToken.snap +++ b/.forge-snapshots/BinMigratorFromPancakeswapV2Test#testMigrateFromV2WithoutNativeToken.snap @@ -1 +1 @@ -1019806 \ No newline at end of file +1019531 \ No newline at end of file diff --git a/.forge-snapshots/BinMigratorFromPancakeswapV3Test#testMigrateFromV3IncludingInit.snap b/.forge-snapshots/BinMigratorFromPancakeswapV3Test#testMigrateFromV3IncludingInit.snap index c1e424f..aaadddd 100644 --- a/.forge-snapshots/BinMigratorFromPancakeswapV3Test#testMigrateFromV3IncludingInit.snap +++ b/.forge-snapshots/BinMigratorFromPancakeswapV3Test#testMigrateFromV3IncludingInit.snap @@ -1 +1 @@ -1094291 \ No newline at end of file +1094129 \ No newline at end of file diff --git a/.forge-snapshots/BinMigratorFromPancakeswapV3Test#testMigrateFromV3WithoutInit.snap b/.forge-snapshots/BinMigratorFromPancakeswapV3Test#testMigrateFromV3WithoutInit.snap index 0735420..1b60566 100644 --- a/.forge-snapshots/BinMigratorFromPancakeswapV3Test#testMigrateFromV3WithoutInit.snap +++ b/.forge-snapshots/BinMigratorFromPancakeswapV3Test#testMigrateFromV3WithoutInit.snap @@ -1 +1 @@ -1054520 \ No newline at end of file +1054358 \ No newline at end of file diff --git a/.forge-snapshots/BinMigratorFromPancakeswapV3Test#testMigrateFromV3WithoutNativeToken.snap b/.forge-snapshots/BinMigratorFromPancakeswapV3Test#testMigrateFromV3WithoutNativeToken.snap index 20d98ea..a5c66af 100644 --- a/.forge-snapshots/BinMigratorFromPancakeswapV3Test#testMigrateFromV3WithoutNativeToken.snap +++ b/.forge-snapshots/BinMigratorFromPancakeswapV3Test#testMigrateFromV3WithoutNativeToken.snap @@ -1 +1 @@ -1092155 \ No newline at end of file +1091880 \ No newline at end of file diff --git a/.forge-snapshots/BinMigratorFromUniswapV2Test#testMigrateFromV2IncludingInit.snap b/.forge-snapshots/BinMigratorFromUniswapV2Test#testMigrateFromV2IncludingInit.snap index bf40e69..0c79bf6 100644 --- a/.forge-snapshots/BinMigratorFromUniswapV2Test#testMigrateFromV2IncludingInit.snap +++ b/.forge-snapshots/BinMigratorFromUniswapV2Test#testMigrateFromV2IncludingInit.snap @@ -1 +1 @@ -1015386 \ No newline at end of file +1015224 \ No newline at end of file diff --git a/.forge-snapshots/BinMigratorFromUniswapV2Test#testMigrateFromV2WithoutInit.snap b/.forge-snapshots/BinMigratorFromUniswapV2Test#testMigrateFromV2WithoutInit.snap index 810f7a9..917cc84 100644 --- a/.forge-snapshots/BinMigratorFromUniswapV2Test#testMigrateFromV2WithoutInit.snap +++ b/.forge-snapshots/BinMigratorFromUniswapV2Test#testMigrateFromV2WithoutInit.snap @@ -1 +1 @@ -975563 \ No newline at end of file +975401 \ No newline at end of file diff --git a/.forge-snapshots/BinMigratorFromUniswapV2Test#testMigrateFromV2WithoutNativeToken.snap b/.forge-snapshots/BinMigratorFromUniswapV2Test#testMigrateFromV2WithoutNativeToken.snap index 734f9b9..5b2ca57 100644 --- a/.forge-snapshots/BinMigratorFromUniswapV2Test#testMigrateFromV2WithoutNativeToken.snap +++ b/.forge-snapshots/BinMigratorFromUniswapV2Test#testMigrateFromV2WithoutNativeToken.snap @@ -1 +1 @@ -1019803 \ No newline at end of file +1019528 \ No newline at end of file diff --git a/.forge-snapshots/BinMigratorFromUniswapV3Test#testMigrateFromV3IncludingInit.snap b/.forge-snapshots/BinMigratorFromUniswapV3Test#testMigrateFromV3IncludingInit.snap index 8083e83..ce7c78a 100644 --- a/.forge-snapshots/BinMigratorFromUniswapV3Test#testMigrateFromV3IncludingInit.snap +++ b/.forge-snapshots/BinMigratorFromUniswapV3Test#testMigrateFromV3IncludingInit.snap @@ -1 +1 @@ -1092273 \ No newline at end of file +1092111 \ No newline at end of file diff --git a/.forge-snapshots/BinMigratorFromUniswapV3Test#testMigrateFromV3WithoutInit.snap b/.forge-snapshots/BinMigratorFromUniswapV3Test#testMigrateFromV3WithoutInit.snap index f31f146..e5ecbea 100644 --- a/.forge-snapshots/BinMigratorFromUniswapV3Test#testMigrateFromV3WithoutInit.snap +++ b/.forge-snapshots/BinMigratorFromUniswapV3Test#testMigrateFromV3WithoutInit.snap @@ -1 +1 @@ -1052502 \ No newline at end of file +1052340 \ No newline at end of file diff --git a/.forge-snapshots/BinMigratorFromUniswapV3Test#testMigrateFromV3WithoutNativeToken.snap b/.forge-snapshots/BinMigratorFromUniswapV3Test#testMigrateFromV3WithoutNativeToken.snap index f6d976a..0d7d7ce 100644 --- a/.forge-snapshots/BinMigratorFromUniswapV3Test#testMigrateFromV3WithoutNativeToken.snap +++ b/.forge-snapshots/BinMigratorFromUniswapV3Test#testMigrateFromV3WithoutNativeToken.snap @@ -1 +1 @@ -1090133 \ No newline at end of file +1089858 \ No newline at end of file diff --git a/.forge-snapshots/NonFungiblePositionManagerBatch#batchMintIncreaseAndDecreaseLiquidity.snap b/.forge-snapshots/NonFungiblePositionManagerBatch#batchMintIncreaseAndDecreaseLiquidity.snap index f697a1a..1c15b0a 100644 --- a/.forge-snapshots/NonFungiblePositionManagerBatch#batchMintIncreaseAndDecreaseLiquidity.snap +++ b/.forge-snapshots/NonFungiblePositionManagerBatch#batchMintIncreaseAndDecreaseLiquidity.snap @@ -1 +1 @@ -718653 \ No newline at end of file +718725 \ No newline at end of file diff --git a/src/pool-bin/BinFungiblePositionManager.sol b/src/pool-bin/BinFungiblePositionManager.sol index 14e7b0f..1d4fac4 100644 --- a/src/pool-bin/BinFungiblePositionManager.sol +++ b/src/pool-bin/BinFungiblePositionManager.sol @@ -292,27 +292,20 @@ contract BinFungiblePositionManager is /// @notice Transfer token from user to vault. If the currency is native, assume ETH is on contract /// @param user If delta.amt > 0, take amt from user. else if delta.amt < 0, transfer amt to user function _settleDeltas(address user, PoolKey memory poolKey, BalanceDelta delta) internal { - if (delta.amount0() > 0) { - vault.take(poolKey.currency0, user, uint128(delta.amount0())); - } else if (delta.amount0() < 0) { - if (poolKey.currency0.isNative()) { - vault.settle{value: uint256(int256(-delta.amount0()))}(poolKey.currency0); - } else { - vault.sync(poolKey.currency0); - pay(poolKey.currency0, user, address(vault), uint256(int256(-delta.amount0()))); - vault.settle(poolKey.currency0); - } - } + _settleOrTake(poolKey.currency0, user, delta.amount0()); + _settleOrTake(poolKey.currency1, user, delta.amount1()); + } - if (delta.amount1() > 0) { - vault.take(poolKey.currency1, user, uint128(delta.amount1())); - } else if (delta.amount1() < 0) { - if (poolKey.currency1.isNative()) { - vault.settle{value: uint256(int256(-delta.amount1()))}(poolKey.currency1); + function _settleOrTake(Currency currency, address sender, int128 amount) internal { + if (amount > 0) { + vault.take(currency, sender, uint128(amount)); + } else if (amount < 0) { + if (currency.isNative()) { + vault.settle{value: uint256(int256(-amount))}(currency); } else { - vault.sync(poolKey.currency1); - pay(poolKey.currency1, user, address(vault), uint256(int256(-delta.amount1()))); - vault.settle(poolKey.currency1); + vault.sync(currency); + pay(currency, sender, address(vault), uint256(int256(-amount))); + vault.settle(currency); } } } From f23c9a9b64b92a15da7a4d48f4d4987b191efd02 Mon Sep 17 00:00:00 2001 From: Chef Snoopy Date: Tue, 6 Aug 2024 11:58:09 +0800 Subject: [PATCH 3/8] feat: Add CloseCurrency --- src/pool-bin/BinFungiblePositionManager.sol | 20 +++++++++++++++++++ .../IBinFungiblePositionManager.sol | 3 ++- 2 files changed, 22 insertions(+), 1 deletion(-) diff --git a/src/pool-bin/BinFungiblePositionManager.sol b/src/pool-bin/BinFungiblePositionManager.sol index 1d4fac4..eca6e1a 100644 --- a/src/pool-bin/BinFungiblePositionManager.sol +++ b/src/pool-bin/BinFungiblePositionManager.sol @@ -170,6 +170,8 @@ contract BinFungiblePositionManager is return _handleIncreaseLiquidity(data, sender, shouldSettle); } else if (data.callbackDataType == CallbackDataType.RemoveLiquidity) { return _handleDecreaseLiquidity(data, sender, shouldSettle); + } else if (data.callbackDataType == CallbackDataType.CloseCurrency) { + return _close(data.params, sender); } else { revert InvalidCalldataType(); } @@ -289,6 +291,24 @@ contract BinFungiblePositionManager is return abi.encode(delta.amount0(), delta.amount1(), tokenIds); } + /// @param params is an encoding of the Currency to close + /// @param sender is the msg.sender encoded by the `modifyLiquidities` function before the `lockAcquired`. + /// @return an encoding of int256 the balance of the currency being settled by this call + function _close(bytes memory params, address sender) internal returns (bytes memory) { + (Currency currency) = abi.decode(params, (Currency)); + // this address has applied all deltas on behalf of the user/owner + // it is safe to close this entire delta because of slippage checks throughout the batched calls. + int256 currencyDelta = vault.currencyDelta(address(this), currency); + + _settleOrTake(currency, sender, int128(currencyDelta)); + // if there are native tokens left over after settling, return to sender + if (address(this).balance > 0 && currency.isNative()) { + CurrencyLibrary.NATIVE.transfer(sender, address(this).balance); + } + + return abi.encode(currencyDelta); + } + /// @notice Transfer token from user to vault. If the currency is native, assume ETH is on contract /// @param user If delta.amt > 0, take amt from user. else if delta.amt < 0, transfer amt to user function _settleDeltas(address user, PoolKey memory poolKey, BalanceDelta delta) internal { diff --git a/src/pool-bin/interfaces/IBinFungiblePositionManager.sol b/src/pool-bin/interfaces/IBinFungiblePositionManager.sol index 0e3dccc..63cdd2d 100644 --- a/src/pool-bin/interfaces/IBinFungiblePositionManager.sol +++ b/src/pool-bin/interfaces/IBinFungiblePositionManager.sol @@ -73,7 +73,8 @@ interface IBinFungiblePositionManager is IBinFungibleToken, IPeripheryPayments, enum CallbackDataType { AddLiquidity, - RemoveLiquidity + RemoveLiquidity, + CloseCurrency } struct CallbackData { From 65da89498266d6a0d9bb2fac9fa2f8def1222d8a Mon Sep 17 00:00:00 2001 From: Chef Snoopy Date: Tue, 6 Aug 2024 13:41:58 +0800 Subject: [PATCH 4/8] feat: Remove CallbackData sender --- ...idityTest#testAddLiquidityOutsideActiveId_ExistingId.snap | 2 +- ...dLiquidityTest#testAddLiquidityOutsideActiveId_NewId.snap | 2 +- ...anager_AddLiquidityTest#testAddLiquidityWithActiveId.snap | 2 +- ...dLiquidityTest#testAddLiquidityWithActiveId_WithHook.snap | 2 +- ...ityTest#testRemoveLiquidityOutsideActiveId_ThreeBins.snap | 2 +- ...uidityTest#testRemoveLiquidityWithActiveId_ThreeBins.snap | 2 +- ...Manager_RemoveLiquidityTest#testRemoveLiquidity_Half.snap | 2 +- ...FromPancakeswapV2Test#testMigrateFromV2IncludingInit.snap | 2 +- ...orFromPancakeswapV2Test#testMigrateFromV2WithoutInit.snap | 2 +- ...ancakeswapV2Test#testMigrateFromV2WithoutNativeToken.snap | 2 +- ...FromPancakeswapV3Test#testMigrateFromV3IncludingInit.snap | 2 +- ...orFromPancakeswapV3Test#testMigrateFromV3WithoutInit.snap | 2 +- ...ancakeswapV3Test#testMigrateFromV3WithoutNativeToken.snap | 2 +- ...atorFromUniswapV2Test#testMigrateFromV2IncludingInit.snap | 2 +- ...gratorFromUniswapV2Test#testMigrateFromV2WithoutInit.snap | 2 +- ...romUniswapV2Test#testMigrateFromV2WithoutNativeToken.snap | 2 +- ...atorFromUniswapV3Test#testMigrateFromV3IncludingInit.snap | 2 +- ...gratorFromUniswapV3Test#testMigrateFromV3WithoutInit.snap | 2 +- ...romUniswapV3Test#testMigrateFromV3WithoutNativeToken.snap | 2 +- ...onManagerBatch#batchMintIncreaseAndDecreaseLiquidity.snap | 2 +- src/pool-bin/BinFungiblePositionManager.sol | 5 ++--- src/pool-bin/interfaces/IBinFungiblePositionManager.sol | 1 - 22 files changed, 22 insertions(+), 24 deletions(-) diff --git a/.forge-snapshots/BinFungiblePositionManager_AddLiquidityTest#testAddLiquidityOutsideActiveId_ExistingId.snap b/.forge-snapshots/BinFungiblePositionManager_AddLiquidityTest#testAddLiquidityOutsideActiveId_ExistingId.snap index 235b49f..82372ae 100644 --- a/.forge-snapshots/BinFungiblePositionManager_AddLiquidityTest#testAddLiquidityOutsideActiveId_ExistingId.snap +++ b/.forge-snapshots/BinFungiblePositionManager_AddLiquidityTest#testAddLiquidityOutsideActiveId_ExistingId.snap @@ -1 +1 @@ -180967 \ No newline at end of file +180746 \ No newline at end of file diff --git a/.forge-snapshots/BinFungiblePositionManager_AddLiquidityTest#testAddLiquidityOutsideActiveId_NewId.snap b/.forge-snapshots/BinFungiblePositionManager_AddLiquidityTest#testAddLiquidityOutsideActiveId_NewId.snap index a9bb2a6..d38e295 100644 --- a/.forge-snapshots/BinFungiblePositionManager_AddLiquidityTest#testAddLiquidityOutsideActiveId_NewId.snap +++ b/.forge-snapshots/BinFungiblePositionManager_AddLiquidityTest#testAddLiquidityOutsideActiveId_NewId.snap @@ -1 +1 @@ -635155 \ No newline at end of file +634934 \ No newline at end of file diff --git a/.forge-snapshots/BinFungiblePositionManager_AddLiquidityTest#testAddLiquidityWithActiveId.snap b/.forge-snapshots/BinFungiblePositionManager_AddLiquidityTest#testAddLiquidityWithActiveId.snap index a24d8f8..7766b2d 100644 --- a/.forge-snapshots/BinFungiblePositionManager_AddLiquidityTest#testAddLiquidityWithActiveId.snap +++ b/.forge-snapshots/BinFungiblePositionManager_AddLiquidityTest#testAddLiquidityWithActiveId.snap @@ -1 +1 @@ -902071 \ No newline at end of file +901854 \ No newline at end of file diff --git a/.forge-snapshots/BinFungiblePositionManager_AddLiquidityTest#testAddLiquidityWithActiveId_WithHook.snap b/.forge-snapshots/BinFungiblePositionManager_AddLiquidityTest#testAddLiquidityWithActiveId_WithHook.snap index fa44967..b7b33cd 100644 --- a/.forge-snapshots/BinFungiblePositionManager_AddLiquidityTest#testAddLiquidityWithActiveId_WithHook.snap +++ b/.forge-snapshots/BinFungiblePositionManager_AddLiquidityTest#testAddLiquidityWithActiveId_WithHook.snap @@ -1 +1 @@ -1268495 \ No newline at end of file +1268280 \ No newline at end of file diff --git a/.forge-snapshots/BinFungiblePositionManager_RemoveLiquidityTest#testRemoveLiquidityOutsideActiveId_ThreeBins.snap b/.forge-snapshots/BinFungiblePositionManager_RemoveLiquidityTest#testRemoveLiquidityOutsideActiveId_ThreeBins.snap index 973d926..f61c076 100644 --- a/.forge-snapshots/BinFungiblePositionManager_RemoveLiquidityTest#testRemoveLiquidityOutsideActiveId_ThreeBins.snap +++ b/.forge-snapshots/BinFungiblePositionManager_RemoveLiquidityTest#testRemoveLiquidityOutsideActiveId_ThreeBins.snap @@ -1 +1 @@ -146822 \ No newline at end of file +146632 \ No newline at end of file diff --git a/.forge-snapshots/BinFungiblePositionManager_RemoveLiquidityTest#testRemoveLiquidityWithActiveId_ThreeBins.snap b/.forge-snapshots/BinFungiblePositionManager_RemoveLiquidityTest#testRemoveLiquidityWithActiveId_ThreeBins.snap index 464957b..c8a01a5 100644 --- a/.forge-snapshots/BinFungiblePositionManager_RemoveLiquidityTest#testRemoveLiquidityWithActiveId_ThreeBins.snap +++ b/.forge-snapshots/BinFungiblePositionManager_RemoveLiquidityTest#testRemoveLiquidityWithActiveId_ThreeBins.snap @@ -1 +1 @@ -213142 \ No newline at end of file +212950 \ No newline at end of file diff --git a/.forge-snapshots/BinFungiblePositionManager_RemoveLiquidityTest#testRemoveLiquidity_Half.snap b/.forge-snapshots/BinFungiblePositionManager_RemoveLiquidityTest#testRemoveLiquidity_Half.snap index ce4f8ab..95e39a6 100644 --- a/.forge-snapshots/BinFungiblePositionManager_RemoveLiquidityTest#testRemoveLiquidity_Half.snap +++ b/.forge-snapshots/BinFungiblePositionManager_RemoveLiquidityTest#testRemoveLiquidity_Half.snap @@ -1 +1 @@ -238253 \ No newline at end of file +238013 \ No newline at end of file diff --git a/.forge-snapshots/BinMigratorFromPancakeswapV2Test#testMigrateFromV2IncludingInit.snap b/.forge-snapshots/BinMigratorFromPancakeswapV2Test#testMigrateFromV2IncludingInit.snap index 6bd92fd..e2a7b36 100644 --- a/.forge-snapshots/BinMigratorFromPancakeswapV2Test#testMigrateFromV2IncludingInit.snap +++ b/.forge-snapshots/BinMigratorFromPancakeswapV2Test#testMigrateFromV2IncludingInit.snap @@ -1 +1 @@ -1015212 \ No newline at end of file +1014995 \ No newline at end of file diff --git a/.forge-snapshots/BinMigratorFromPancakeswapV2Test#testMigrateFromV2WithoutInit.snap b/.forge-snapshots/BinMigratorFromPancakeswapV2Test#testMigrateFromV2WithoutInit.snap index fb9f350..84b1106 100644 --- a/.forge-snapshots/BinMigratorFromPancakeswapV2Test#testMigrateFromV2WithoutInit.snap +++ b/.forge-snapshots/BinMigratorFromPancakeswapV2Test#testMigrateFromV2WithoutInit.snap @@ -1 +1 @@ -975389 \ No newline at end of file +975172 \ No newline at end of file diff --git a/.forge-snapshots/BinMigratorFromPancakeswapV2Test#testMigrateFromV2WithoutNativeToken.snap b/.forge-snapshots/BinMigratorFromPancakeswapV2Test#testMigrateFromV2WithoutNativeToken.snap index 1f4231f..47fc4e0 100644 --- a/.forge-snapshots/BinMigratorFromPancakeswapV2Test#testMigrateFromV2WithoutNativeToken.snap +++ b/.forge-snapshots/BinMigratorFromPancakeswapV2Test#testMigrateFromV2WithoutNativeToken.snap @@ -1 +1 @@ -1019531 \ No newline at end of file +1019314 \ No newline at end of file diff --git a/.forge-snapshots/BinMigratorFromPancakeswapV3Test#testMigrateFromV3IncludingInit.snap b/.forge-snapshots/BinMigratorFromPancakeswapV3Test#testMigrateFromV3IncludingInit.snap index aaadddd..20dc1cd 100644 --- a/.forge-snapshots/BinMigratorFromPancakeswapV3Test#testMigrateFromV3IncludingInit.snap +++ b/.forge-snapshots/BinMigratorFromPancakeswapV3Test#testMigrateFromV3IncludingInit.snap @@ -1 +1 @@ -1094129 \ No newline at end of file +1093912 \ No newline at end of file diff --git a/.forge-snapshots/BinMigratorFromPancakeswapV3Test#testMigrateFromV3WithoutInit.snap b/.forge-snapshots/BinMigratorFromPancakeswapV3Test#testMigrateFromV3WithoutInit.snap index 1b60566..b4a253d 100644 --- a/.forge-snapshots/BinMigratorFromPancakeswapV3Test#testMigrateFromV3WithoutInit.snap +++ b/.forge-snapshots/BinMigratorFromPancakeswapV3Test#testMigrateFromV3WithoutInit.snap @@ -1 +1 @@ -1054358 \ No newline at end of file +1054141 \ No newline at end of file diff --git a/.forge-snapshots/BinMigratorFromPancakeswapV3Test#testMigrateFromV3WithoutNativeToken.snap b/.forge-snapshots/BinMigratorFromPancakeswapV3Test#testMigrateFromV3WithoutNativeToken.snap index a5c66af..d5a1a58 100644 --- a/.forge-snapshots/BinMigratorFromPancakeswapV3Test#testMigrateFromV3WithoutNativeToken.snap +++ b/.forge-snapshots/BinMigratorFromPancakeswapV3Test#testMigrateFromV3WithoutNativeToken.snap @@ -1 +1 @@ -1091880 \ No newline at end of file +1091663 \ No newline at end of file diff --git a/.forge-snapshots/BinMigratorFromUniswapV2Test#testMigrateFromV2IncludingInit.snap b/.forge-snapshots/BinMigratorFromUniswapV2Test#testMigrateFromV2IncludingInit.snap index 0c79bf6..d926551 100644 --- a/.forge-snapshots/BinMigratorFromUniswapV2Test#testMigrateFromV2IncludingInit.snap +++ b/.forge-snapshots/BinMigratorFromUniswapV2Test#testMigrateFromV2IncludingInit.snap @@ -1 +1 @@ -1015224 \ No newline at end of file +1015007 \ No newline at end of file diff --git a/.forge-snapshots/BinMigratorFromUniswapV2Test#testMigrateFromV2WithoutInit.snap b/.forge-snapshots/BinMigratorFromUniswapV2Test#testMigrateFromV2WithoutInit.snap index 917cc84..ba15138 100644 --- a/.forge-snapshots/BinMigratorFromUniswapV2Test#testMigrateFromV2WithoutInit.snap +++ b/.forge-snapshots/BinMigratorFromUniswapV2Test#testMigrateFromV2WithoutInit.snap @@ -1 +1 @@ -975401 \ No newline at end of file +975184 \ No newline at end of file diff --git a/.forge-snapshots/BinMigratorFromUniswapV2Test#testMigrateFromV2WithoutNativeToken.snap b/.forge-snapshots/BinMigratorFromUniswapV2Test#testMigrateFromV2WithoutNativeToken.snap index 5b2ca57..b612303 100644 --- a/.forge-snapshots/BinMigratorFromUniswapV2Test#testMigrateFromV2WithoutNativeToken.snap +++ b/.forge-snapshots/BinMigratorFromUniswapV2Test#testMigrateFromV2WithoutNativeToken.snap @@ -1 +1 @@ -1019528 \ No newline at end of file +1019311 \ No newline at end of file diff --git a/.forge-snapshots/BinMigratorFromUniswapV3Test#testMigrateFromV3IncludingInit.snap b/.forge-snapshots/BinMigratorFromUniswapV3Test#testMigrateFromV3IncludingInit.snap index ce7c78a..5c1a552 100644 --- a/.forge-snapshots/BinMigratorFromUniswapV3Test#testMigrateFromV3IncludingInit.snap +++ b/.forge-snapshots/BinMigratorFromUniswapV3Test#testMigrateFromV3IncludingInit.snap @@ -1 +1 @@ -1092111 \ No newline at end of file +1091894 \ No newline at end of file diff --git a/.forge-snapshots/BinMigratorFromUniswapV3Test#testMigrateFromV3WithoutInit.snap b/.forge-snapshots/BinMigratorFromUniswapV3Test#testMigrateFromV3WithoutInit.snap index e5ecbea..5480947 100644 --- a/.forge-snapshots/BinMigratorFromUniswapV3Test#testMigrateFromV3WithoutInit.snap +++ b/.forge-snapshots/BinMigratorFromUniswapV3Test#testMigrateFromV3WithoutInit.snap @@ -1 +1 @@ -1052340 \ No newline at end of file +1052123 \ No newline at end of file diff --git a/.forge-snapshots/BinMigratorFromUniswapV3Test#testMigrateFromV3WithoutNativeToken.snap b/.forge-snapshots/BinMigratorFromUniswapV3Test#testMigrateFromV3WithoutNativeToken.snap index 0d7d7ce..7849af6 100644 --- a/.forge-snapshots/BinMigratorFromUniswapV3Test#testMigrateFromV3WithoutNativeToken.snap +++ b/.forge-snapshots/BinMigratorFromUniswapV3Test#testMigrateFromV3WithoutNativeToken.snap @@ -1 +1 @@ -1089858 \ No newline at end of file +1089641 \ No newline at end of file diff --git a/.forge-snapshots/NonFungiblePositionManagerBatch#batchMintIncreaseAndDecreaseLiquidity.snap b/.forge-snapshots/NonFungiblePositionManagerBatch#batchMintIncreaseAndDecreaseLiquidity.snap index 1c15b0a..f697a1a 100644 --- a/.forge-snapshots/NonFungiblePositionManagerBatch#batchMintIncreaseAndDecreaseLiquidity.snap +++ b/.forge-snapshots/NonFungiblePositionManagerBatch#batchMintIncreaseAndDecreaseLiquidity.snap @@ -1 +1 @@ -718725 \ No newline at end of file +718653 \ No newline at end of file diff --git a/src/pool-bin/BinFungiblePositionManager.sol b/src/pool-bin/BinFungiblePositionManager.sol index eca6e1a..128a178 100644 --- a/src/pool-bin/BinFungiblePositionManager.sol +++ b/src/pool-bin/BinFungiblePositionManager.sol @@ -104,8 +104,7 @@ contract BinFungiblePositionManager is checkDeadline(params.deadline) returns (uint128 amount0, uint128 amount1, uint256[] memory tokenIds, uint256[] memory liquidityMinted) { - bytes memory addLiquidityData = - abi.encode(CallbackData(msg.sender, CallbackDataType.AddLiquidity, abi.encode(params))); + bytes memory addLiquidityData = abi.encode(CallbackData(CallbackDataType.AddLiquidity, abi.encode(params))); (amount0, amount1, tokenIds, liquidityMinted) = abi.decode( vault.lock(abi.encode(msg.sender, true, addLiquidityData)), (uint128, uint128, uint256[], uint256[]) @@ -128,7 +127,7 @@ contract BinFungiblePositionManager is ) { bytes memory removeLiquidityData = - abi.encode(CallbackData(msg.sender, CallbackDataType.RemoveLiquidity, abi.encode(params))); + abi.encode(CallbackData(CallbackDataType.RemoveLiquidity, abi.encode(params))); (amount0, amount1, tokenIds) = abi.decode(vault.lock(abi.encode(msg.sender, true, removeLiquidityData)), (uint128, uint128, uint256[])); diff --git a/src/pool-bin/interfaces/IBinFungiblePositionManager.sol b/src/pool-bin/interfaces/IBinFungiblePositionManager.sol index 63cdd2d..b7f771f 100644 --- a/src/pool-bin/interfaces/IBinFungiblePositionManager.sol +++ b/src/pool-bin/interfaces/IBinFungiblePositionManager.sol @@ -78,7 +78,6 @@ interface IBinFungiblePositionManager is IBinFungibleToken, IPeripheryPayments, } struct CallbackData { - address sender; CallbackDataType callbackDataType; bytes params; } From e5acfba67b33ea25d4963a2503564b85da831ad6 Mon Sep 17 00:00:00 2001 From: Chef Snoopy Date: Tue, 6 Aug 2024 15:22:23 +0800 Subject: [PATCH 5/8] feat: Add batch test cases --- ...ddLiquidityOutsideActiveId_ExistingId.snap | 2 +- ...testAddLiquidityOutsideActiveId_NewId.snap | 2 +- ...dityTest#testAddLiquidityWithActiveId.snap | 2 +- ...testAddLiquidityWithActiveId_WithHook.snap | 2 +- ...st#testBatch_AddLiquidityWithActiveId.snap | 1 + ...dityWithActiveId_WithoutCloseCurrency.snap | 1 + ...RemoveLiquidityWithActiveId_ThreeBins.snap | 1 + ...tiveId_ThreeBins_WithoutCloseCurrency.snap | 1 + ...oveLiquidityOutsideActiveId_ThreeBins.snap | 2 +- ...RemoveLiquidityWithActiveId_ThreeBins.snap | 2 +- ...iquidityTest#testRemoveLiquidity_Half.snap | 2 +- ...V2Test#testMigrateFromV2IncludingInit.snap | 2 +- ...apV2Test#testMigrateFromV2WithoutInit.snap | 2 +- ...t#testMigrateFromV2WithoutNativeToken.snap | 2 +- ...V3Test#testMigrateFromV3IncludingInit.snap | 2 +- ...apV3Test#testMigrateFromV3WithoutInit.snap | 2 +- ...t#testMigrateFromV3WithoutNativeToken.snap | 2 +- ...V2Test#testMigrateFromV2IncludingInit.snap | 2 +- ...apV2Test#testMigrateFromV2WithoutInit.snap | 2 +- ...t#testMigrateFromV2WithoutNativeToken.snap | 2 +- ...V3Test#testMigrateFromV3IncludingInit.snap | 2 +- ...apV3Test#testMigrateFromV3WithoutInit.snap | 2 +- ...t#testMigrateFromV3WithoutNativeToken.snap | 2 +- src/pool-bin/BinFungiblePositionManager.sol | 7 +- ...FungiblePositionManager_AddLiquidity.t.sol | 131 +++++++++++++++++ ...giblePositionManager_RemoveLiquidity.t.sol | 133 ++++++++++++++++++ 26 files changed, 290 insertions(+), 23 deletions(-) create mode 100644 .forge-snapshots/BinFungiblePositionManager_AddLiquidityTest#testBatch_AddLiquidityWithActiveId.snap create mode 100644 .forge-snapshots/BinFungiblePositionManager_AddLiquidityTest#testBatch_AddLiquidityWithActiveId_WithoutCloseCurrency.snap create mode 100644 .forge-snapshots/BinFungiblePositionManager_RemoveLiquidityTest#testBatch_RemoveLiquidityWithActiveId_ThreeBins.snap create mode 100644 .forge-snapshots/BinFungiblePositionManager_RemoveLiquidityTest#testBatch_RemoveLiquidityWithActiveId_ThreeBins_WithoutCloseCurrency.snap diff --git a/.forge-snapshots/BinFungiblePositionManager_AddLiquidityTest#testAddLiquidityOutsideActiveId_ExistingId.snap b/.forge-snapshots/BinFungiblePositionManager_AddLiquidityTest#testAddLiquidityOutsideActiveId_ExistingId.snap index 82372ae..a9358fb 100644 --- a/.forge-snapshots/BinFungiblePositionManager_AddLiquidityTest#testAddLiquidityOutsideActiveId_ExistingId.snap +++ b/.forge-snapshots/BinFungiblePositionManager_AddLiquidityTest#testAddLiquidityOutsideActiveId_ExistingId.snap @@ -1 +1 @@ -180746 \ No newline at end of file +180763 \ No newline at end of file diff --git a/.forge-snapshots/BinFungiblePositionManager_AddLiquidityTest#testAddLiquidityOutsideActiveId_NewId.snap b/.forge-snapshots/BinFungiblePositionManager_AddLiquidityTest#testAddLiquidityOutsideActiveId_NewId.snap index d38e295..1acd896 100644 --- a/.forge-snapshots/BinFungiblePositionManager_AddLiquidityTest#testAddLiquidityOutsideActiveId_NewId.snap +++ b/.forge-snapshots/BinFungiblePositionManager_AddLiquidityTest#testAddLiquidityOutsideActiveId_NewId.snap @@ -1 +1 @@ -634934 \ No newline at end of file +634951 \ No newline at end of file diff --git a/.forge-snapshots/BinFungiblePositionManager_AddLiquidityTest#testAddLiquidityWithActiveId.snap b/.forge-snapshots/BinFungiblePositionManager_AddLiquidityTest#testAddLiquidityWithActiveId.snap index 7766b2d..c9f3d61 100644 --- a/.forge-snapshots/BinFungiblePositionManager_AddLiquidityTest#testAddLiquidityWithActiveId.snap +++ b/.forge-snapshots/BinFungiblePositionManager_AddLiquidityTest#testAddLiquidityWithActiveId.snap @@ -1 +1 @@ -901854 \ No newline at end of file +901871 \ No newline at end of file diff --git a/.forge-snapshots/BinFungiblePositionManager_AddLiquidityTest#testAddLiquidityWithActiveId_WithHook.snap b/.forge-snapshots/BinFungiblePositionManager_AddLiquidityTest#testAddLiquidityWithActiveId_WithHook.snap index b7b33cd..eec9f9c 100644 --- a/.forge-snapshots/BinFungiblePositionManager_AddLiquidityTest#testAddLiquidityWithActiveId_WithHook.snap +++ b/.forge-snapshots/BinFungiblePositionManager_AddLiquidityTest#testAddLiquidityWithActiveId_WithHook.snap @@ -1 +1 @@ -1268280 \ No newline at end of file +1268297 \ No newline at end of file diff --git a/.forge-snapshots/BinFungiblePositionManager_AddLiquidityTest#testBatch_AddLiquidityWithActiveId.snap b/.forge-snapshots/BinFungiblePositionManager_AddLiquidityTest#testBatch_AddLiquidityWithActiveId.snap new file mode 100644 index 0000000..625ea06 --- /dev/null +++ b/.forge-snapshots/BinFungiblePositionManager_AddLiquidityTest#testBatch_AddLiquidityWithActiveId.snap @@ -0,0 +1 @@ +913834 \ No newline at end of file diff --git a/.forge-snapshots/BinFungiblePositionManager_AddLiquidityTest#testBatch_AddLiquidityWithActiveId_WithoutCloseCurrency.snap b/.forge-snapshots/BinFungiblePositionManager_AddLiquidityTest#testBatch_AddLiquidityWithActiveId_WithoutCloseCurrency.snap new file mode 100644 index 0000000..9b19ffa --- /dev/null +++ b/.forge-snapshots/BinFungiblePositionManager_AddLiquidityTest#testBatch_AddLiquidityWithActiveId_WithoutCloseCurrency.snap @@ -0,0 +1 @@ +900913 \ No newline at end of file diff --git a/.forge-snapshots/BinFungiblePositionManager_RemoveLiquidityTest#testBatch_RemoveLiquidityWithActiveId_ThreeBins.snap b/.forge-snapshots/BinFungiblePositionManager_RemoveLiquidityTest#testBatch_RemoveLiquidityWithActiveId_ThreeBins.snap new file mode 100644 index 0000000..aab0943 --- /dev/null +++ b/.forge-snapshots/BinFungiblePositionManager_RemoveLiquidityTest#testBatch_RemoveLiquidityWithActiveId_ThreeBins.snap @@ -0,0 +1 @@ +222821 \ No newline at end of file diff --git a/.forge-snapshots/BinFungiblePositionManager_RemoveLiquidityTest#testBatch_RemoveLiquidityWithActiveId_ThreeBins_WithoutCloseCurrency.snap b/.forge-snapshots/BinFungiblePositionManager_RemoveLiquidityTest#testBatch_RemoveLiquidityWithActiveId_ThreeBins_WithoutCloseCurrency.snap new file mode 100644 index 0000000..2351ca1 --- /dev/null +++ b/.forge-snapshots/BinFungiblePositionManager_RemoveLiquidityTest#testBatch_RemoveLiquidityWithActiveId_ThreeBins_WithoutCloseCurrency.snap @@ -0,0 +1 @@ +212335 \ No newline at end of file diff --git a/.forge-snapshots/BinFungiblePositionManager_RemoveLiquidityTest#testRemoveLiquidityOutsideActiveId_ThreeBins.snap b/.forge-snapshots/BinFungiblePositionManager_RemoveLiquidityTest#testRemoveLiquidityOutsideActiveId_ThreeBins.snap index f61c076..9157a60 100644 --- a/.forge-snapshots/BinFungiblePositionManager_RemoveLiquidityTest#testRemoveLiquidityOutsideActiveId_ThreeBins.snap +++ b/.forge-snapshots/BinFungiblePositionManager_RemoveLiquidityTest#testRemoveLiquidityOutsideActiveId_ThreeBins.snap @@ -1 +1 @@ -146632 \ No newline at end of file +146615 \ No newline at end of file diff --git a/.forge-snapshots/BinFungiblePositionManager_RemoveLiquidityTest#testRemoveLiquidityWithActiveId_ThreeBins.snap b/.forge-snapshots/BinFungiblePositionManager_RemoveLiquidityTest#testRemoveLiquidityWithActiveId_ThreeBins.snap index c8a01a5..455caf8 100644 --- a/.forge-snapshots/BinFungiblePositionManager_RemoveLiquidityTest#testRemoveLiquidityWithActiveId_ThreeBins.snap +++ b/.forge-snapshots/BinFungiblePositionManager_RemoveLiquidityTest#testRemoveLiquidityWithActiveId_ThreeBins.snap @@ -1 +1 @@ -212950 \ No newline at end of file +212997 \ No newline at end of file diff --git a/.forge-snapshots/BinFungiblePositionManager_RemoveLiquidityTest#testRemoveLiquidity_Half.snap b/.forge-snapshots/BinFungiblePositionManager_RemoveLiquidityTest#testRemoveLiquidity_Half.snap index 95e39a6..c581290 100644 --- a/.forge-snapshots/BinFungiblePositionManager_RemoveLiquidityTest#testRemoveLiquidity_Half.snap +++ b/.forge-snapshots/BinFungiblePositionManager_RemoveLiquidityTest#testRemoveLiquidity_Half.snap @@ -1 +1 @@ -238013 \ No newline at end of file +238072 \ No newline at end of file diff --git a/.forge-snapshots/BinMigratorFromPancakeswapV2Test#testMigrateFromV2IncludingInit.snap b/.forge-snapshots/BinMigratorFromPancakeswapV2Test#testMigrateFromV2IncludingInit.snap index e2a7b36..ae48b9d 100644 --- a/.forge-snapshots/BinMigratorFromPancakeswapV2Test#testMigrateFromV2IncludingInit.snap +++ b/.forge-snapshots/BinMigratorFromPancakeswapV2Test#testMigrateFromV2IncludingInit.snap @@ -1 +1 @@ -1014995 \ No newline at end of file +1015012 \ No newline at end of file diff --git a/.forge-snapshots/BinMigratorFromPancakeswapV2Test#testMigrateFromV2WithoutInit.snap b/.forge-snapshots/BinMigratorFromPancakeswapV2Test#testMigrateFromV2WithoutInit.snap index 84b1106..a107e50 100644 --- a/.forge-snapshots/BinMigratorFromPancakeswapV2Test#testMigrateFromV2WithoutInit.snap +++ b/.forge-snapshots/BinMigratorFromPancakeswapV2Test#testMigrateFromV2WithoutInit.snap @@ -1 +1 @@ -975172 \ No newline at end of file +975189 \ No newline at end of file diff --git a/.forge-snapshots/BinMigratorFromPancakeswapV2Test#testMigrateFromV2WithoutNativeToken.snap b/.forge-snapshots/BinMigratorFromPancakeswapV2Test#testMigrateFromV2WithoutNativeToken.snap index 47fc4e0..a56e8ef 100644 --- a/.forge-snapshots/BinMigratorFromPancakeswapV2Test#testMigrateFromV2WithoutNativeToken.snap +++ b/.forge-snapshots/BinMigratorFromPancakeswapV2Test#testMigrateFromV2WithoutNativeToken.snap @@ -1 +1 @@ -1019314 \ No newline at end of file +1019331 \ No newline at end of file diff --git a/.forge-snapshots/BinMigratorFromPancakeswapV3Test#testMigrateFromV3IncludingInit.snap b/.forge-snapshots/BinMigratorFromPancakeswapV3Test#testMigrateFromV3IncludingInit.snap index 20dc1cd..9419c2c 100644 --- a/.forge-snapshots/BinMigratorFromPancakeswapV3Test#testMigrateFromV3IncludingInit.snap +++ b/.forge-snapshots/BinMigratorFromPancakeswapV3Test#testMigrateFromV3IncludingInit.snap @@ -1 +1 @@ -1093912 \ No newline at end of file +1093929 \ No newline at end of file diff --git a/.forge-snapshots/BinMigratorFromPancakeswapV3Test#testMigrateFromV3WithoutInit.snap b/.forge-snapshots/BinMigratorFromPancakeswapV3Test#testMigrateFromV3WithoutInit.snap index b4a253d..519008d 100644 --- a/.forge-snapshots/BinMigratorFromPancakeswapV3Test#testMigrateFromV3WithoutInit.snap +++ b/.forge-snapshots/BinMigratorFromPancakeswapV3Test#testMigrateFromV3WithoutInit.snap @@ -1 +1 @@ -1054141 \ No newline at end of file +1054158 \ No newline at end of file diff --git a/.forge-snapshots/BinMigratorFromPancakeswapV3Test#testMigrateFromV3WithoutNativeToken.snap b/.forge-snapshots/BinMigratorFromPancakeswapV3Test#testMigrateFromV3WithoutNativeToken.snap index d5a1a58..470caf1 100644 --- a/.forge-snapshots/BinMigratorFromPancakeswapV3Test#testMigrateFromV3WithoutNativeToken.snap +++ b/.forge-snapshots/BinMigratorFromPancakeswapV3Test#testMigrateFromV3WithoutNativeToken.snap @@ -1 +1 @@ -1091663 \ No newline at end of file +1091680 \ No newline at end of file diff --git a/.forge-snapshots/BinMigratorFromUniswapV2Test#testMigrateFromV2IncludingInit.snap b/.forge-snapshots/BinMigratorFromUniswapV2Test#testMigrateFromV2IncludingInit.snap index d926551..fa8f09c 100644 --- a/.forge-snapshots/BinMigratorFromUniswapV2Test#testMigrateFromV2IncludingInit.snap +++ b/.forge-snapshots/BinMigratorFromUniswapV2Test#testMigrateFromV2IncludingInit.snap @@ -1 +1 @@ -1015007 \ No newline at end of file +1015024 \ No newline at end of file diff --git a/.forge-snapshots/BinMigratorFromUniswapV2Test#testMigrateFromV2WithoutInit.snap b/.forge-snapshots/BinMigratorFromUniswapV2Test#testMigrateFromV2WithoutInit.snap index ba15138..89c1d69 100644 --- a/.forge-snapshots/BinMigratorFromUniswapV2Test#testMigrateFromV2WithoutInit.snap +++ b/.forge-snapshots/BinMigratorFromUniswapV2Test#testMigrateFromV2WithoutInit.snap @@ -1 +1 @@ -975184 \ No newline at end of file +975201 \ No newline at end of file diff --git a/.forge-snapshots/BinMigratorFromUniswapV2Test#testMigrateFromV2WithoutNativeToken.snap b/.forge-snapshots/BinMigratorFromUniswapV2Test#testMigrateFromV2WithoutNativeToken.snap index b612303..62bd2d2 100644 --- a/.forge-snapshots/BinMigratorFromUniswapV2Test#testMigrateFromV2WithoutNativeToken.snap +++ b/.forge-snapshots/BinMigratorFromUniswapV2Test#testMigrateFromV2WithoutNativeToken.snap @@ -1 +1 @@ -1019311 \ No newline at end of file +1019328 \ No newline at end of file diff --git a/.forge-snapshots/BinMigratorFromUniswapV3Test#testMigrateFromV3IncludingInit.snap b/.forge-snapshots/BinMigratorFromUniswapV3Test#testMigrateFromV3IncludingInit.snap index 5c1a552..6fb4eb7 100644 --- a/.forge-snapshots/BinMigratorFromUniswapV3Test#testMigrateFromV3IncludingInit.snap +++ b/.forge-snapshots/BinMigratorFromUniswapV3Test#testMigrateFromV3IncludingInit.snap @@ -1 +1 @@ -1091894 \ No newline at end of file +1091911 \ No newline at end of file diff --git a/.forge-snapshots/BinMigratorFromUniswapV3Test#testMigrateFromV3WithoutInit.snap b/.forge-snapshots/BinMigratorFromUniswapV3Test#testMigrateFromV3WithoutInit.snap index 5480947..d1a3ed9 100644 --- a/.forge-snapshots/BinMigratorFromUniswapV3Test#testMigrateFromV3WithoutInit.snap +++ b/.forge-snapshots/BinMigratorFromUniswapV3Test#testMigrateFromV3WithoutInit.snap @@ -1 +1 @@ -1052123 \ No newline at end of file +1052140 \ No newline at end of file diff --git a/.forge-snapshots/BinMigratorFromUniswapV3Test#testMigrateFromV3WithoutNativeToken.snap b/.forge-snapshots/BinMigratorFromUniswapV3Test#testMigrateFromV3WithoutNativeToken.snap index 7849af6..e5d8727 100644 --- a/.forge-snapshots/BinMigratorFromUniswapV3Test#testMigrateFromV3WithoutNativeToken.snap +++ b/.forge-snapshots/BinMigratorFromUniswapV3Test#testMigrateFromV3WithoutNativeToken.snap @@ -1 +1 @@ -1089641 \ No newline at end of file +1089658 \ No newline at end of file diff --git a/src/pool-bin/BinFungiblePositionManager.sol b/src/pool-bin/BinFungiblePositionManager.sol index 128a178..59f7f1d 100644 --- a/src/pool-bin/BinFungiblePositionManager.sol +++ b/src/pool-bin/BinFungiblePositionManager.sol @@ -109,8 +109,6 @@ contract BinFungiblePositionManager is (amount0, amount1, tokenIds, liquidityMinted) = abi.decode( vault.lock(abi.encode(msg.sender, true, addLiquidityData)), (uint128, uint128, uint256[], uint256[]) ); - - emit TransferBatch(msg.sender, address(0), params.to, tokenIds, liquidityMinted); } /// @inheritdoc IBinFungiblePositionManager @@ -131,8 +129,6 @@ contract BinFungiblePositionManager is (amount0, amount1, tokenIds) = abi.decode(vault.lock(abi.encode(msg.sender, true, removeLiquidityData)), (uint128, uint128, uint256[])); - - emit TransferBatch(msg.sender, params.from, address(0), tokenIds, params.amounts); } function lockAcquired(bytes calldata rawData) external override returns (bytes memory returnData) { @@ -249,6 +245,8 @@ contract BinFungiblePositionManager is } } + emit TransferBatch(sender, address(0), params.to, tokenIds, mintArray.liquidityMinted); + return abi.encode(uint128(-delta.amount0()), uint128(-delta.amount1()), tokenIds, mintArray.liquidityMinted); } @@ -286,6 +284,7 @@ contract BinFungiblePositionManager is ++i; } } + emit TransferBatch(sender, params.from, address(0), tokenIds, params.amounts); return abi.encode(delta.amount0(), delta.amount1(), tokenIds); } diff --git a/test/pool-bin/BinFungiblePositionManager_AddLiquidity.t.sol b/test/pool-bin/BinFungiblePositionManager_AddLiquidity.t.sol index 116f26d..012692f 100644 --- a/test/pool-bin/BinFungiblePositionManager_AddLiquidity.t.sol +++ b/test/pool-bin/BinFungiblePositionManager_AddLiquidity.t.sol @@ -327,6 +327,137 @@ contract BinFungiblePositionManager_AddLiquidityTest is Test, GasSnapshot, Liqui } } + function testBatch_AddLiquidityWithActiveId_WithoutCloseCurrency() public { + // pre-test, verify alice has 1e18 token0 and token1 + token0.mint(alice, 1 ether); + token1.mint(alice, 1 ether); + assertEq(token0.balanceOf(alice), 1 ether); + assertEq(token1.balanceOf(alice), 1 ether); + + vm.startPrank(alice); + uint24[] memory binIds = getBinIds(activeId, 3); + IBinFungiblePositionManager.AddLiquidityParams memory params; + params = _getAddParams(key1, binIds, 1 ether, 1 ether, activeId, alice); + + // Expect emitted events + uint256[] memory liquidityMinted = new uint256[](binIds.length); + bytes32 binReserves = PackedUint128Math.encode(0, 0); // binReserve=0 for new pool + liquidityMinted[0] = calculateLiquidityMinted(binReserves, 0 ether, 0.5 ether, binIds[0], 10, 0); + liquidityMinted[1] = calculateLiquidityMinted(binReserves, 0.5 ether, 0.5 ether, binIds[1], 10, 0); + liquidityMinted[2] = calculateLiquidityMinted(binReserves, 0.5 ether, 0 ether, binIds[2], 10, 0); + uint256[] memory tokenIds = new uint256[](binIds.length); + for (uint256 i; i < binIds.length; i++) { + tokenIds[i] = key1.toId().toTokenId(binIds[i]); + } + vm.expectEmit(); + emit TransferBatch(alice, address(0), alice, tokenIds, liquidityMinted); + + // generate modifyLiquidities payload + bytes[] memory payloadArray = new bytes[](1); + bytes memory addliquidityData = abi.encode( + IBinFungiblePositionManager.CallbackData( + IBinFungiblePositionManager.CallbackDataType.AddLiquidity, abi.encode(params) + ) + ); + payloadArray[0] = addliquidityData; + bytes memory payload = abi.encode(payloadArray); + + // amt0, amt1 = total amt0/amt1 from addLiquidity -- 660207 - + snapStart("BinFungiblePositionManager_AddLiquidityTest#testBatch_AddLiquidityWithActiveId_WithoutCloseCurrency"); + bytes[] memory returnDataArrayBytes = binFungiblePositionManager.modifyLiquidities(payload, block.timestamp + 1); + snapEnd(); + (uint128 amt0, uint128 amt1, uint256[] memory _tokenIds, uint256[] memory _liquidityMinted) = + abi.decode(returnDataArrayBytes[0], (uint128, uint128, uint256[], uint256[])); + + // verify token taken from alice + assertEq(amt0, 1 ether); + assertEq(amt1, 1 ether); + assertEq(token0.balanceOf(alice), 0); + assertEq(token1.balanceOf(alice), 0); + + for (uint256 i; i < binIds.length; i++) { + // verify nft minted to user + uint256 balance = binFungiblePositionManager.balanceOf(alice, tokenIds[i]); + assertEq(balance, _liquidityMinted[i]); + assertGt(balance, 0); + + // verify return value from addLiquidity + assertEq(tokenIds[i], _tokenIds[i]); + } + } + + function testBatch_AddLiquidityWithActiveId() public { + // pre-test, verify alice has 1e18 token0 and token1 + token0.mint(alice, 1 ether); + token1.mint(alice, 1 ether); + assertEq(token0.balanceOf(alice), 1 ether); + assertEq(token1.balanceOf(alice), 1 ether); + + vm.startPrank(alice); + uint24[] memory binIds = getBinIds(activeId, 3); + IBinFungiblePositionManager.AddLiquidityParams memory params; + params = _getAddParams(key1, binIds, 1 ether, 1 ether, activeId, alice); + + // Expect emitted events + uint256[] memory liquidityMinted = new uint256[](binIds.length); + bytes32 binReserves = PackedUint128Math.encode(0, 0); // binReserve=0 for new pool + liquidityMinted[0] = calculateLiquidityMinted(binReserves, 0 ether, 0.5 ether, binIds[0], 10, 0); + liquidityMinted[1] = calculateLiquidityMinted(binReserves, 0.5 ether, 0.5 ether, binIds[1], 10, 0); + liquidityMinted[2] = calculateLiquidityMinted(binReserves, 0.5 ether, 0 ether, binIds[2], 10, 0); + uint256[] memory tokenIds = new uint256[](binIds.length); + for (uint256 i; i < binIds.length; i++) { + tokenIds[i] = key1.toId().toTokenId(binIds[i]); + } + vm.expectEmit(); + emit TransferBatch(alice, address(0), alice, tokenIds, liquidityMinted); + + // generate modifyLiquidities payload + bytes[] memory payloadArray = new bytes[](3); + bytes memory addliquidityData = abi.encode( + IBinFungiblePositionManager.CallbackData( + IBinFungiblePositionManager.CallbackDataType.AddLiquidity, abi.encode(params) + ) + ); + payloadArray[0] = addliquidityData; + + // set current close data + payloadArray[1] = abi.encode( + IBinFungiblePositionManager.CallbackData( + IBinFungiblePositionManager.CallbackDataType.CloseCurrency, abi.encode(key1.currency0) + ) + ); + payloadArray[2] = abi.encode( + IBinFungiblePositionManager.CallbackData( + IBinFungiblePositionManager.CallbackDataType.CloseCurrency, abi.encode(currency1) + ) + ); + + bytes memory payload = abi.encode(payloadArray); + + // amt0, amt1 = total amt0/amt1 from addLiquidity -- 660207 - + snapStart("BinFungiblePositionManager_AddLiquidityTest#testBatch_AddLiquidityWithActiveId"); + bytes[] memory returnDataArrayBytes = binFungiblePositionManager.modifyLiquidities(payload, block.timestamp + 1); + snapEnd(); + (uint128 amt0, uint128 amt1, uint256[] memory _tokenIds, uint256[] memory _liquidityMinted) = + abi.decode(returnDataArrayBytes[0], (uint128, uint128, uint256[], uint256[])); + + // verify token taken from alice + assertEq(amt0, 1 ether); + assertEq(amt1, 1 ether); + assertEq(token0.balanceOf(alice), 0); + assertEq(token1.balanceOf(alice), 0); + + for (uint256 i; i < binIds.length; i++) { + // verify nft minted to user + uint256 balance = binFungiblePositionManager.balanceOf(alice, tokenIds[i]); + assertEq(balance, _liquidityMinted[i]); + assertGt(balance, 0); + + // verify return value from addLiquidity + assertEq(tokenIds[i], _tokenIds[i]); + } + } + function testAddLiquidityOutsideActiveId() public { // add at the left side, so all tokenY token1.mint(alice, 2 ether); diff --git a/test/pool-bin/BinFungiblePositionManager_RemoveLiquidity.t.sol b/test/pool-bin/BinFungiblePositionManager_RemoveLiquidity.t.sol index ae6896e..be3a663 100644 --- a/test/pool-bin/BinFungiblePositionManager_RemoveLiquidity.t.sol +++ b/test/pool-bin/BinFungiblePositionManager_RemoveLiquidity.t.sol @@ -217,6 +217,139 @@ contract BinFungiblePositionManager_RemoveLiquidityTest is Test, GasSnapshot, Li } } + function testBatch_RemoveLiquidityWithActiveId_ThreeBins_WithoutCloseCurrency() public { + vm.startPrank(alice); + uint24[] memory binIds = getBinIds(activeId, 3); + + // Pre-req: Add liquidity, 1 eth on each side + token0.mint(alice, 1 ether); + token1.mint(alice, 1 ether); + addParams = _getAddParams(key1, binIds, 1 ether, 1 ether, activeId, alice); + (,, uint256[] memory tokenIdsMinted, uint256[] memory liquidityMinted) = + binFungiblePositionManager.addLiquidity(addParams); + + // check token/nft balance of alice + assertEq(token0.balanceOf(alice), 0); + assertEq(token1.balanceOf(alice), 0); + for (uint256 i; i < tokenIdsMinted.length; i++) { + assertEq(key1.toId().toTokenId(binIds[i]), tokenIdsMinted[i]); + assertEq(binFungiblePositionManager.balanceOf(alice, tokenIdsMinted[i]), liquidityMinted[i]); + assertGt(liquidityMinted[i], 0); + } + + // Expect emitted events + uint256[] memory _tokenIds = new uint256[](binIds.length); + for (uint256 i; i < binIds.length; i++) { + _tokenIds[i] = key1.toId().toTokenId(binIds[i]); + } + vm.expectEmit(); + emit TransferBatch(alice, alice, address(0), _tokenIds, liquidityMinted); + + // remove liquidity + removeParams = _getRemoveParams(key1, binIds, liquidityMinted); + + // generate modifyLiquidities data + bytes[] memory payloadArray = new bytes[](1); + bytes memory removeLiquidityData = abi.encode( + IBinFungiblePositionManager.CallbackData( + IBinFungiblePositionManager.CallbackDataType.RemoveLiquidity, abi.encode(removeParams) + ) + ); + payloadArray[0] = removeLiquidityData; + bytes memory payload = abi.encode(payloadArray); + + snapStart( + "BinFungiblePositionManager_RemoveLiquidityTest#testBatch_RemoveLiquidityWithActiveId_ThreeBins_WithoutCloseCurrency" + ); + bytes[] memory returnDataArrayBytes = binFungiblePositionManager.modifyLiquidities(payload, block.timestamp + 1); + snapEnd(); + + (uint128 amt0, uint128 amt1, uint256[] memory tokenIdsBurnt) = + abi.decode(returnDataArrayBytes[0], (uint128, uint128, uint256[])); + + // check token/nft balance of alice + assertEq(amt0, 1 ether); + assertEq(amt1, 1 ether); + assertEq(token0.balanceOf(alice), amt0); + assertEq(token1.balanceOf(alice), amt1); + for (uint256 i; i < tokenIdsMinted.length; i++) { + assertEq(tokenIdsMinted[i], tokenIdsBurnt[i]); + assertEq(binFungiblePositionManager.balanceOf(alice, tokenIdsMinted[i]), 0); + } + } + + function testBatch_RemoveLiquidityWithActiveId_ThreeBins() public { + vm.startPrank(alice); + uint24[] memory binIds = getBinIds(activeId, 3); + + // Pre-req: Add liquidity, 1 eth on each side + token0.mint(alice, 1 ether); + token1.mint(alice, 1 ether); + addParams = _getAddParams(key1, binIds, 1 ether, 1 ether, activeId, alice); + (,, uint256[] memory tokenIdsMinted, uint256[] memory liquidityMinted) = + binFungiblePositionManager.addLiquidity(addParams); + + // check token/nft balance of alice + assertEq(token0.balanceOf(alice), 0); + assertEq(token1.balanceOf(alice), 0); + for (uint256 i; i < tokenIdsMinted.length; i++) { + assertEq(key1.toId().toTokenId(binIds[i]), tokenIdsMinted[i]); + assertEq(binFungiblePositionManager.balanceOf(alice, tokenIdsMinted[i]), liquidityMinted[i]); + assertGt(liquidityMinted[i], 0); + } + + // Expect emitted events + uint256[] memory _tokenIds = new uint256[](binIds.length); + for (uint256 i; i < binIds.length; i++) { + _tokenIds[i] = key1.toId().toTokenId(binIds[i]); + } + vm.expectEmit(); + emit TransferBatch(alice, alice, address(0), _tokenIds, liquidityMinted); + + // remove liquidity + removeParams = _getRemoveParams(key1, binIds, liquidityMinted); + + // generate modifyLiquidities data + bytes[] memory payloadArray = new bytes[](3); + bytes memory removeLiquidityData = abi.encode( + IBinFungiblePositionManager.CallbackData( + IBinFungiblePositionManager.CallbackDataType.RemoveLiquidity, abi.encode(removeParams) + ) + ); + payloadArray[0] = removeLiquidityData; + + // set current close data + payloadArray[1] = abi.encode( + IBinFungiblePositionManager.CallbackData( + IBinFungiblePositionManager.CallbackDataType.CloseCurrency, abi.encode(key1.currency0) + ) + ); + payloadArray[2] = abi.encode( + IBinFungiblePositionManager.CallbackData( + IBinFungiblePositionManager.CallbackDataType.CloseCurrency, abi.encode(currency1) + ) + ); + + bytes memory payload = abi.encode(payloadArray); + + snapStart("BinFungiblePositionManager_RemoveLiquidityTest#testBatch_RemoveLiquidityWithActiveId_ThreeBins"); + bytes[] memory returnDataArrayBytes = binFungiblePositionManager.modifyLiquidities(payload, block.timestamp + 1); + snapEnd(); + + (uint128 amt0, uint128 amt1, uint256[] memory tokenIdsBurnt) = + abi.decode(returnDataArrayBytes[0], (uint128, uint128, uint256[])); + + // check token/nft balance of alice + assertEq(amt0, 1 ether); + assertEq(amt1, 1 ether); + assertEq(token0.balanceOf(alice), amt0); + assertEq(token1.balanceOf(alice), amt1); + for (uint256 i; i < tokenIdsMinted.length; i++) { + assertEq(tokenIdsMinted[i], tokenIdsBurnt[i]); + assertEq(binFungiblePositionManager.balanceOf(alice, tokenIdsMinted[i]), 0); + } + } + function testRemoveLiquidity_Half() public { vm.startPrank(alice); uint24[] memory binIds = getBinIds(activeId, 3); From 4556e271bc8d711a05c31cd3a35a1868f2c77356 Mon Sep 17 00:00:00 2001 From: Chef Snoopy Date: Tue, 6 Aug 2024 15:34:53 +0800 Subject: [PATCH 6/8] feat: Remove comments --- src/pool-bin/BinFungiblePositionManager.sol | 1 - 1 file changed, 1 deletion(-) diff --git a/src/pool-bin/BinFungiblePositionManager.sol b/src/pool-bin/BinFungiblePositionManager.sol index 59f7f1d..3695afc 100644 --- a/src/pool-bin/BinFungiblePositionManager.sol +++ b/src/pool-bin/BinFungiblePositionManager.sol @@ -118,7 +118,6 @@ contract BinFungiblePositionManager is override checkDeadline(params.deadline) returns ( - // checkApproval(params.from, msg.sender) uint128 amount0, uint128 amount1, uint256[] memory tokenIds From 152725a70449d5460773fc0acb543ac8c96da698 Mon Sep 17 00:00:00 2001 From: Chef Snoopy Date: Tue, 6 Aug 2024 15:37:52 +0800 Subject: [PATCH 7/8] feat: Format codes --- src/pool-bin/BinFungiblePositionManager.sol | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/pool-bin/BinFungiblePositionManager.sol b/src/pool-bin/BinFungiblePositionManager.sol index 3695afc..c284bd4 100644 --- a/src/pool-bin/BinFungiblePositionManager.sol +++ b/src/pool-bin/BinFungiblePositionManager.sol @@ -117,11 +117,7 @@ contract BinFungiblePositionManager is payable override checkDeadline(params.deadline) - returns ( - uint128 amount0, - uint128 amount1, - uint256[] memory tokenIds - ) + returns (uint128 amount0, uint128 amount1, uint256[] memory tokenIds) { bytes memory removeLiquidityData = abi.encode(CallbackData(CallbackDataType.RemoveLiquidity, abi.encode(params))); From 90b38da24301a0e8e5f4292ef7b01148cbf3c4a9 Mon Sep 17 00:00:00 2001 From: Chef Snoopy Date: Tue, 6 Aug 2024 15:56:13 +0800 Subject: [PATCH 8/8] feat: Remove modifier checkApproval --- src/pool-bin/BinFungibleToken.sol | 7 ------- 1 file changed, 7 deletions(-) diff --git a/src/pool-bin/BinFungibleToken.sol b/src/pool-bin/BinFungibleToken.sol index a499890..819aab2 100644 --- a/src/pool-bin/BinFungibleToken.sol +++ b/src/pool-bin/BinFungibleToken.sol @@ -22,13 +22,6 @@ abstract contract BinFungibleToken is IBinFungibleToken { mapping(address => mapping(address => bool)) public isApprovedForAll; /// @notice Revert if "spender" is not approved to spend "from" token - modifier checkApproval(address from, address spender) { - if (!(spender == from || isApprovedForAll[from][spender])) { - revert BinFungibleToken_SpenderNotApproved(from, spender); - } - _; - } - function _checkApproval(address from, address spender) internal view { if (!(spender == from || isApprovedForAll[from][spender])) { revert BinFungibleToken_SpenderNotApproved(from, spender);