From 10c67a33712e247b463b384eb441ab4a67427aa7 Mon Sep 17 00:00:00 2001 From: dianakocsis Date: Fri, 2 Aug 2024 12:39:39 -0400 Subject: [PATCH 1/4] clean --- ...er_increaseLiquidity_erc20_withClose.snap} | 0 ...ncreaseLiquidity_erc20_withSettlePair.snap | 1 + .../PositionManager_mint_nativeWithSweep.snap | 1 - ...anager_mint_nativeWithSweep_withClose.snap | 1 + ...r_mint_nativeWithSweep_withSettlePair.snap | 1 + ...nManager_mint_settleWithBalance_sweep.snap | 2 +- ...ap => PositionManager_mint_withClose.snap} | 0 .../PositionManager_mint_withSettlePair.snap | 1 + src/PositionManager.sol | 10 ++ src/libraries/Actions.sol | 10 +- src/libraries/CalldataDecoder.sol | 8 ++ test/libraries/CalldataDecoder.t.sol | 8 ++ test/mocks/MockCalldataDecoder.sol | 4 + test/position-managers/Execute.t.sol | 40 ++++++- .../position-managers/IncreaseLiquidity.t.sol | 2 +- test/position-managers/NativeToken.t.sol | 101 +++++++++++++++++- .../PositionManager.gas.t.sol | 93 ++++++++++++---- .../PositionManager.multicall.t.sol | 2 +- test/shared/LiquidityOperations.sol | 10 +- test/shared/Planner.sol | 7 +- test/shared/fuzz/LiquidityFuzzers.sol | 2 +- 21 files changed, 260 insertions(+), 44 deletions(-) rename .forge-snapshots/{PositionManager_increaseLiquidity_erc20.snap => PositionManager_increaseLiquidity_erc20_withClose.snap} (100%) create mode 100644 .forge-snapshots/PositionManager_increaseLiquidity_erc20_withSettlePair.snap delete mode 100644 .forge-snapshots/PositionManager_mint_nativeWithSweep.snap create mode 100644 .forge-snapshots/PositionManager_mint_nativeWithSweep_withClose.snap create mode 100644 .forge-snapshots/PositionManager_mint_nativeWithSweep_withSettlePair.snap rename .forge-snapshots/{PositionManager_mint.snap => PositionManager_mint_withClose.snap} (100%) create mode 100644 .forge-snapshots/PositionManager_mint_withSettlePair.snap diff --git a/.forge-snapshots/PositionManager_increaseLiquidity_erc20.snap b/.forge-snapshots/PositionManager_increaseLiquidity_erc20_withClose.snap similarity index 100% rename from .forge-snapshots/PositionManager_increaseLiquidity_erc20.snap rename to .forge-snapshots/PositionManager_increaseLiquidity_erc20_withClose.snap diff --git a/.forge-snapshots/PositionManager_increaseLiquidity_erc20_withSettlePair.snap b/.forge-snapshots/PositionManager_increaseLiquidity_erc20_withSettlePair.snap new file mode 100644 index 000000000..6ce3534b4 --- /dev/null +++ b/.forge-snapshots/PositionManager_increaseLiquidity_erc20_withSettlePair.snap @@ -0,0 +1 @@ +151341 \ No newline at end of file diff --git a/.forge-snapshots/PositionManager_mint_nativeWithSweep.snap b/.forge-snapshots/PositionManager_mint_nativeWithSweep.snap deleted file mode 100644 index 15689f38b..000000000 --- a/.forge-snapshots/PositionManager_mint_nativeWithSweep.snap +++ /dev/null @@ -1 +0,0 @@ -345244 \ No newline at end of file diff --git a/.forge-snapshots/PositionManager_mint_nativeWithSweep_withClose.snap b/.forge-snapshots/PositionManager_mint_nativeWithSweep_withClose.snap new file mode 100644 index 000000000..378d9bfb1 --- /dev/null +++ b/.forge-snapshots/PositionManager_mint_nativeWithSweep_withClose.snap @@ -0,0 +1 @@ +345267 \ No newline at end of file diff --git a/.forge-snapshots/PositionManager_mint_nativeWithSweep_withSettlePair.snap b/.forge-snapshots/PositionManager_mint_nativeWithSweep_withSettlePair.snap new file mode 100644 index 000000000..9f308f43c --- /dev/null +++ b/.forge-snapshots/PositionManager_mint_nativeWithSweep_withSettlePair.snap @@ -0,0 +1 @@ +344532 \ No newline at end of file diff --git a/.forge-snapshots/PositionManager_mint_settleWithBalance_sweep.snap b/.forge-snapshots/PositionManager_mint_settleWithBalance_sweep.snap index a6459af08..817d77abd 100644 --- a/.forge-snapshots/PositionManager_mint_settleWithBalance_sweep.snap +++ b/.forge-snapshots/PositionManager_mint_settleWithBalance_sweep.snap @@ -1 +1 @@ -370018 \ No newline at end of file +370064 \ No newline at end of file diff --git a/.forge-snapshots/PositionManager_mint.snap b/.forge-snapshots/PositionManager_mint_withClose.snap similarity index 100% rename from .forge-snapshots/PositionManager_mint.snap rename to .forge-snapshots/PositionManager_mint_withClose.snap diff --git a/.forge-snapshots/PositionManager_mint_withSettlePair.snap b/.forge-snapshots/PositionManager_mint_withSettlePair.snap new file mode 100644 index 000000000..99ea27ab7 --- /dev/null +++ b/.forge-snapshots/PositionManager_mint_withSettlePair.snap @@ -0,0 +1 @@ +371253 \ No newline at end of file diff --git a/src/PositionManager.sol b/src/PositionManager.sol index 43cafe544..285493f5f 100644 --- a/src/PositionManager.sol +++ b/src/PositionManager.sol @@ -127,6 +127,9 @@ contract PositionManager is } else if (action == Actions.SETTLE_WITH_BALANCE) { Currency currency = params.decodeCurrency(); _settleWithBalance(currency); + } else if (action == Actions.SETTLE_PAIR) { + (Currency currency0, Currency currency1) = params.decodeCurrencyPair(); + _settlePair(currency0, currency1); } else if (action == Actions.SWEEP) { (Currency currency, address to) = params.decodeCurrencyAndAddress(); _sweep(currency, to); @@ -221,6 +224,13 @@ contract PositionManager is _settle(currency, address(this), _getFullSettleAmount(currency)); } + function _settlePair(Currency currency0, Currency currency1) internal { + // the locker is the payer when settling + address caller = _msgSender(); + _settle(currency0, caller, _getFullSettleAmount(currency0)); + _settle(currency1, caller, _getFullSettleAmount(currency1)); + } + /// @dev this is overloaded with ERC721Permit._burn function _burn( uint256 tokenId, diff --git a/src/libraries/Actions.sol b/src/libraries/Actions.sol index 132fde68a..b60f3095e 100644 --- a/src/libraries/Actions.sol +++ b/src/libraries/Actions.sol @@ -23,17 +23,17 @@ library Actions { uint256 constant SETTLE = 0x10; uint256 constant SETTLE_ALL = 0x11; uint256 constant SETTLE_WITH_BALANCE = 0x12; + uint256 constant SETTLE_PAIR = 0x13; // taking uint256 constant TAKE = 0x13; uint256 constant TAKE_ALL = 0x14; uint256 constant TAKE_PORTION = 0x15; uint256 constant CLOSE_CURRENCY = 0x16; - uint256 constant CLOSE_PAIR = 0x17; - uint256 constant CLEAR = 0x18; - uint256 constant SWEEP = 0x19; + uint256 constant CLEAR = 0x17; + uint256 constant SWEEP = 0x18; // minting/burning 6909s to close deltas - uint256 constant MINT_6909 = 0x20; - uint256 constant BURN_6909 = 0x21; + uint256 constant MINT_6909 = 0x19; + uint256 constant BURN_6909 = 0x20; } diff --git a/src/libraries/CalldataDecoder.sol b/src/libraries/CalldataDecoder.sol index 11ba49d4c..6c48685d2 100644 --- a/src/libraries/CalldataDecoder.sol +++ b/src/libraries/CalldataDecoder.sol @@ -117,6 +117,14 @@ library CalldataDecoder { } } + /// @dev equivalent to: abi.decode(params, (Currency, Currency)) in calldata + function decodeCurrencyPair(bytes calldata params) internal pure returns (Currency currency0, Currency currency1) { + assembly ("memory-safe") { + currency0 := calldataload(params.offset) + currency1 := calldataload(add(params.offset, 0x20)) + } + } + /// @dev equivalent to: abi.decode(params, (Currency, address)) in calldata function decodeCurrencyAndAddress(bytes calldata params) internal diff --git a/test/libraries/CalldataDecoder.t.sol b/test/libraries/CalldataDecoder.t.sol index bfc9c08e3..04bb82ff0 100644 --- a/test/libraries/CalldataDecoder.t.sol +++ b/test/libraries/CalldataDecoder.t.sol @@ -98,6 +98,14 @@ contract CalldataDecoderTest is Test { assertEq(Currency.unwrap(currency), Currency.unwrap(_currency)); } + function test_fuzz_decodeCurrencyPair(Currency _currency0, Currency _currency1) public view { + bytes memory params = abi.encode(_currency0, _currency1); + (Currency currency0, Currency currency1) = decoder.decodeCurrencyPair(params); + + assertEq(Currency.unwrap(currency0), Currency.unwrap(_currency0)); + assertEq(Currency.unwrap(currency1), Currency.unwrap(_currency1)); + } + function test_fuzz_decodeCurrencyAndUint256(Currency _currency, uint256 _amount) public view { bytes memory params = abi.encode(_currency, _amount); (Currency currency, uint256 amount) = decoder.decodeCurrencyAndUint256(params); diff --git a/test/mocks/MockCalldataDecoder.sol b/test/mocks/MockCalldataDecoder.sol index b60bd7077..b57a0aa58 100644 --- a/test/mocks/MockCalldataDecoder.sol +++ b/test/mocks/MockCalldataDecoder.sol @@ -65,6 +65,10 @@ contract MockCalldataDecoder { return params.decodeCurrency(); } + function decodeCurrencyPair(bytes calldata params) external pure returns (Currency currency0, Currency currency1) { + return params.decodeCurrencyPair(); + } + function decodeCurrencyAndUint256(bytes calldata params) external pure returns (Currency currency, uint256 _uint) { return params.decodeCurrencyAndUint256(); } diff --git a/test/position-managers/Execute.t.sol b/test/position-managers/Execute.t.sol index d75f3ac75..792359273 100644 --- a/test/position-managers/Execute.t.sol +++ b/test/position-managers/Execute.t.sol @@ -78,7 +78,7 @@ contract ExecuteTest is Test, PosmTestSetup, LiquidityFuzzers { assertEq(liquidity, initialLiquidity + liquidityToAdd); } - function test_fuzz_execute_increaseLiquidity_twice( + function test_fuzz_execute_increaseLiquidity_twice_withClose( uint256 initialLiquidity, uint256 liquidityToAdd, uint256 liquidityToAdd2 @@ -100,7 +100,39 @@ contract ExecuteTest is Test, PosmTestSetup, LiquidityFuzzers { abi.encode(tokenId, config, liquidityToAdd2, MAX_SLIPPAGE_INCREASE, MAX_SLIPPAGE_INCREASE, ZERO_BYTES) ); - bytes memory calls = planner.finalizeModifyLiquidity(config.poolKey); + bytes memory calls = planner.finalizeModifyLiquidityWithClose(config.poolKey); + lpm.modifyLiquidities(calls, _deadline); + + bytes32 positionId = + Position.calculatePositionKey(address(lpm), config.tickLower, config.tickUpper, bytes32(tokenId)); + (uint256 liquidity,,) = manager.getPositionInfo(config.poolKey.toId(), positionId); + + assertEq(liquidity, initialLiquidity + liquidityToAdd + liquidityToAdd2); + } + + function test_fuzz_execute_increaseLiquidity_twice_withSettlePair( + uint256 initialLiquidity, + uint256 liquidityToAdd, + uint256 liquidityToAdd2 + ) public { + initialLiquidity = bound(initialLiquidity, 1e18, 1000e18); + liquidityToAdd = bound(liquidityToAdd, 1e18, 1000e18); + liquidityToAdd2 = bound(liquidityToAdd2, 1e18, 1000e18); + uint256 tokenId = lpm.nextTokenId(); + mint(config, initialLiquidity, address(this), ZERO_BYTES); + + Plan memory planner = Planner.init(); + + planner.add( + Actions.INCREASE_LIQUIDITY, + abi.encode(tokenId, config, liquidityToAdd, MAX_SLIPPAGE_INCREASE, MAX_SLIPPAGE_INCREASE, ZERO_BYTES) + ); + planner.add( + Actions.INCREASE_LIQUIDITY, + abi.encode(tokenId, config, liquidityToAdd2, MAX_SLIPPAGE_INCREASE, MAX_SLIPPAGE_INCREASE, ZERO_BYTES) + ); + + bytes memory calls = planner.finalizeModifyLiquidityWithSettlePair(config.poolKey); lpm.modifyLiquidities(calls, _deadline); bytes32 positionId = @@ -130,7 +162,7 @@ contract ExecuteTest is Test, PosmTestSetup, LiquidityFuzzers { abi.encode(tokenId, config, liquidityToAdd, MAX_SLIPPAGE_INCREASE, MAX_SLIPPAGE_INCREASE, ZERO_BYTES) ); - bytes memory calls = planner.finalizeModifyLiquidity(config.poolKey); + bytes memory calls = planner.finalizeModifyLiquidityWithClose(config.poolKey); lpm.modifyLiquidities(calls, _deadline); bytes32 positionId = @@ -175,7 +207,7 @@ contract ExecuteTest is Test, PosmTestSetup, LiquidityFuzzers { Actions.MINT_POSITION, abi.encode(newConfig, newLiquidity, MAX_SLIPPAGE_INCREASE, MAX_SLIPPAGE_INCREASE, address(this), ZERO_BYTES) ); - bytes memory calls = planner.finalizeModifyLiquidity(config.poolKey); + bytes memory calls = planner.finalizeModifyLiquidityWithClose(config.poolKey); lpm.modifyLiquidities(calls, _deadline); { diff --git a/test/position-managers/IncreaseLiquidity.t.sol b/test/position-managers/IncreaseLiquidity.t.sol index 49e057c6e..8807d69bb 100644 --- a/test/position-managers/IncreaseLiquidity.t.sol +++ b/test/position-managers/IncreaseLiquidity.t.sol @@ -119,7 +119,7 @@ contract IncreaseLiquidityTest is Test, PosmTestSetup, Fuzzers { planner.add( Actions.INCREASE_LIQUIDITY, abi.encode(tokenIdAlice, config, liquidityDelta, 0 wei, 0 wei, ZERO_BYTES) ); - bytes memory calls = planner.finalizeModifyLiquidity(config.poolKey); + bytes memory calls = planner.finalizeModifyLiquidityWithClose(config.poolKey); vm.startPrank(alice); lpm.modifyLiquidities(calls, _deadline); vm.stopPrank(); diff --git a/test/position-managers/NativeToken.t.sol b/test/position-managers/NativeToken.t.sol index b7a8e901c..8cebd15de 100644 --- a/test/position-managers/NativeToken.t.sol +++ b/test/position-managers/NativeToken.t.sol @@ -96,7 +96,7 @@ contract PositionManagerTest is Test, PosmTestSetup, LiquidityFuzzers { } // minting with excess native tokens are returned to caller - function test_fuzz_mint_native_excess(IPoolManager.ModifyLiquidityParams memory params) public { + function test_fuzz_mint_native_excess_withClose(IPoolManager.ModifyLiquidityParams memory params) public { params = createFuzzyLiquidityParams(nativeKey, params, SQRT_PRICE_1_1); vm.assume(params.tickLower < 0 && 0 < params.tickUpper); // two-sided liquidity @@ -144,6 +144,53 @@ contract PositionManagerTest is Test, PosmTestSetup, LiquidityFuzzers { assertEq(balance1Before - currency1.balanceOfSelf(), uint256(int256(-delta.amount1()))); } + function test_fuzz_mint_native_excess_withSettlePair(IPoolManager.ModifyLiquidityParams memory params) public { + params = createFuzzyLiquidityParams(nativeKey, params, SQRT_PRICE_1_1); + vm.assume(params.tickLower < 0 && 0 < params.tickUpper); // two-sided liquidity + + uint256 liquidityToAdd = + params.liquidityDelta < 0 ? uint256(-params.liquidityDelta) : uint256(params.liquidityDelta); + PositionConfig memory config = + PositionConfig({poolKey: nativeKey, tickLower: params.tickLower, tickUpper: params.tickUpper}); + + uint256 balance0Before = currency0.balanceOfSelf(); + uint256 balance1Before = currency1.balanceOfSelf(); + + uint256 tokenId = lpm.nextTokenId(); + + Plan memory planner = Planner.init(); + planner.add( + Actions.MINT_POSITION, + abi.encode(config, liquidityToAdd, MAX_SLIPPAGE_INCREASE, MAX_SLIPPAGE_INCREASE, address(this), ZERO_BYTES) + ); + planner.add(Actions.SETTLE_PAIR, abi.encode(nativeKey.currency0, nativeKey.currency1)); + // sweep the excess eth + planner.add(Actions.SWEEP, abi.encode(currency0, address(this))); + + bytes memory calls = planner.encode(); + + (uint256 amount0,) = LiquidityAmounts.getAmountsForLiquidity( + SQRT_PRICE_1_1, + TickMath.getSqrtPriceAtTick(params.tickLower), + TickMath.getSqrtPriceAtTick(params.tickUpper), + liquidityToAdd.toUint128() + ); + + // Mint with excess native tokens + lpm.modifyLiquidities{value: amount0 * 2 + 1}(calls, _deadline); + BalanceDelta delta = getLastDelta(); + + bytes32 positionId = + Position.calculatePositionKey(address(lpm), config.tickLower, config.tickUpper, bytes32(tokenId)); + (uint256 liquidity,,) = manager.getPositionInfo(config.poolKey.toId(), positionId); + assertEq(liquidity, uint256(params.liquidityDelta)); + + // only paid the delta amount, with excess tokens returned to caller + assertEq(balance0Before - currency0.balanceOfSelf(), uint256(int256(-delta.amount0()))); + assertEq(balance0Before - currency0.balanceOfSelf(), amount0 + 1); // TODO: off by one?? + assertEq(balance1Before - currency1.balanceOfSelf(), uint256(int256(-delta.amount1()))); + } + function test_fuzz_burn_native_emptyPosition(IPoolManager.ModifyLiquidityParams memory params) public { uint256 balance0Start = address(this).balance; uint256 balance1Start = currency1.balanceOfSelf(); @@ -287,7 +334,7 @@ contract PositionManagerTest is Test, PosmTestSetup, LiquidityFuzzers { } // overpaying native tokens on increase liquidity is returned to caller - function test_fuzz_increaseLiquidity_native_excess(IPoolManager.ModifyLiquidityParams memory params) public { + function test_fuzz_increaseLiquidity_native_excess_withClose(IPoolManager.ModifyLiquidityParams memory params) public { // fuzz for the range params = createFuzzyLiquidityParams(nativeKey, params, SQRT_PRICE_1_1); vm.assume(params.tickLower < 0 && 0 < params.tickUpper); // two-sided liquidity @@ -338,6 +385,56 @@ contract PositionManagerTest is Test, PosmTestSetup, LiquidityFuzzers { assertEq(balance1Before - currency1.balanceOfSelf(), uint256(int256(-delta.amount1()))); } + function test_fuzz_increaseLiquidity_native_excess_withSettlePair(IPoolManager.ModifyLiquidityParams memory params) public { + // fuzz for the range + params = createFuzzyLiquidityParams(nativeKey, params, SQRT_PRICE_1_1); + vm.assume(params.tickLower < 0 && 0 < params.tickUpper); // two-sided liquidity + + // TODO: figure out if we can fuzz the increase liquidity delta. we're annoyingly getting TickLiquidityOverflow + uint256 liquidityToAdd = 1e18; + PositionConfig memory config = + PositionConfig({poolKey: nativeKey, tickLower: params.tickLower, tickUpper: params.tickUpper}); + + // mint the position with native token liquidity + uint256 tokenId = lpm.nextTokenId(); + mintWithNative(SQRT_PRICE_1_1, config, liquidityToAdd, address(this), ZERO_BYTES); + + uint256 balance0Before = address(this).balance; + uint256 balance1Before = currency1.balanceOfSelf(); + + // calculate how much native token is required for the liquidity increase (doubling the liquidity) + (uint256 amount0,) = LiquidityAmounts.getAmountsForLiquidity( + SQRT_PRICE_1_1, + TickMath.getSqrtPriceAtTick(params.tickLower), + TickMath.getSqrtPriceAtTick(params.tickUpper), + uint128(liquidityToAdd) + ); + + Plan memory planner = Planner.init(); + planner.add( + Actions.INCREASE_LIQUIDITY, + abi.encode(tokenId, config, liquidityToAdd, MAX_SLIPPAGE_INCREASE, MAX_SLIPPAGE_INCREASE, ZERO_BYTES) + ); + planner.add(Actions.SETTLE_PAIR, abi.encode(nativeKey.currency0, nativeKey.currency1)); + // sweep the excess eth + planner.add(Actions.SWEEP, abi.encode(currency0, address(this))); + bytes memory calls = planner.encode(); + + lpm.modifyLiquidities{value: amount0 * 2}(calls, _deadline); // overpay on increase liquidity + BalanceDelta delta = getLastDelta(); + + // verify position liquidity increased + bytes32 positionId = + Position.calculatePositionKey(address(lpm), config.tickLower, config.tickUpper, bytes32(tokenId)); + (uint256 liquidity,,) = manager.getPositionInfo(config.poolKey.toId(), positionId); + assertEq(liquidity, liquidityToAdd + liquidityToAdd); // liquidity was doubled + + // verify native token balances changed as expected, with overpaid tokens returned + assertEq(balance0Before - currency0.balanceOfSelf(), amount0 + 1 wei); + assertEq(balance0Before - currency0.balanceOfSelf(), uint256(int256(-delta.amount0()))); + assertEq(balance1Before - currency1.balanceOfSelf(), uint256(int256(-delta.amount1()))); + } + function test_fuzz_decreaseLiquidity_native( IPoolManager.ModifyLiquidityParams memory params, uint256 decreaseLiquidityDelta diff --git a/test/position-managers/PositionManager.gas.t.sol b/test/position-managers/PositionManager.gas.t.sol index 8f9aade0c..23ac63d6f 100644 --- a/test/position-managers/PositionManager.gas.t.sol +++ b/test/position-managers/PositionManager.gas.t.sol @@ -69,14 +69,24 @@ contract PosMGasTest is Test, PosmTestSetup, GasSnapshot { configNative = PositionConfig({poolKey: nativeKey, tickLower: -300, tickUpper: 300}); } - function test_gas_mint() public { + function test_gas_mint_withClose() public { Plan memory planner = Planner.init().add( Actions.MINT_POSITION, abi.encode(config, 10_000 ether, MAX_SLIPPAGE_INCREASE, MAX_SLIPPAGE_INCREASE, address(this), ZERO_BYTES) ); - bytes memory calls = planner.finalizeModifyLiquidity(config.poolKey); + bytes memory calls = planner.finalizeModifyLiquidityWithClose(config.poolKey); lpm.modifyLiquidities(calls, _deadline); - snapLastCall("PositionManager_mint"); + snapLastCall("PositionManager_mint_withClose"); + } + + function test_gas_mint_withSettlePair() public { + Plan memory planner = Planner.init().add( + Actions.MINT_POSITION, + abi.encode(config, 10_000 ether, MAX_SLIPPAGE_INCREASE, MAX_SLIPPAGE_INCREASE, address(this), ZERO_BYTES) + ); + bytes memory calls = planner.finalizeModifyLiquidityWithSettlePair(config.poolKey); + lpm.modifyLiquidities(calls, _deadline); + snapLastCall("PositionManager_mint_withSettlePair"); } function test_gas_mint_differentRanges() public { @@ -90,7 +100,7 @@ contract PosMGasTest is Test, PosmTestSetup, GasSnapshot { Actions.MINT_POSITION, abi.encode(config, 10_000 ether, MAX_SLIPPAGE_INCREASE, MAX_SLIPPAGE_INCREASE, address(alice), ZERO_BYTES) ); - bytes memory calls = planner.finalizeModifyLiquidity(config.poolKey); + bytes memory calls = planner.finalizeModifyLiquidityWithClose(config.poolKey); vm.prank(alice); lpm.modifyLiquidities(calls, _deadline); snapLastCall("PositionManager_mint_warmedPool_differentRange"); @@ -107,7 +117,7 @@ contract PosMGasTest is Test, PosmTestSetup, GasSnapshot { Actions.MINT_POSITION, abi.encode(config, 10_000 ether, MAX_SLIPPAGE_INCREASE, MAX_SLIPPAGE_INCREASE, address(alice), ZERO_BYTES) ); - bytes memory calls = planner.finalizeModifyLiquidity(config.poolKey); + bytes memory calls = planner.finalizeModifyLiquidityWithClose(config.poolKey); vm.prank(alice); lpm.modifyLiquidities(calls, _deadline); snapLastCall("PositionManager_mint_onSameTickLower"); @@ -124,13 +134,27 @@ contract PosMGasTest is Test, PosmTestSetup, GasSnapshot { Actions.MINT_POSITION, abi.encode(config, 10_000 ether, MAX_SLIPPAGE_INCREASE, MAX_SLIPPAGE_INCREASE, address(alice), ZERO_BYTES) ); - bytes memory calls = planner.finalizeModifyLiquidity(config.poolKey); + bytes memory calls = planner.finalizeModifyLiquidityWithClose(config.poolKey); vm.prank(alice); lpm.modifyLiquidities(calls, _deadline); snapLastCall("PositionManager_mint_onSameTickUpper"); } - function test_gas_increaseLiquidity_erc20() public { + function test_gas_increaseLiquidity_erc20_withClose() public { + uint256 tokenId = lpm.nextTokenId(); + mint(config, 10_000 ether, address(this), ZERO_BYTES); + + Plan memory planner = Planner.init().add( + Actions.INCREASE_LIQUIDITY, + abi.encode(tokenId, config, 10_000 ether, MAX_SLIPPAGE_INCREASE, MAX_SLIPPAGE_INCREASE, ZERO_BYTES) + ); + + bytes memory calls = planner.finalizeModifyLiquidityWithClose(config.poolKey); + lpm.modifyLiquidities(calls, _deadline); + snapLastCall("PositionManager_increaseLiquidity_erc20_withClose"); + } + + function test_gas_increaseLiquidity_erc20_withSettlePair() public { uint256 tokenId = lpm.nextTokenId(); mint(config, 10_000 ether, address(this), ZERO_BYTES); @@ -139,9 +163,9 @@ contract PosMGasTest is Test, PosmTestSetup, GasSnapshot { abi.encode(tokenId, config, 10_000 ether, MAX_SLIPPAGE_INCREASE, MAX_SLIPPAGE_INCREASE, ZERO_BYTES) ); - bytes memory calls = planner.finalizeModifyLiquidity(config.poolKey); + bytes memory calls = planner.finalizeModifyLiquidityWithSettlePair(config.poolKey); lpm.modifyLiquidities(calls, _deadline); - snapLastCall("PositionManager_increaseLiquidity_erc20"); + snapLastCall("PositionManager_increaseLiquidity_erc20_withSettlePair"); } function test_gas_autocompound_exactUnclaimedFees() public { @@ -278,7 +302,7 @@ contract PosMGasTest is Test, PosmTestSetup, GasSnapshot { abi.encode(tokenIdAlice, config, liquidityDelta, MAX_SLIPPAGE_INCREASE, MAX_SLIPPAGE_INCREASE, ZERO_BYTES) ); - bytes memory calls = planner.finalizeModifyLiquidity(config.poolKey); + bytes memory calls = planner.finalizeModifyLiquidityWithClose(config.poolKey); vm.prank(alice); lpm.modifyLiquidities(calls, _deadline); @@ -294,7 +318,7 @@ contract PosMGasTest is Test, PosmTestSetup, GasSnapshot { abi.encode(tokenId, config, 10_000 ether, MIN_SLIPPAGE_DECREASE, MIN_SLIPPAGE_DECREASE, ZERO_BYTES) ); - bytes memory calls = planner.finalizeModifyLiquidity(config.poolKey); + bytes memory calls = planner.finalizeModifyLiquidityWithClose(config.poolKey); lpm.modifyLiquidities(calls, _deadline); snapLastCall("PositionManager_decreaseLiquidity"); } @@ -317,7 +341,7 @@ contract PosMGasTest is Test, PosmTestSetup, GasSnapshot { Actions.MINT_POSITION, abi.encode(config, 100e18, MAX_SLIPPAGE_INCREASE, MAX_SLIPPAGE_INCREASE, address(this), ZERO_BYTES) ); - bytes memory actions = planner.finalizeModifyLiquidity(config.poolKey); + bytes memory actions = planner.finalizeModifyLiquidityWithClose(config.poolKey); calls[1] = abi.encodeWithSelector(IPositionManager.modifyLiquidities.selector, actions, _deadline); @@ -338,7 +362,7 @@ contract PosMGasTest is Test, PosmTestSetup, GasSnapshot { abi.encode(tokenId, config, 0, MIN_SLIPPAGE_DECREASE, MIN_SLIPPAGE_DECREASE, ZERO_BYTES) ); - bytes memory calls = planner.finalizeModifyLiquidity(config.poolKey); + bytes memory calls = planner.finalizeModifyLiquidityWithClose(config.poolKey); lpm.modifyLiquidities(calls, _deadline); snapLastCall("PositionManager_collect"); } @@ -351,7 +375,7 @@ contract PosMGasTest is Test, PosmTestSetup, GasSnapshot { Actions.MINT_POSITION, abi.encode(config, 10_001 ether, MAX_SLIPPAGE_INCREASE, MAX_SLIPPAGE_INCREASE, address(alice), ZERO_BYTES) ); - bytes memory calls = planner.finalizeModifyLiquidity(config.poolKey); + bytes memory calls = planner.finalizeModifyLiquidityWithClose(config.poolKey); vm.prank(alice); lpm.modifyLiquidities(calls, _deadline); snapLastCall("PositionManager_mint_sameRange"); @@ -371,7 +395,7 @@ contract PosMGasTest is Test, PosmTestSetup, GasSnapshot { abi.encode(tokenId, config, 10_000 ether, MIN_SLIPPAGE_DECREASE, MIN_SLIPPAGE_DECREASE, ZERO_BYTES) ); - bytes memory calls = planner.finalizeModifyLiquidity(config.poolKey); + bytes memory calls = planner.finalizeModifyLiquidityWithClose(config.poolKey); lpm.modifyLiquidities(calls, _deadline); snapLastCall("PositionManager_decrease_sameRange_allLiquidity"); } @@ -393,7 +417,7 @@ contract PosMGasTest is Test, PosmTestSetup, GasSnapshot { abi.encode(tokenId, config, 0, MIN_SLIPPAGE_DECREASE, MIN_SLIPPAGE_DECREASE, ZERO_BYTES) ); - bytes memory calls = planner.finalizeModifyLiquidity(config.poolKey); + bytes memory calls = planner.finalizeModifyLiquidityWithClose(config.poolKey); lpm.modifyLiquidities(calls, _deadline); snapLastCall("PositionManager_collect_sameRange"); } @@ -405,7 +429,7 @@ contract PosMGasTest is Test, PosmTestSetup, GasSnapshot { Plan memory planner = Planner.init().add( Actions.BURN_POSITION, abi.encode(tokenId, config, MIN_SLIPPAGE_DECREASE, MIN_SLIPPAGE_DECREASE, ZERO_BYTES) ); - bytes memory calls = planner.finalizeModifyLiquidity(config.poolKey); + bytes memory calls = planner.finalizeModifyLiquidityWithClose(config.poolKey); lpm.modifyLiquidities(calls, _deadline); snapLastCall("PositionManager_burn_nonEmpty"); @@ -441,7 +465,7 @@ contract PosMGasTest is Test, PosmTestSetup, GasSnapshot { ); // We must include CLOSE commands. - bytes memory calls = planner.finalizeModifyLiquidity(config.poolKey); + bytes memory calls = planner.finalizeModifyLiquidityWithClose(config.poolKey); lpm.modifyLiquidities(calls, _deadline); snapLastCall("PositionManager_decrease_burnEmpty"); } @@ -465,7 +489,7 @@ contract PosMGasTest is Test, PosmTestSetup, GasSnapshot { snapLastCall("PositionManager_mint_native"); } - function test_gas_mint_native_excess() public { + function test_gas_mint_native_excess_withClose() public { uint256 liquidityToAdd = 10_000 ether; Plan memory planner = Planner.init(); @@ -488,7 +512,32 @@ contract PosMGasTest is Test, PosmTestSetup, GasSnapshot { ); // overpay on the native token lpm.modifyLiquidities{value: amount0 * 2}(calls, _deadline); - snapLastCall("PositionManager_mint_nativeWithSweep"); + snapLastCall("PositionManager_mint_nativeWithSweep_withClose"); + } + + function test_gas_mint_native_excess_withSettlePair() public { + uint256 liquidityToAdd = 10_000 ether; + + Plan memory planner = Planner.init(); + planner.add( + Actions.MINT_POSITION, + abi.encode( + configNative, liquidityToAdd, MAX_SLIPPAGE_INCREASE, MAX_SLIPPAGE_INCREASE, address(this), ZERO_BYTES + ) + ); + planner.add(Actions.SETTLE_PAIR, abi.encode(nativeKey.currency0, nativeKey.currency1)); + planner.add(Actions.SWEEP, abi.encode(CurrencyLibrary.NATIVE, address(this))); + bytes memory calls = planner.encode(); + + (uint256 amount0,) = LiquidityAmounts.getAmountsForLiquidity( + SQRT_PRICE_1_1, + TickMath.getSqrtPriceAtTick(configNative.tickLower), + TickMath.getSqrtPriceAtTick(configNative.tickUpper), + uint128(liquidityToAdd) + ); + // overpay on the native token + lpm.modifyLiquidities{value: amount0 * 2}(calls, _deadline); + snapLastCall("PositionManager_mint_nativeWithSweep_withSettlePair"); } function test_gas_increase_native() public { @@ -537,7 +586,7 @@ contract PosMGasTest is Test, PosmTestSetup, GasSnapshot { Actions.BURN_POSITION, abi.encode(tokenId, configNative, MIN_SLIPPAGE_DECREASE, MIN_SLIPPAGE_DECREASE, ZERO_BYTES) ); - bytes memory calls = planner.finalizeModifyLiquidity(configNative.poolKey); + bytes memory calls = planner.finalizeModifyLiquidityWithClose(configNative.poolKey); lpm.modifyLiquidities(calls, _deadline); snapLastCall("PositionManager_burn_nonEmpty_native"); @@ -572,7 +621,7 @@ contract PosMGasTest is Test, PosmTestSetup, GasSnapshot { planner.add(Actions.BURN_POSITION, abi.encode(tokenId, configNative, 0 wei, 0 wei, ZERO_BYTES)); // We must include CLOSE commands. - bytes memory calls = planner.finalizeModifyLiquidity(configNative.poolKey); + bytes memory calls = planner.finalizeModifyLiquidityWithClose(configNative.poolKey); lpm.modifyLiquidities(calls, _deadline); snapLastCall("PositionManager_decrease_burnEmpty_native"); } diff --git a/test/position-managers/PositionManager.multicall.t.sol b/test/position-managers/PositionManager.multicall.t.sol index da8774fdb..c47a98521 100644 --- a/test/position-managers/PositionManager.multicall.t.sol +++ b/test/position-managers/PositionManager.multicall.t.sol @@ -59,7 +59,7 @@ contract PositionManagerMulticallTest is Test, PosmTestSetup, LiquidityFuzzers { Actions.MINT_POSITION, abi.encode(config, 100e18, MAX_SLIPPAGE_INCREASE, MAX_SLIPPAGE_INCREASE, address(this), ZERO_BYTES) ); - bytes memory actions = planner.finalizeModifyLiquidity(config.poolKey); + bytes memory actions = planner.finalizeModifyLiquidityWithClose(config.poolKey); calls[1] = abi.encodeWithSelector(IPositionManager.modifyLiquidities.selector, actions, _deadline); diff --git a/test/shared/LiquidityOperations.sol b/test/shared/LiquidityOperations.sol index a46230920..026abe8c2 100644 --- a/test/shared/LiquidityOperations.sol +++ b/test/shared/LiquidityOperations.sol @@ -101,7 +101,7 @@ abstract contract LiquidityOperations is CommonBase { Plan memory planner = Planner.init(); planner.add(Actions.MINT_POSITION, abi.encode(config, liquidity, amount0Max, amount1Max, recipient, hookData)); - return planner.finalizeModifyLiquidity(config.poolKey); + return planner.finalizeModifyLiquidityWithClose(config.poolKey); } function getIncreaseEncoded( @@ -127,7 +127,7 @@ abstract contract LiquidityOperations is CommonBase { planner.add( Actions.INCREASE_LIQUIDITY, abi.encode(tokenId, config, liquidityToAdd, amount0Max, amount1Max, hookData) ); - return planner.finalizeModifyLiquidity(config.poolKey); + return planner.finalizeModifyLiquidityWithClose(config.poolKey); } function getDecreaseEncoded( @@ -153,7 +153,7 @@ abstract contract LiquidityOperations is CommonBase { planner.add( Actions.DECREASE_LIQUIDITY, abi.encode(tokenId, config, liquidityToRemove, amount0Min, amount1Min, hookData) ); - return planner.finalizeModifyLiquidity(config.poolKey); + return planner.finalizeModifyLiquidityWithClose(config.poolKey); } function getCollectEncoded(uint256 tokenId, PositionConfig memory config, bytes memory hookData) @@ -173,7 +173,7 @@ abstract contract LiquidityOperations is CommonBase { ) internal pure returns (bytes memory) { Plan memory planner = Planner.init(); planner.add(Actions.DECREASE_LIQUIDITY, abi.encode(tokenId, config, 0, amount0Min, amount1Min, hookData)); - return planner.finalizeModifyLiquidity(config.poolKey); + return planner.finalizeModifyLiquidityWithClose(config.poolKey); } function getBurnEncoded(uint256 tokenId, PositionConfig memory config, bytes memory hookData) @@ -194,6 +194,6 @@ abstract contract LiquidityOperations is CommonBase { Plan memory planner = Planner.init(); planner.add(Actions.BURN_POSITION, abi.encode(tokenId, config, amount0Min, amount1Min, hookData)); // Close needed on burn in case there is liquidity left in the position. - return planner.finalizeModifyLiquidity(config.poolKey); + return planner.finalizeModifyLiquidityWithClose(config.poolKey); } } diff --git a/test/shared/Planner.sol b/test/shared/Planner.sol index 71020abed..8c8a2f860 100644 --- a/test/shared/Planner.sol +++ b/test/shared/Planner.sol @@ -37,12 +37,17 @@ library Planner { return plan; } - function finalizeModifyLiquidity(Plan memory plan, PoolKey memory poolKey) internal pure returns (bytes memory) { + function finalizeModifyLiquidityWithClose(Plan memory plan, PoolKey memory poolKey) internal pure returns (bytes memory) { plan.add(Actions.CLOSE_CURRENCY, abi.encode(poolKey.currency0)); plan.add(Actions.CLOSE_CURRENCY, abi.encode(poolKey.currency1)); return plan.encode(); } + function finalizeModifyLiquidityWithSettlePair(Plan memory plan, PoolKey memory poolKey) internal pure returns (bytes memory) { + plan.add(Actions.SETTLE_PAIR, abi.encode(poolKey.currency0, poolKey.currency1)); + return plan.encode(); + } + function encode(Plan memory plan) internal pure returns (bytes memory) { return abi.encode(plan.actions, plan.params); } diff --git a/test/shared/fuzz/LiquidityFuzzers.sol b/test/shared/fuzz/LiquidityFuzzers.sol index 5bbfbc73e..02d6583f4 100644 --- a/test/shared/fuzz/LiquidityFuzzers.sol +++ b/test/shared/fuzz/LiquidityFuzzers.sol @@ -41,7 +41,7 @@ contract LiquidityFuzzers is Fuzzers { ); uint256 tokenId = lpm.nextTokenId(); - bytes memory calls = planner.finalizeModifyLiquidity(config.poolKey); + bytes memory calls = planner.finalizeModifyLiquidityWithClose(config.poolKey); lpm.modifyLiquidities(calls, block.timestamp + 1); return (tokenId, params); From cf3cdc0aeb945943bce8559444cce8414efd2f76 Mon Sep 17 00:00:00 2001 From: dianakocsis Date: Fri, 2 Aug 2024 12:40:45 -0400 Subject: [PATCH 2/4] format --- test/position-managers/NativeToken.t.sol | 8 ++++++-- test/shared/Planner.sol | 12 ++++++++++-- 2 files changed, 16 insertions(+), 4 deletions(-) diff --git a/test/position-managers/NativeToken.t.sol b/test/position-managers/NativeToken.t.sol index 8cebd15de..c877b8a62 100644 --- a/test/position-managers/NativeToken.t.sol +++ b/test/position-managers/NativeToken.t.sol @@ -334,7 +334,9 @@ contract PositionManagerTest is Test, PosmTestSetup, LiquidityFuzzers { } // overpaying native tokens on increase liquidity is returned to caller - function test_fuzz_increaseLiquidity_native_excess_withClose(IPoolManager.ModifyLiquidityParams memory params) public { + function test_fuzz_increaseLiquidity_native_excess_withClose(IPoolManager.ModifyLiquidityParams memory params) + public + { // fuzz for the range params = createFuzzyLiquidityParams(nativeKey, params, SQRT_PRICE_1_1); vm.assume(params.tickLower < 0 && 0 < params.tickUpper); // two-sided liquidity @@ -385,7 +387,9 @@ contract PositionManagerTest is Test, PosmTestSetup, LiquidityFuzzers { assertEq(balance1Before - currency1.balanceOfSelf(), uint256(int256(-delta.amount1()))); } - function test_fuzz_increaseLiquidity_native_excess_withSettlePair(IPoolManager.ModifyLiquidityParams memory params) public { + function test_fuzz_increaseLiquidity_native_excess_withSettlePair(IPoolManager.ModifyLiquidityParams memory params) + public + { // fuzz for the range params = createFuzzyLiquidityParams(nativeKey, params, SQRT_PRICE_1_1); vm.assume(params.tickLower < 0 && 0 < params.tickUpper); // two-sided liquidity diff --git a/test/shared/Planner.sol b/test/shared/Planner.sol index 8c8a2f860..58913083d 100644 --- a/test/shared/Planner.sol +++ b/test/shared/Planner.sol @@ -37,13 +37,21 @@ library Planner { return plan; } - function finalizeModifyLiquidityWithClose(Plan memory plan, PoolKey memory poolKey) internal pure returns (bytes memory) { + function finalizeModifyLiquidityWithClose(Plan memory plan, PoolKey memory poolKey) + internal + pure + returns (bytes memory) + { plan.add(Actions.CLOSE_CURRENCY, abi.encode(poolKey.currency0)); plan.add(Actions.CLOSE_CURRENCY, abi.encode(poolKey.currency1)); return plan.encode(); } - function finalizeModifyLiquidityWithSettlePair(Plan memory plan, PoolKey memory poolKey) internal pure returns (bytes memory) { + function finalizeModifyLiquidityWithSettlePair(Plan memory plan, PoolKey memory poolKey) + internal + pure + returns (bytes memory) + { plan.add(Actions.SETTLE_PAIR, abi.encode(poolKey.currency0, poolKey.currency1)); return plan.encode(); } From d9570d85949707270b1d1f69bbcc27e9bf5f3b62 Mon Sep 17 00:00:00 2001 From: dianakocsis Date: Fri, 2 Aug 2024 12:51:02 -0400 Subject: [PATCH 3/4] with currencydeltas library --- .forge-snapshots/PositionManager_burn_empty.snap | 2 +- .forge-snapshots/PositionManager_burn_empty_native.snap | 2 +- .forge-snapshots/PositionManager_burn_nonEmpty.snap | 2 +- .forge-snapshots/PositionManager_burn_nonEmpty_native.snap | 2 +- .forge-snapshots/PositionManager_collect.snap | 2 +- .forge-snapshots/PositionManager_collect_native.snap | 2 +- .forge-snapshots/PositionManager_collect_sameRange.snap | 2 +- .forge-snapshots/PositionManager_decreaseLiquidity.snap | 2 +- .../PositionManager_decreaseLiquidity_native.snap | 2 +- .forge-snapshots/PositionManager_decrease_burnEmpty.snap | 2 +- .../PositionManager_decrease_burnEmpty_native.snap | 2 +- .../PositionManager_decrease_sameRange_allLiquidity.snap | 2 +- .../PositionManager_increaseLiquidity_erc20_withClose.snap | 2 +- ...tionManager_increaseLiquidity_erc20_withSettlePair.snap | 2 +- .../PositionManager_increaseLiquidity_native.snap | 2 +- ...ionManager_increase_autocompoundExactUnclaimedFees.snap | 2 +- ...itionManager_increase_autocompoundExcessFeesCredit.snap | 2 +- .../PositionManager_increase_autocompound_clearExcess.snap | 2 +- .forge-snapshots/PositionManager_mint_native.snap | 2 +- .../PositionManager_mint_nativeWithSweep_withClose.snap | 2 +- ...ositionManager_mint_nativeWithSweep_withSettlePair.snap | 2 +- .forge-snapshots/PositionManager_mint_onSameTickLower.snap | 2 +- .forge-snapshots/PositionManager_mint_onSameTickUpper.snap | 2 +- .forge-snapshots/PositionManager_mint_sameRange.snap | 2 +- .../PositionManager_mint_settleWithBalance_sweep.snap | 2 +- .../PositionManager_mint_warmedPool_differentRange.snap | 2 +- .forge-snapshots/PositionManager_mint_withClose.snap | 2 +- .forge-snapshots/PositionManager_mint_withSettlePair.snap | 2 +- .../PositionManager_multicall_initialize_mint.snap | 2 +- src/PositionManager.sol | 7 +++++-- 30 files changed, 34 insertions(+), 31 deletions(-) diff --git a/.forge-snapshots/PositionManager_burn_empty.snap b/.forge-snapshots/PositionManager_burn_empty.snap index 4c1846423..c28945ad4 100644 --- a/.forge-snapshots/PositionManager_burn_empty.snap +++ b/.forge-snapshots/PositionManager_burn_empty.snap @@ -1 +1 @@ -47059 \ No newline at end of file +47092 \ No newline at end of file diff --git a/.forge-snapshots/PositionManager_burn_empty_native.snap b/.forge-snapshots/PositionManager_burn_empty_native.snap index 9230f513f..2e392d56c 100644 --- a/.forge-snapshots/PositionManager_burn_empty_native.snap +++ b/.forge-snapshots/PositionManager_burn_empty_native.snap @@ -1 +1 @@ -46876 \ No newline at end of file +46909 \ No newline at end of file diff --git a/.forge-snapshots/PositionManager_burn_nonEmpty.snap b/.forge-snapshots/PositionManager_burn_nonEmpty.snap index c15f4f2dc..b7cdf0170 100644 --- a/.forge-snapshots/PositionManager_burn_nonEmpty.snap +++ b/.forge-snapshots/PositionManager_burn_nonEmpty.snap @@ -1 +1 @@ -129852 \ No newline at end of file +129884 \ No newline at end of file diff --git a/.forge-snapshots/PositionManager_burn_nonEmpty_native.snap b/.forge-snapshots/PositionManager_burn_nonEmpty_native.snap index d2ae1c7d4..d431e401c 100644 --- a/.forge-snapshots/PositionManager_burn_nonEmpty_native.snap +++ b/.forge-snapshots/PositionManager_burn_nonEmpty_native.snap @@ -1 +1 @@ -122773 \ No newline at end of file +122806 \ No newline at end of file diff --git a/.forge-snapshots/PositionManager_collect.snap b/.forge-snapshots/PositionManager_collect.snap index 0cf00f2ad..e33b55453 100644 --- a/.forge-snapshots/PositionManager_collect.snap +++ b/.forge-snapshots/PositionManager_collect.snap @@ -1 +1 @@ -149984 \ No newline at end of file +150025 \ No newline at end of file diff --git a/.forge-snapshots/PositionManager_collect_native.snap b/.forge-snapshots/PositionManager_collect_native.snap index 1b627db8b..1580a3486 100644 --- a/.forge-snapshots/PositionManager_collect_native.snap +++ b/.forge-snapshots/PositionManager_collect_native.snap @@ -1 +1 @@ -141136 \ No newline at end of file +141177 \ No newline at end of file diff --git a/.forge-snapshots/PositionManager_collect_sameRange.snap b/.forge-snapshots/PositionManager_collect_sameRange.snap index 0cf00f2ad..e33b55453 100644 --- a/.forge-snapshots/PositionManager_collect_sameRange.snap +++ b/.forge-snapshots/PositionManager_collect_sameRange.snap @@ -1 +1 @@ -149984 \ No newline at end of file +150025 \ No newline at end of file diff --git a/.forge-snapshots/PositionManager_decreaseLiquidity.snap b/.forge-snapshots/PositionManager_decreaseLiquidity.snap index c30fc9dee..1c1593d1e 100644 --- a/.forge-snapshots/PositionManager_decreaseLiquidity.snap +++ b/.forge-snapshots/PositionManager_decreaseLiquidity.snap @@ -1 +1 @@ -115527 \ No newline at end of file +115568 \ No newline at end of file diff --git a/.forge-snapshots/PositionManager_decreaseLiquidity_native.snap b/.forge-snapshots/PositionManager_decreaseLiquidity_native.snap index 3c0e3daf0..319c4877d 100644 --- a/.forge-snapshots/PositionManager_decreaseLiquidity_native.snap +++ b/.forge-snapshots/PositionManager_decreaseLiquidity_native.snap @@ -1 +1 @@ -108384 \ No newline at end of file +108416 \ No newline at end of file diff --git a/.forge-snapshots/PositionManager_decrease_burnEmpty.snap b/.forge-snapshots/PositionManager_decrease_burnEmpty.snap index 58fe18442..2b39a06db 100644 --- a/.forge-snapshots/PositionManager_decrease_burnEmpty.snap +++ b/.forge-snapshots/PositionManager_decrease_burnEmpty.snap @@ -1 +1 @@ -133885 \ No newline at end of file +133918 \ No newline at end of file diff --git a/.forge-snapshots/PositionManager_decrease_burnEmpty_native.snap b/.forge-snapshots/PositionManager_decrease_burnEmpty_native.snap index 23aac82f0..f83add2a1 100644 --- a/.forge-snapshots/PositionManager_decrease_burnEmpty_native.snap +++ b/.forge-snapshots/PositionManager_decrease_burnEmpty_native.snap @@ -1 +1 @@ -126624 \ No newline at end of file +126657 \ No newline at end of file diff --git a/.forge-snapshots/PositionManager_decrease_sameRange_allLiquidity.snap b/.forge-snapshots/PositionManager_decrease_sameRange_allLiquidity.snap index 48ed66878..75cc3313d 100644 --- a/.forge-snapshots/PositionManager_decrease_sameRange_allLiquidity.snap +++ b/.forge-snapshots/PositionManager_decrease_sameRange_allLiquidity.snap @@ -1 +1 @@ -128243 \ No newline at end of file +128284 \ No newline at end of file diff --git a/.forge-snapshots/PositionManager_increaseLiquidity_erc20_withClose.snap b/.forge-snapshots/PositionManager_increaseLiquidity_erc20_withClose.snap index 267233964..c749113b5 100644 --- a/.forge-snapshots/PositionManager_increaseLiquidity_erc20_withClose.snap +++ b/.forge-snapshots/PositionManager_increaseLiquidity_erc20_withClose.snap @@ -1 +1 @@ -152100 \ No newline at end of file +152141 \ No newline at end of file diff --git a/.forge-snapshots/PositionManager_increaseLiquidity_erc20_withSettlePair.snap b/.forge-snapshots/PositionManager_increaseLiquidity_erc20_withSettlePair.snap index 6ce3534b4..2e341ff2a 100644 --- a/.forge-snapshots/PositionManager_increaseLiquidity_erc20_withSettlePair.snap +++ b/.forge-snapshots/PositionManager_increaseLiquidity_erc20_withSettlePair.snap @@ -1 +1 @@ -151341 \ No newline at end of file +152344 \ No newline at end of file diff --git a/.forge-snapshots/PositionManager_increaseLiquidity_native.snap b/.forge-snapshots/PositionManager_increaseLiquidity_native.snap index 35295eaff..e8b34b1f8 100644 --- a/.forge-snapshots/PositionManager_increaseLiquidity_native.snap +++ b/.forge-snapshots/PositionManager_increaseLiquidity_native.snap @@ -1 +1 @@ -133900 \ No newline at end of file +133941 \ No newline at end of file diff --git a/.forge-snapshots/PositionManager_increase_autocompoundExactUnclaimedFees.snap b/.forge-snapshots/PositionManager_increase_autocompoundExactUnclaimedFees.snap index 04c138b3d..6913dd59b 100644 --- a/.forge-snapshots/PositionManager_increase_autocompoundExactUnclaimedFees.snap +++ b/.forge-snapshots/PositionManager_increase_autocompoundExactUnclaimedFees.snap @@ -1 +1 @@ -130065 \ No newline at end of file +130106 \ No newline at end of file diff --git a/.forge-snapshots/PositionManager_increase_autocompoundExcessFeesCredit.snap b/.forge-snapshots/PositionManager_increase_autocompoundExcessFeesCredit.snap index e55d62578..8b1ec079c 100644 --- a/.forge-snapshots/PositionManager_increase_autocompoundExcessFeesCredit.snap +++ b/.forge-snapshots/PositionManager_increase_autocompoundExcessFeesCredit.snap @@ -1 +1 @@ -170759 \ No newline at end of file +170800 \ No newline at end of file diff --git a/.forge-snapshots/PositionManager_increase_autocompound_clearExcess.snap b/.forge-snapshots/PositionManager_increase_autocompound_clearExcess.snap index 375f518b7..815cd2fa2 100644 --- a/.forge-snapshots/PositionManager_increase_autocompound_clearExcess.snap +++ b/.forge-snapshots/PositionManager_increase_autocompound_clearExcess.snap @@ -1 +1 @@ -140581 \ No newline at end of file +140622 \ No newline at end of file diff --git a/.forge-snapshots/PositionManager_mint_native.snap b/.forge-snapshots/PositionManager_mint_native.snap index e708094ba..96d04a797 100644 --- a/.forge-snapshots/PositionManager_mint_native.snap +++ b/.forge-snapshots/PositionManager_mint_native.snap @@ -1 +1 @@ -336712 \ No newline at end of file +336753 \ No newline at end of file diff --git a/.forge-snapshots/PositionManager_mint_nativeWithSweep_withClose.snap b/.forge-snapshots/PositionManager_mint_nativeWithSweep_withClose.snap index 378d9bfb1..a9d71fb93 100644 --- a/.forge-snapshots/PositionManager_mint_nativeWithSweep_withClose.snap +++ b/.forge-snapshots/PositionManager_mint_nativeWithSweep_withClose.snap @@ -1 +1 @@ -345267 \ No newline at end of file +345308 \ No newline at end of file diff --git a/.forge-snapshots/PositionManager_mint_nativeWithSweep_withSettlePair.snap b/.forge-snapshots/PositionManager_mint_nativeWithSweep_withSettlePair.snap index 9f308f43c..699aa1f73 100644 --- a/.forge-snapshots/PositionManager_mint_nativeWithSweep_withSettlePair.snap +++ b/.forge-snapshots/PositionManager_mint_nativeWithSweep_withSettlePair.snap @@ -1 +1 @@ -344532 \ No newline at end of file +345535 \ No newline at end of file diff --git a/.forge-snapshots/PositionManager_mint_onSameTickLower.snap b/.forge-snapshots/PositionManager_mint_onSameTickLower.snap index 90fd8fec4..683690a21 100644 --- a/.forge-snapshots/PositionManager_mint_onSameTickLower.snap +++ b/.forge-snapshots/PositionManager_mint_onSameTickLower.snap @@ -1 +1 @@ -314694 \ No newline at end of file +314735 \ No newline at end of file diff --git a/.forge-snapshots/PositionManager_mint_onSameTickUpper.snap b/.forge-snapshots/PositionManager_mint_onSameTickUpper.snap index 9b6845afb..a24ca951a 100644 --- a/.forge-snapshots/PositionManager_mint_onSameTickUpper.snap +++ b/.forge-snapshots/PositionManager_mint_onSameTickUpper.snap @@ -1 +1 @@ -315336 \ No newline at end of file +315377 \ No newline at end of file diff --git a/.forge-snapshots/PositionManager_mint_sameRange.snap b/.forge-snapshots/PositionManager_mint_sameRange.snap index 597983b55..0c320de4e 100644 --- a/.forge-snapshots/PositionManager_mint_sameRange.snap +++ b/.forge-snapshots/PositionManager_mint_sameRange.snap @@ -1 +1 @@ -240918 \ No newline at end of file +240959 \ No newline at end of file diff --git a/.forge-snapshots/PositionManager_mint_settleWithBalance_sweep.snap b/.forge-snapshots/PositionManager_mint_settleWithBalance_sweep.snap index 817d77abd..7c7156698 100644 --- a/.forge-snapshots/PositionManager_mint_settleWithBalance_sweep.snap +++ b/.forge-snapshots/PositionManager_mint_settleWithBalance_sweep.snap @@ -1 +1 @@ -370064 \ No newline at end of file +370105 \ No newline at end of file diff --git a/.forge-snapshots/PositionManager_mint_warmedPool_differentRange.snap b/.forge-snapshots/PositionManager_mint_warmedPool_differentRange.snap index af4a8aa0c..c015cf17b 100644 --- a/.forge-snapshots/PositionManager_mint_warmedPool_differentRange.snap +++ b/.forge-snapshots/PositionManager_mint_warmedPool_differentRange.snap @@ -1 +1 @@ -320712 \ No newline at end of file +320753 \ No newline at end of file diff --git a/.forge-snapshots/PositionManager_mint_withClose.snap b/.forge-snapshots/PositionManager_mint_withClose.snap index 7e0f6688a..78db2c60a 100644 --- a/.forge-snapshots/PositionManager_mint_withClose.snap +++ b/.forge-snapshots/PositionManager_mint_withClose.snap @@ -1 +1 @@ -372012 \ No newline at end of file +372053 \ No newline at end of file diff --git a/.forge-snapshots/PositionManager_mint_withSettlePair.snap b/.forge-snapshots/PositionManager_mint_withSettlePair.snap index 99ea27ab7..3eb70c9c6 100644 --- a/.forge-snapshots/PositionManager_mint_withSettlePair.snap +++ b/.forge-snapshots/PositionManager_mint_withSettlePair.snap @@ -1 +1 @@ -371253 \ No newline at end of file +372256 \ No newline at end of file diff --git a/.forge-snapshots/PositionManager_multicall_initialize_mint.snap b/.forge-snapshots/PositionManager_multicall_initialize_mint.snap index 28856ebdf..3c6426895 100644 --- a/.forge-snapshots/PositionManager_multicall_initialize_mint.snap +++ b/.forge-snapshots/PositionManager_multicall_initialize_mint.snap @@ -1 +1 @@ -416388 \ No newline at end of file +416429 \ No newline at end of file diff --git a/src/PositionManager.sol b/src/PositionManager.sol index 285493f5f..23a571962 100644 --- a/src/PositionManager.sol +++ b/src/PositionManager.sol @@ -26,6 +26,7 @@ import {BaseActionsRouter} from "./base/BaseActionsRouter.sol"; import {Actions} from "./libraries/Actions.sol"; import {CalldataDecoder} from "./libraries/CalldataDecoder.sol"; import {SlippageCheckLibrary} from "./libraries/SlippageCheck.sol"; +import {CurrencyDeltas} from "./libraries/CurrencyDeltas.sol"; contract PositionManager is IPositionManager, @@ -45,6 +46,7 @@ contract PositionManager is using SafeCast for uint256; using CalldataDecoder for bytes; using SlippageCheckLibrary for BalanceDelta; + using CurrencyDeltas for IPoolManager; /// @dev The ID of the next token that will be minted. Skips 0 uint256 public nextTokenId = 1; @@ -227,8 +229,9 @@ contract PositionManager is function _settlePair(Currency currency0, Currency currency1) internal { // the locker is the payer when settling address caller = _msgSender(); - _settle(currency0, caller, _getFullSettleAmount(currency0)); - _settle(currency1, caller, _getFullSettleAmount(currency1)); + BalanceDelta delta = poolManager.currencyDeltas(address(this), currency0, currency1); + _settle(currency0, caller, uint256(int256(-delta.amount0()))); + _settle(currency1, caller, uint256(int256(-delta.amount1()))); } /// @dev this is overloaded with ERC721Permit._burn From fc69b3d1238ea6b171586b741e969ff93bdb2dd0 Mon Sep 17 00:00:00 2001 From: dianakocsis Date: Fri, 2 Aug 2024 12:57:06 -0400 Subject: [PATCH 4/4] remove currencydeltas library --- .../PositionManager_burn_empty.snap | 2 +- .../PositionManager_burn_empty_native.snap | 2 +- .../PositionManager_burn_nonEmpty.snap | 2 +- .../PositionManager_burn_nonEmpty_native.snap | 2 +- .forge-snapshots/PositionManager_collect.snap | 2 +- .../PositionManager_collect_native.snap | 2 +- .../PositionManager_collect_sameRange.snap | 2 +- .../PositionManager_decreaseLiquidity.snap | 2 +- ...itionManager_decreaseLiquidity_native.snap | 2 +- .../PositionManager_decrease_burnEmpty.snap | 2 +- ...tionManager_decrease_burnEmpty_native.snap | 2 +- ...nager_decrease_sameRange_allLiquidity.snap | 2 +- ...ger_increaseLiquidity_erc20_withClose.snap | 2 +- ...ncreaseLiquidity_erc20_withSettlePair.snap | 2 +- ...itionManager_increaseLiquidity_native.snap | 2 +- ...crease_autocompoundExactUnclaimedFees.snap | 2 +- ...increase_autocompoundExcessFeesCredit.snap | 2 +- ...ger_increase_autocompound_clearExcess.snap | 2 +- .../PositionManager_mint_native.snap | 2 +- ...anager_mint_nativeWithSweep_withClose.snap | 2 +- ...r_mint_nativeWithSweep_withSettlePair.snap | 2 +- .../PositionManager_mint_onSameTickLower.snap | 2 +- .../PositionManager_mint_onSameTickUpper.snap | 2 +- .../PositionManager_mint_sameRange.snap | 2 +- ...nManager_mint_settleWithBalance_sweep.snap | 2 +- ...anager_mint_warmedPool_differentRange.snap | 2 +- .../PositionManager_mint_withClose.snap | 2 +- .../PositionManager_mint_withSettlePair.snap | 2 +- ...tionManager_multicall_initialize_mint.snap | 2 +- src/PositionManager.sol | 7 +- src/libraries/CurrencyDeltas.sol | 42 ---------- test/libraries/CurrencyDeltas.t.sol | 82 ------------------- test/mocks/MockCurrencyDeltaReader.sol | 71 ---------------- 33 files changed, 31 insertions(+), 229 deletions(-) delete mode 100644 src/libraries/CurrencyDeltas.sol delete mode 100644 test/libraries/CurrencyDeltas.t.sol delete mode 100644 test/mocks/MockCurrencyDeltaReader.sol diff --git a/.forge-snapshots/PositionManager_burn_empty.snap b/.forge-snapshots/PositionManager_burn_empty.snap index c28945ad4..4c1846423 100644 --- a/.forge-snapshots/PositionManager_burn_empty.snap +++ b/.forge-snapshots/PositionManager_burn_empty.snap @@ -1 +1 @@ -47092 \ No newline at end of file +47059 \ No newline at end of file diff --git a/.forge-snapshots/PositionManager_burn_empty_native.snap b/.forge-snapshots/PositionManager_burn_empty_native.snap index 2e392d56c..9230f513f 100644 --- a/.forge-snapshots/PositionManager_burn_empty_native.snap +++ b/.forge-snapshots/PositionManager_burn_empty_native.snap @@ -1 +1 @@ -46909 \ No newline at end of file +46876 \ No newline at end of file diff --git a/.forge-snapshots/PositionManager_burn_nonEmpty.snap b/.forge-snapshots/PositionManager_burn_nonEmpty.snap index b7cdf0170..c15f4f2dc 100644 --- a/.forge-snapshots/PositionManager_burn_nonEmpty.snap +++ b/.forge-snapshots/PositionManager_burn_nonEmpty.snap @@ -1 +1 @@ -129884 \ No newline at end of file +129852 \ No newline at end of file diff --git a/.forge-snapshots/PositionManager_burn_nonEmpty_native.snap b/.forge-snapshots/PositionManager_burn_nonEmpty_native.snap index d431e401c..d2ae1c7d4 100644 --- a/.forge-snapshots/PositionManager_burn_nonEmpty_native.snap +++ b/.forge-snapshots/PositionManager_burn_nonEmpty_native.snap @@ -1 +1 @@ -122806 \ No newline at end of file +122773 \ No newline at end of file diff --git a/.forge-snapshots/PositionManager_collect.snap b/.forge-snapshots/PositionManager_collect.snap index e33b55453..0cf00f2ad 100644 --- a/.forge-snapshots/PositionManager_collect.snap +++ b/.forge-snapshots/PositionManager_collect.snap @@ -1 +1 @@ -150025 \ No newline at end of file +149984 \ No newline at end of file diff --git a/.forge-snapshots/PositionManager_collect_native.snap b/.forge-snapshots/PositionManager_collect_native.snap index 1580a3486..1b627db8b 100644 --- a/.forge-snapshots/PositionManager_collect_native.snap +++ b/.forge-snapshots/PositionManager_collect_native.snap @@ -1 +1 @@ -141177 \ No newline at end of file +141136 \ No newline at end of file diff --git a/.forge-snapshots/PositionManager_collect_sameRange.snap b/.forge-snapshots/PositionManager_collect_sameRange.snap index e33b55453..0cf00f2ad 100644 --- a/.forge-snapshots/PositionManager_collect_sameRange.snap +++ b/.forge-snapshots/PositionManager_collect_sameRange.snap @@ -1 +1 @@ -150025 \ No newline at end of file +149984 \ No newline at end of file diff --git a/.forge-snapshots/PositionManager_decreaseLiquidity.snap b/.forge-snapshots/PositionManager_decreaseLiquidity.snap index 1c1593d1e..c30fc9dee 100644 --- a/.forge-snapshots/PositionManager_decreaseLiquidity.snap +++ b/.forge-snapshots/PositionManager_decreaseLiquidity.snap @@ -1 +1 @@ -115568 \ No newline at end of file +115527 \ No newline at end of file diff --git a/.forge-snapshots/PositionManager_decreaseLiquidity_native.snap b/.forge-snapshots/PositionManager_decreaseLiquidity_native.snap index 319c4877d..3c0e3daf0 100644 --- a/.forge-snapshots/PositionManager_decreaseLiquidity_native.snap +++ b/.forge-snapshots/PositionManager_decreaseLiquidity_native.snap @@ -1 +1 @@ -108416 \ No newline at end of file +108384 \ No newline at end of file diff --git a/.forge-snapshots/PositionManager_decrease_burnEmpty.snap b/.forge-snapshots/PositionManager_decrease_burnEmpty.snap index 2b39a06db..58fe18442 100644 --- a/.forge-snapshots/PositionManager_decrease_burnEmpty.snap +++ b/.forge-snapshots/PositionManager_decrease_burnEmpty.snap @@ -1 +1 @@ -133918 \ No newline at end of file +133885 \ No newline at end of file diff --git a/.forge-snapshots/PositionManager_decrease_burnEmpty_native.snap b/.forge-snapshots/PositionManager_decrease_burnEmpty_native.snap index f83add2a1..23aac82f0 100644 --- a/.forge-snapshots/PositionManager_decrease_burnEmpty_native.snap +++ b/.forge-snapshots/PositionManager_decrease_burnEmpty_native.snap @@ -1 +1 @@ -126657 \ No newline at end of file +126624 \ No newline at end of file diff --git a/.forge-snapshots/PositionManager_decrease_sameRange_allLiquidity.snap b/.forge-snapshots/PositionManager_decrease_sameRange_allLiquidity.snap index 75cc3313d..48ed66878 100644 --- a/.forge-snapshots/PositionManager_decrease_sameRange_allLiquidity.snap +++ b/.forge-snapshots/PositionManager_decrease_sameRange_allLiquidity.snap @@ -1 +1 @@ -128284 \ No newline at end of file +128243 \ No newline at end of file diff --git a/.forge-snapshots/PositionManager_increaseLiquidity_erc20_withClose.snap b/.forge-snapshots/PositionManager_increaseLiquidity_erc20_withClose.snap index c749113b5..267233964 100644 --- a/.forge-snapshots/PositionManager_increaseLiquidity_erc20_withClose.snap +++ b/.forge-snapshots/PositionManager_increaseLiquidity_erc20_withClose.snap @@ -1 +1 @@ -152141 \ No newline at end of file +152100 \ No newline at end of file diff --git a/.forge-snapshots/PositionManager_increaseLiquidity_erc20_withSettlePair.snap b/.forge-snapshots/PositionManager_increaseLiquidity_erc20_withSettlePair.snap index 2e341ff2a..6ce3534b4 100644 --- a/.forge-snapshots/PositionManager_increaseLiquidity_erc20_withSettlePair.snap +++ b/.forge-snapshots/PositionManager_increaseLiquidity_erc20_withSettlePair.snap @@ -1 +1 @@ -152344 \ No newline at end of file +151341 \ No newline at end of file diff --git a/.forge-snapshots/PositionManager_increaseLiquidity_native.snap b/.forge-snapshots/PositionManager_increaseLiquidity_native.snap index e8b34b1f8..35295eaff 100644 --- a/.forge-snapshots/PositionManager_increaseLiquidity_native.snap +++ b/.forge-snapshots/PositionManager_increaseLiquidity_native.snap @@ -1 +1 @@ -133941 \ No newline at end of file +133900 \ No newline at end of file diff --git a/.forge-snapshots/PositionManager_increase_autocompoundExactUnclaimedFees.snap b/.forge-snapshots/PositionManager_increase_autocompoundExactUnclaimedFees.snap index 6913dd59b..04c138b3d 100644 --- a/.forge-snapshots/PositionManager_increase_autocompoundExactUnclaimedFees.snap +++ b/.forge-snapshots/PositionManager_increase_autocompoundExactUnclaimedFees.snap @@ -1 +1 @@ -130106 \ No newline at end of file +130065 \ No newline at end of file diff --git a/.forge-snapshots/PositionManager_increase_autocompoundExcessFeesCredit.snap b/.forge-snapshots/PositionManager_increase_autocompoundExcessFeesCredit.snap index 8b1ec079c..e55d62578 100644 --- a/.forge-snapshots/PositionManager_increase_autocompoundExcessFeesCredit.snap +++ b/.forge-snapshots/PositionManager_increase_autocompoundExcessFeesCredit.snap @@ -1 +1 @@ -170800 \ No newline at end of file +170759 \ No newline at end of file diff --git a/.forge-snapshots/PositionManager_increase_autocompound_clearExcess.snap b/.forge-snapshots/PositionManager_increase_autocompound_clearExcess.snap index 815cd2fa2..375f518b7 100644 --- a/.forge-snapshots/PositionManager_increase_autocompound_clearExcess.snap +++ b/.forge-snapshots/PositionManager_increase_autocompound_clearExcess.snap @@ -1 +1 @@ -140622 \ No newline at end of file +140581 \ No newline at end of file diff --git a/.forge-snapshots/PositionManager_mint_native.snap b/.forge-snapshots/PositionManager_mint_native.snap index 96d04a797..e708094ba 100644 --- a/.forge-snapshots/PositionManager_mint_native.snap +++ b/.forge-snapshots/PositionManager_mint_native.snap @@ -1 +1 @@ -336753 \ No newline at end of file +336712 \ No newline at end of file diff --git a/.forge-snapshots/PositionManager_mint_nativeWithSweep_withClose.snap b/.forge-snapshots/PositionManager_mint_nativeWithSweep_withClose.snap index a9d71fb93..378d9bfb1 100644 --- a/.forge-snapshots/PositionManager_mint_nativeWithSweep_withClose.snap +++ b/.forge-snapshots/PositionManager_mint_nativeWithSweep_withClose.snap @@ -1 +1 @@ -345308 \ No newline at end of file +345267 \ No newline at end of file diff --git a/.forge-snapshots/PositionManager_mint_nativeWithSweep_withSettlePair.snap b/.forge-snapshots/PositionManager_mint_nativeWithSweep_withSettlePair.snap index 699aa1f73..9f308f43c 100644 --- a/.forge-snapshots/PositionManager_mint_nativeWithSweep_withSettlePair.snap +++ b/.forge-snapshots/PositionManager_mint_nativeWithSweep_withSettlePair.snap @@ -1 +1 @@ -345535 \ No newline at end of file +344532 \ No newline at end of file diff --git a/.forge-snapshots/PositionManager_mint_onSameTickLower.snap b/.forge-snapshots/PositionManager_mint_onSameTickLower.snap index 683690a21..90fd8fec4 100644 --- a/.forge-snapshots/PositionManager_mint_onSameTickLower.snap +++ b/.forge-snapshots/PositionManager_mint_onSameTickLower.snap @@ -1 +1 @@ -314735 \ No newline at end of file +314694 \ No newline at end of file diff --git a/.forge-snapshots/PositionManager_mint_onSameTickUpper.snap b/.forge-snapshots/PositionManager_mint_onSameTickUpper.snap index a24ca951a..9b6845afb 100644 --- a/.forge-snapshots/PositionManager_mint_onSameTickUpper.snap +++ b/.forge-snapshots/PositionManager_mint_onSameTickUpper.snap @@ -1 +1 @@ -315377 \ No newline at end of file +315336 \ No newline at end of file diff --git a/.forge-snapshots/PositionManager_mint_sameRange.snap b/.forge-snapshots/PositionManager_mint_sameRange.snap index 0c320de4e..597983b55 100644 --- a/.forge-snapshots/PositionManager_mint_sameRange.snap +++ b/.forge-snapshots/PositionManager_mint_sameRange.snap @@ -1 +1 @@ -240959 \ No newline at end of file +240918 \ No newline at end of file diff --git a/.forge-snapshots/PositionManager_mint_settleWithBalance_sweep.snap b/.forge-snapshots/PositionManager_mint_settleWithBalance_sweep.snap index 7c7156698..817d77abd 100644 --- a/.forge-snapshots/PositionManager_mint_settleWithBalance_sweep.snap +++ b/.forge-snapshots/PositionManager_mint_settleWithBalance_sweep.snap @@ -1 +1 @@ -370105 \ No newline at end of file +370064 \ No newline at end of file diff --git a/.forge-snapshots/PositionManager_mint_warmedPool_differentRange.snap b/.forge-snapshots/PositionManager_mint_warmedPool_differentRange.snap index c015cf17b..af4a8aa0c 100644 --- a/.forge-snapshots/PositionManager_mint_warmedPool_differentRange.snap +++ b/.forge-snapshots/PositionManager_mint_warmedPool_differentRange.snap @@ -1 +1 @@ -320753 \ No newline at end of file +320712 \ No newline at end of file diff --git a/.forge-snapshots/PositionManager_mint_withClose.snap b/.forge-snapshots/PositionManager_mint_withClose.snap index 78db2c60a..7e0f6688a 100644 --- a/.forge-snapshots/PositionManager_mint_withClose.snap +++ b/.forge-snapshots/PositionManager_mint_withClose.snap @@ -1 +1 @@ -372053 \ No newline at end of file +372012 \ No newline at end of file diff --git a/.forge-snapshots/PositionManager_mint_withSettlePair.snap b/.forge-snapshots/PositionManager_mint_withSettlePair.snap index 3eb70c9c6..99ea27ab7 100644 --- a/.forge-snapshots/PositionManager_mint_withSettlePair.snap +++ b/.forge-snapshots/PositionManager_mint_withSettlePair.snap @@ -1 +1 @@ -372256 \ No newline at end of file +371253 \ No newline at end of file diff --git a/.forge-snapshots/PositionManager_multicall_initialize_mint.snap b/.forge-snapshots/PositionManager_multicall_initialize_mint.snap index 3c6426895..28856ebdf 100644 --- a/.forge-snapshots/PositionManager_multicall_initialize_mint.snap +++ b/.forge-snapshots/PositionManager_multicall_initialize_mint.snap @@ -1 +1 @@ -416429 \ No newline at end of file +416388 \ No newline at end of file diff --git a/src/PositionManager.sol b/src/PositionManager.sol index 23a571962..285493f5f 100644 --- a/src/PositionManager.sol +++ b/src/PositionManager.sol @@ -26,7 +26,6 @@ import {BaseActionsRouter} from "./base/BaseActionsRouter.sol"; import {Actions} from "./libraries/Actions.sol"; import {CalldataDecoder} from "./libraries/CalldataDecoder.sol"; import {SlippageCheckLibrary} from "./libraries/SlippageCheck.sol"; -import {CurrencyDeltas} from "./libraries/CurrencyDeltas.sol"; contract PositionManager is IPositionManager, @@ -46,7 +45,6 @@ contract PositionManager is using SafeCast for uint256; using CalldataDecoder for bytes; using SlippageCheckLibrary for BalanceDelta; - using CurrencyDeltas for IPoolManager; /// @dev The ID of the next token that will be minted. Skips 0 uint256 public nextTokenId = 1; @@ -229,9 +227,8 @@ contract PositionManager is function _settlePair(Currency currency0, Currency currency1) internal { // the locker is the payer when settling address caller = _msgSender(); - BalanceDelta delta = poolManager.currencyDeltas(address(this), currency0, currency1); - _settle(currency0, caller, uint256(int256(-delta.amount0()))); - _settle(currency1, caller, uint256(int256(-delta.amount1()))); + _settle(currency0, caller, _getFullSettleAmount(currency0)); + _settle(currency1, caller, _getFullSettleAmount(currency1)); } /// @dev this is overloaded with ERC721Permit._burn diff --git a/src/libraries/CurrencyDeltas.sol b/src/libraries/CurrencyDeltas.sol deleted file mode 100644 index 2a7b85f80..000000000 --- a/src/libraries/CurrencyDeltas.sol +++ /dev/null @@ -1,42 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.21; - -import {IPoolManager} from "@uniswap/v4-core/src/interfaces/IPoolManager.sol"; -import {Currency} from "@uniswap/v4-core/src/types/Currency.sol"; -import {BalanceDelta, toBalanceDelta} from "@uniswap/v4-core/src/types/BalanceDelta.sol"; -import {SafeCast} from "@uniswap/v4-core/src/libraries/SafeCast.sol"; - -/// @title Currency Deltas -/// @notice Fetch two currency deltas in a single call -library CurrencyDeltas { - using SafeCast for int256; - - /// @notice Get the current delta for a caller in the two given currencies - /// @param _caller The address of the caller - /// @param currency0 The currency to lookup the delta - /// @param currency1 The other currency to lookup the delta - /// @return BalanceDelta The delta of the two currencies packed - /// amount0 corresponding to currency0 and amount1 corresponding to currency1 - function currencyDeltas(IPoolManager manager, address _caller, Currency currency0, Currency currency1) - internal - view - returns (BalanceDelta) - { - bytes32 tloadSlot0; - bytes32 tloadSlot1; - assembly { - mstore(0, _caller) - mstore(32, currency0) - tloadSlot0 := keccak256(0, 64) - - mstore(0, _caller) - mstore(32, currency1) - tloadSlot1 := keccak256(0, 64) - } - bytes32[] memory slots = new bytes32[](2); - slots[0] = tloadSlot0; - slots[1] = tloadSlot1; - bytes32[] memory result = manager.exttload(slots); - return toBalanceDelta(int256(uint256(result[0])).toInt128(), int256(uint256(result[1])).toInt128()); - } -} diff --git a/test/libraries/CurrencyDeltas.t.sol b/test/libraries/CurrencyDeltas.t.sol deleted file mode 100644 index 53dad9e45..000000000 --- a/test/libraries/CurrencyDeltas.t.sol +++ /dev/null @@ -1,82 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.24; - -import "forge-std/Test.sol"; -import {IERC20} from "forge-std/interfaces/IERC20.sol"; -import {IPoolManager} from "@uniswap/v4-core/src/interfaces/IPoolManager.sol"; -import {BalanceDelta} from "@uniswap/v4-core/src/types/BalanceDelta.sol"; -import {Currency, CurrencyLibrary} from "@uniswap/v4-core/src/types/Currency.sol"; -import {StateLibrary} from "@uniswap/v4-core/src/libraries/StateLibrary.sol"; -import {Deployers} from "@uniswap/v4-core/test/utils/Deployers.sol"; - -import {MockCurrencyDeltaReader} from "../mocks/MockCurrencyDeltaReader.sol"; - -contract CurrencyDeltasTest is Test, Deployers { - using CurrencyLibrary for Currency; - - MockCurrencyDeltaReader reader; - - function setUp() public { - deployFreshManagerAndRouters(); - deployMintAndApprove2Currencies(); - - reader = new MockCurrencyDeltaReader(manager); - - IERC20 token0 = IERC20(Currency.unwrap(currency0)); - IERC20 token1 = IERC20(Currency.unwrap(currency1)); - - token0.approve(address(reader), type(uint256).max); - token1.approve(address(reader), type(uint256).max); - - // send tokens to PoolManager so tests can .take() - token0.transfer(address(manager), 1_000_000e18); - token1.transfer(address(manager), 1_000_000e18); - - // convert some ERC20s into ERC6909 - claimsRouter.deposit(currency0, address(this), 1_000_000e18); - claimsRouter.deposit(currency1, address(this), 1_000_000e18); - manager.approve(address(reader), currency0.toId(), type(uint256).max); - manager.approve(address(reader), currency1.toId(), type(uint256).max); - } - - function test_fuzz_currencyDeltas(uint8 depth, uint256 seed, uint128 amount0, uint128 amount1) public { - int128 delta0Expected = 0; - int128 delta1Expected = 0; - - bytes[] memory calls = new bytes[](depth); - for (uint256 i = 0; i < depth; i++) { - amount0 = uint128(bound(amount0, 1, 100e18)); - amount1 = uint128(bound(amount1, 1, 100e18)); - uint256 _seed = seed % (i + 1); - if (_seed % 8 == 0) { - calls[i] = abi.encodeWithSelector(MockCurrencyDeltaReader.settle.selector, currency0, amount0); - delta0Expected += int128(amount0); - } else if (_seed % 8 == 1) { - calls[i] = abi.encodeWithSelector(MockCurrencyDeltaReader.settle.selector, currency1, amount1); - delta1Expected += int128(amount1); - } else if (_seed % 8 == 2) { - calls[i] = abi.encodeWithSelector(MockCurrencyDeltaReader.burn.selector, currency0, amount0); - delta0Expected += int128(amount0); - } else if (_seed % 8 == 3) { - calls[i] = abi.encodeWithSelector(MockCurrencyDeltaReader.burn.selector, currency1, amount1); - delta1Expected += int128(amount1); - } else if (_seed % 8 == 4) { - calls[i] = abi.encodeWithSelector(MockCurrencyDeltaReader.take.selector, currency0, amount0); - delta0Expected -= int128(amount0); - } else if (_seed % 8 == 5) { - calls[i] = abi.encodeWithSelector(MockCurrencyDeltaReader.take.selector, currency1, amount1); - delta1Expected -= int128(amount1); - } else if (_seed % 8 == 6) { - calls[i] = abi.encodeWithSelector(MockCurrencyDeltaReader.mint.selector, currency0, amount0); - delta0Expected -= int128(amount0); - } else if (_seed % 8 == 7) { - calls[i] = abi.encodeWithSelector(MockCurrencyDeltaReader.mint.selector, currency1, amount1); - delta1Expected -= int128(amount1); - } - } - - BalanceDelta delta = reader.execute(calls, currency0, currency1); - assertEq(delta.amount0(), delta0Expected); - assertEq(delta.amount1(), delta1Expected); - } -} diff --git a/test/mocks/MockCurrencyDeltaReader.sol b/test/mocks/MockCurrencyDeltaReader.sol deleted file mode 100644 index 94aa3db77..000000000 --- a/test/mocks/MockCurrencyDeltaReader.sol +++ /dev/null @@ -1,71 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.24; - -import {IPoolManager} from "@uniswap/v4-core/src/interfaces/IPoolManager.sol"; -import {BalanceDelta} from "@uniswap/v4-core/src/types/BalanceDelta.sol"; -import {Currency} from "@uniswap/v4-core/src/types/Currency.sol"; -import {TransientStateLibrary} from "@uniswap/v4-core/src/libraries/TransientStateLibrary.sol"; -import {Deployers} from "@uniswap/v4-core/test/utils/Deployers.sol"; -import {CurrencySettler} from "@uniswap/v4-core/test/utils/CurrencySettler.sol"; - -import {CurrencyDeltas} from "../../src/libraries/CurrencyDeltas.sol"; - -/// @dev A minimal helper strictly for testing -contract MockCurrencyDeltaReader { - using TransientStateLibrary for IPoolManager; - using CurrencyDeltas for IPoolManager; - using CurrencySettler for Currency; - - IPoolManager public poolManager; - - address sender; - - constructor(IPoolManager _poolManager) { - poolManager = _poolManager; - } - - /// @param calls an array of abi.encodeWithSelector - function execute(bytes[] calldata calls, Currency currency0, Currency currency1) external returns (BalanceDelta) { - sender = msg.sender; - return abi.decode(poolManager.unlock(abi.encode(calls, currency0, currency1)), (BalanceDelta)); - } - - function unlockCallback(bytes calldata data) external returns (bytes memory) { - (bytes[] memory calls, Currency currency0, Currency currency1) = abi.decode(data, (bytes[], Currency, Currency)); - for (uint256 i; i < calls.length; i++) { - (bool success,) = address(this).call(calls[i]); - if (!success) revert("CurrencyDeltaReader"); - } - - BalanceDelta delta = poolManager.currencyDeltas(address(this), currency0, currency1); - int256 delta0 = poolManager.currencyDelta(address(this), currency0); - int256 delta1 = poolManager.currencyDelta(address(this), currency1); - - // confirm agreement between currencyDeltas and single-read currencyDelta - require(delta.amount0() == int128(delta0), "CurrencyDeltaReader: delta0"); - require(delta.amount1() == int128(delta1), "CurrencyDeltaReader: delta1"); - - // close deltas - if (delta.amount0() < 0) currency0.settle(poolManager, sender, uint256(-int256(delta.amount0())), false); - if (delta.amount1() < 0) currency1.settle(poolManager, sender, uint256(-int256(delta.amount1())), false); - if (delta.amount0() > 0) currency0.take(poolManager, sender, uint256(int256(delta.amount0())), false); - if (delta.amount1() > 0) currency1.take(poolManager, sender, uint256(int256(delta.amount1())), false); - return abi.encode(delta); - } - - function settle(Currency currency, uint256 amount) external { - currency.settle(poolManager, sender, amount, false); - } - - function burn(Currency currency, uint256 amount) external { - currency.settle(poolManager, sender, amount, true); - } - - function take(Currency currency, uint256 amount) external { - currency.take(poolManager, sender, amount, false); - } - - function mint(Currency currency, uint256 amount) external { - currency.take(poolManager, sender, amount, true); - } -}