From 4ac5f57a5dab46ba4c818f7b88992a6aca3b6419 Mon Sep 17 00:00:00 2001 From: Sara Reynolds <30504811+snreynolds@users.noreply.github.com> Date: Mon, 25 Nov 2024 17:07:48 +0000 Subject: [PATCH] use notifyBurn (#399) * use notifyBurn * rename * update bytecode --- .../PositionManager_burn_empty.snap | 2 +- .../PositionManager_burn_empty_native.snap | 2 +- ...anager_burn_nonEmpty_native_withClose.snap | 2 +- ...ger_burn_nonEmpty_native_withTakePair.snap | 2 +- ...sitionManager_burn_nonEmpty_withClose.snap | 2 +- ...ionManager_burn_nonEmpty_withTakePair.snap | 2 +- .../PositionManager_collect_native.snap | 2 +- .../PositionManager_collect_sameRange.snap | 2 +- .../PositionManager_collect_withClose.snap | 2 +- .../PositionManager_collect_withTakePair.snap | 2 +- ...itionManager_decreaseLiquidity_native.snap | 2 +- ...onManager_decreaseLiquidity_withClose.snap | 2 +- ...anager_decreaseLiquidity_withTakePair.snap | 2 +- .../PositionManager_decrease_burnEmpty.snap | 2 +- ...tionManager_decrease_burnEmpty_native.snap | 2 +- ...nager_decrease_sameRange_allLiquidity.snap | 2 +- .../PositionManager_decrease_take_take.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 +- .../PositionManager_unsubscribe.snap | 2 +- src/PositionManager.sol | 21 +++++++++++++--- src/base/Notifier.sol | 24 +++++++++++++++++++ src/interfaces/INotifier.sol | 2 ++ src/interfaces/ISubscriber.sol | 9 +++++++ test/mocks/MockBadSubscribers.sol | 13 ++++++++++ test/mocks/MockSubscriber.sol | 9 +++++++ .../PositionManager.notifier.t.sol | 9 +++---- 42 files changed, 115 insertions(+), 42 deletions(-) diff --git a/.forge-snapshots/PositionManager_burn_empty.snap b/.forge-snapshots/PositionManager_burn_empty.snap index 2479c983..fcb81926 100644 --- a/.forge-snapshots/PositionManager_burn_empty.snap +++ b/.forge-snapshots/PositionManager_burn_empty.snap @@ -1 +1 @@ -50540 \ No newline at end of file +50845 \ 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 2479c983..fcb81926 100644 --- a/.forge-snapshots/PositionManager_burn_empty_native.snap +++ b/.forge-snapshots/PositionManager_burn_empty_native.snap @@ -1 +1 @@ -50540 \ No newline at end of file +50845 \ No newline at end of file diff --git a/.forge-snapshots/PositionManager_burn_nonEmpty_native_withClose.snap b/.forge-snapshots/PositionManager_burn_nonEmpty_native_withClose.snap index 7ec59583..9c88356c 100644 --- a/.forge-snapshots/PositionManager_burn_nonEmpty_native_withClose.snap +++ b/.forge-snapshots/PositionManager_burn_nonEmpty_native_withClose.snap @@ -1 +1 @@ -125788 \ No newline at end of file +126075 \ No newline at end of file diff --git a/.forge-snapshots/PositionManager_burn_nonEmpty_native_withTakePair.snap b/.forge-snapshots/PositionManager_burn_nonEmpty_native_withTakePair.snap index 5218895c..0c610d43 100644 --- a/.forge-snapshots/PositionManager_burn_nonEmpty_native_withTakePair.snap +++ b/.forge-snapshots/PositionManager_burn_nonEmpty_native_withTakePair.snap @@ -1 +1 @@ -125220 \ No newline at end of file +125508 \ No newline at end of file diff --git a/.forge-snapshots/PositionManager_burn_nonEmpty_withClose.snap b/.forge-snapshots/PositionManager_burn_nonEmpty_withClose.snap index 1be09a21..02c6f586 100644 --- a/.forge-snapshots/PositionManager_burn_nonEmpty_withClose.snap +++ b/.forge-snapshots/PositionManager_burn_nonEmpty_withClose.snap @@ -1 +1 @@ -132648 \ No newline at end of file +132935 \ No newline at end of file diff --git a/.forge-snapshots/PositionManager_burn_nonEmpty_withTakePair.snap b/.forge-snapshots/PositionManager_burn_nonEmpty_withTakePair.snap index 7c6408e3..5d1c4b28 100644 --- a/.forge-snapshots/PositionManager_burn_nonEmpty_withTakePair.snap +++ b/.forge-snapshots/PositionManager_burn_nonEmpty_withTakePair.snap @@ -1 +1 @@ -132080 \ No newline at end of file +132368 \ No newline at end of file diff --git a/.forge-snapshots/PositionManager_collect_native.snap b/.forge-snapshots/PositionManager_collect_native.snap index 40f4aecb..300b94d2 100644 --- a/.forge-snapshots/PositionManager_collect_native.snap +++ b/.forge-snapshots/PositionManager_collect_native.snap @@ -1 +1 @@ -146518 \ No newline at end of file +146517 \ No newline at end of file diff --git a/.forge-snapshots/PositionManager_collect_sameRange.snap b/.forge-snapshots/PositionManager_collect_sameRange.snap index 3a0b4f70..9d8c45b6 100644 --- a/.forge-snapshots/PositionManager_collect_sameRange.snap +++ b/.forge-snapshots/PositionManager_collect_sameRange.snap @@ -1 +1 @@ -155093 \ No newline at end of file +155092 \ No newline at end of file diff --git a/.forge-snapshots/PositionManager_collect_withClose.snap b/.forge-snapshots/PositionManager_collect_withClose.snap index 3a0b4f70..9d8c45b6 100644 --- a/.forge-snapshots/PositionManager_collect_withClose.snap +++ b/.forge-snapshots/PositionManager_collect_withClose.snap @@ -1 +1 @@ -155093 \ No newline at end of file +155092 \ No newline at end of file diff --git a/.forge-snapshots/PositionManager_collect_withTakePair.snap b/.forge-snapshots/PositionManager_collect_withTakePair.snap index 3e9ec783..3a772220 100644 --- a/.forge-snapshots/PositionManager_collect_withTakePair.snap +++ b/.forge-snapshots/PositionManager_collect_withTakePair.snap @@ -1 +1 @@ -154396 \ No newline at end of file +154395 \ No newline at end of file diff --git a/.forge-snapshots/PositionManager_decreaseLiquidity_native.snap b/.forge-snapshots/PositionManager_decreaseLiquidity_native.snap index ba0b210d..03b97f2f 100644 --- a/.forge-snapshots/PositionManager_decreaseLiquidity_native.snap +++ b/.forge-snapshots/PositionManager_decreaseLiquidity_native.snap @@ -1 +1 @@ -112160 \ No newline at end of file +112159 \ No newline at end of file diff --git a/.forge-snapshots/PositionManager_decreaseLiquidity_withClose.snap b/.forge-snapshots/PositionManager_decreaseLiquidity_withClose.snap index 8f0ff9be..48ff8dce 100644 --- a/.forge-snapshots/PositionManager_decreaseLiquidity_withClose.snap +++ b/.forge-snapshots/PositionManager_decreaseLiquidity_withClose.snap @@ -1 +1 @@ -119974 \ No newline at end of file +119973 \ No newline at end of file diff --git a/.forge-snapshots/PositionManager_decreaseLiquidity_withTakePair.snap b/.forge-snapshots/PositionManager_decreaseLiquidity_withTakePair.snap index 323d58aa..c576e745 100644 --- a/.forge-snapshots/PositionManager_decreaseLiquidity_withTakePair.snap +++ b/.forge-snapshots/PositionManager_decreaseLiquidity_withTakePair.snap @@ -1 +1 @@ -119277 \ No newline at end of file +119276 \ No newline at end of file diff --git a/.forge-snapshots/PositionManager_decrease_burnEmpty.snap b/.forge-snapshots/PositionManager_decrease_burnEmpty.snap index 92d88d4a..d997832e 100644 --- a/.forge-snapshots/PositionManager_decrease_burnEmpty.snap +++ b/.forge-snapshots/PositionManager_decrease_burnEmpty.snap @@ -1 +1 @@ -135480 \ No newline at end of file +135785 \ 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 5c195ecc..178defb9 100644 --- a/.forge-snapshots/PositionManager_decrease_burnEmpty_native.snap +++ b/.forge-snapshots/PositionManager_decrease_burnEmpty_native.snap @@ -1 +1 @@ -128620 \ No newline at end of file +128925 \ 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 de446de0..5067e921 100644 --- a/.forge-snapshots/PositionManager_decrease_sameRange_allLiquidity.snap +++ b/.forge-snapshots/PositionManager_decrease_sameRange_allLiquidity.snap @@ -1 +1 @@ -132661 \ No newline at end of file +132660 \ No newline at end of file diff --git a/.forge-snapshots/PositionManager_decrease_take_take.snap b/.forge-snapshots/PositionManager_decrease_take_take.snap index c1f9fc28..1704633b 100644 --- a/.forge-snapshots/PositionManager_decrease_take_take.snap +++ b/.forge-snapshots/PositionManager_decrease_take_take.snap @@ -1 +1 @@ -120564 \ No newline at end of file +120563 \ 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 07d41e53..e041bfa5 100644 --- a/.forge-snapshots/PositionManager_increaseLiquidity_erc20_withClose.snap +++ b/.forge-snapshots/PositionManager_increaseLiquidity_erc20_withClose.snap @@ -1 +1 @@ -158973 \ No newline at end of file +158972 \ 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 f3733866..4218521c 100644 --- a/.forge-snapshots/PositionManager_increaseLiquidity_erc20_withSettlePair.snap +++ b/.forge-snapshots/PositionManager_increaseLiquidity_erc20_withSettlePair.snap @@ -1 +1 @@ -157884 \ No newline at end of file +157883 \ No newline at end of file diff --git a/.forge-snapshots/PositionManager_increaseLiquidity_native.snap b/.forge-snapshots/PositionManager_increaseLiquidity_native.snap index 43a1de11..173f0fd1 100644 --- a/.forge-snapshots/PositionManager_increaseLiquidity_native.snap +++ b/.forge-snapshots/PositionManager_increaseLiquidity_native.snap @@ -1 +1 @@ -142237 \ No newline at end of file +142236 \ No newline at end of file diff --git a/.forge-snapshots/PositionManager_increase_autocompoundExactUnclaimedFees.snap b/.forge-snapshots/PositionManager_increase_autocompoundExactUnclaimedFees.snap index 15b5ab6c..65400e18 100644 --- a/.forge-snapshots/PositionManager_increase_autocompoundExactUnclaimedFees.snap +++ b/.forge-snapshots/PositionManager_increase_autocompoundExactUnclaimedFees.snap @@ -1 +1 @@ -136418 \ No newline at end of file +136417 \ No newline at end of file diff --git a/.forge-snapshots/PositionManager_increase_autocompoundExcessFeesCredit.snap b/.forge-snapshots/PositionManager_increase_autocompoundExcessFeesCredit.snap index 81df070a..c100c3a7 100644 --- a/.forge-snapshots/PositionManager_increase_autocompoundExcessFeesCredit.snap +++ b/.forge-snapshots/PositionManager_increase_autocompoundExcessFeesCredit.snap @@ -1 +1 @@ -177562 \ No newline at end of file +177561 \ 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 3abe5dbd..f780123b 100644 --- a/.forge-snapshots/PositionManager_increase_autocompound_clearExcess.snap +++ b/.forge-snapshots/PositionManager_increase_autocompound_clearExcess.snap @@ -1 +1 @@ -148338 \ No newline at end of file +148337 \ No newline at end of file diff --git a/.forge-snapshots/PositionManager_mint_native.snap b/.forge-snapshots/PositionManager_mint_native.snap index 9258b17f..fd7f97d4 100644 --- a/.forge-snapshots/PositionManager_mint_native.snap +++ b/.forge-snapshots/PositionManager_mint_native.snap @@ -1 +1 @@ -366111 \ No newline at end of file +366110 \ 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 571f3e49..d5189274 100644 --- a/.forge-snapshots/PositionManager_mint_nativeWithSweep_withClose.snap +++ b/.forge-snapshots/PositionManager_mint_nativeWithSweep_withClose.snap @@ -1 +1 @@ -374685 \ No newline at end of file +374684 \ 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 9f80774d..4bc4b7b3 100644 --- a/.forge-snapshots/PositionManager_mint_nativeWithSweep_withSettlePair.snap +++ b/.forge-snapshots/PositionManager_mint_nativeWithSweep_withSettlePair.snap @@ -1 +1 @@ -373880 \ No newline at end of file +373879 \ No newline at end of file diff --git a/.forge-snapshots/PositionManager_mint_onSameTickLower.snap b/.forge-snapshots/PositionManager_mint_onSameTickLower.snap index 62bd3d80..1dbf1cac 100644 --- a/.forge-snapshots/PositionManager_mint_onSameTickLower.snap +++ b/.forge-snapshots/PositionManager_mint_onSameTickLower.snap @@ -1 +1 @@ -317534 \ No newline at end of file +317533 \ No newline at end of file diff --git a/.forge-snapshots/PositionManager_mint_onSameTickUpper.snap b/.forge-snapshots/PositionManager_mint_onSameTickUpper.snap index dd8c88a2..762eabe2 100644 --- a/.forge-snapshots/PositionManager_mint_onSameTickUpper.snap +++ b/.forge-snapshots/PositionManager_mint_onSameTickUpper.snap @@ -1 +1 @@ -318204 \ No newline at end of file +318203 \ No newline at end of file diff --git a/.forge-snapshots/PositionManager_mint_sameRange.snap b/.forge-snapshots/PositionManager_mint_sameRange.snap index ade21eeb..79c42629 100644 --- a/.forge-snapshots/PositionManager_mint_sameRange.snap +++ b/.forge-snapshots/PositionManager_mint_sameRange.snap @@ -1 +1 @@ -243773 \ No newline at end of file +243772 \ 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 7d6b5503..1a107995 100644 --- a/.forge-snapshots/PositionManager_mint_settleWithBalance_sweep.snap +++ b/.forge-snapshots/PositionManager_mint_settleWithBalance_sweep.snap @@ -1 +1 @@ -419063 \ No newline at end of file +419062 \ 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 95c1d778..51af8572 100644 --- a/.forge-snapshots/PositionManager_mint_warmedPool_differentRange.snap +++ b/.forge-snapshots/PositionManager_mint_warmedPool_differentRange.snap @@ -1 +1 @@ -323565 \ No newline at end of file +323564 \ No newline at end of file diff --git a/.forge-snapshots/PositionManager_mint_withClose.snap b/.forge-snapshots/PositionManager_mint_withClose.snap index 189188dc..3fa2f80f 100644 --- a/.forge-snapshots/PositionManager_mint_withClose.snap +++ b/.forge-snapshots/PositionManager_mint_withClose.snap @@ -1 +1 @@ -420087 \ No newline at end of file +420086 \ No newline at end of file diff --git a/.forge-snapshots/PositionManager_mint_withSettlePair.snap b/.forge-snapshots/PositionManager_mint_withSettlePair.snap index eb86505b..530393d3 100644 --- a/.forge-snapshots/PositionManager_mint_withSettlePair.snap +++ b/.forge-snapshots/PositionManager_mint_withSettlePair.snap @@ -1 +1 @@ -419116 \ No newline at end of file +419115 \ 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 175d70ef..db9aea25 100644 --- a/.forge-snapshots/PositionManager_multicall_initialize_mint.snap +++ b/.forge-snapshots/PositionManager_multicall_initialize_mint.snap @@ -1 +1 @@ -455917 \ No newline at end of file +455916 \ No newline at end of file diff --git a/.forge-snapshots/PositionManager_unsubscribe.snap b/.forge-snapshots/PositionManager_unsubscribe.snap index c9bfebd4..ef5e368e 100644 --- a/.forge-snapshots/PositionManager_unsubscribe.snap +++ b/.forge-snapshots/PositionManager_unsubscribe.snap @@ -1 +1 @@ -63036 \ No newline at end of file +63058 \ No newline at end of file diff --git a/src/PositionManager.sol b/src/PositionManager.sol index 58efd722..dfe6e8f0 100644 --- a/src/PositionManager.sol +++ b/src/PositionManager.sol @@ -411,20 +411,34 @@ contract PositionManager is uint256 liquidity = uint256(_getLiquidity(tokenId, poolKey, info.tickLower(), info.tickUpper())); + address owner = ownerOf(tokenId); + // Clear the position info. positionInfo[tokenId] = PositionInfoLibrary.EMPTY_POSITION_INFO; // Burn the token. _burn(tokenId); // Can only call modify if there is non zero liquidity. + BalanceDelta feesAccrued; + BalanceDelta liquidityDelta; if (liquidity > 0) { - (BalanceDelta liquidityDelta, BalanceDelta feesAccrued) = - _modifyLiquidity(info, poolKey, -(liquidity.toInt256()), bytes32(tokenId), hookData); + // do not use _modifyLiquidity as we do not need to notify on modification for burns. + (liquidityDelta, feesAccrued) = poolManager.modifyLiquidity( + poolKey, + IPoolManager.ModifyLiquidityParams({ + tickLower: info.tickLower(), + tickUpper: info.tickUpper(), + liquidityDelta: -(liquidity.toInt256()), + salt: bytes32(tokenId) + }), + hookData + ); // Slippage checks should be done on the principal liquidityDelta which is the liquidityDelta - feesAccrued (liquidityDelta - feesAccrued).validateMinOut(amount0Min, amount1Min); } - if (info.hasSubscriber()) _unsubscribe(tokenId); + // deletes then notifies the subscriber + if (info.hasSubscriber()) _removeSubscriberAndNotifyBurn(tokenId, owner, info, liquidity, feesAccrued); } function _settlePair(Currency currency0, Currency currency1) internal { @@ -475,6 +489,7 @@ contract PositionManager is if (balance > 0) currency.transfer(to, balance); } + /// @dev if there is a subscriber attached to the position, this function will notify the subscriber function _modifyLiquidity( PositionInfo info, PoolKey memory poolKey, diff --git a/src/base/Notifier.sol b/src/base/Notifier.sol index b85d3e6e..3b288053 100644 --- a/src/base/Notifier.sol +++ b/src/base/Notifier.sol @@ -88,6 +88,30 @@ abstract contract Notifier is INotifier { emit Unsubscription(tokenId, address(_subscriber)); } + /// @dev note this function also deletes the subscriber address from the mapping + function _removeSubscriberAndNotifyBurn( + uint256 tokenId, + address owner, + PositionInfo info, + uint256 liquidity, + BalanceDelta feesAccrued + ) internal { + ISubscriber _subscriber = subscriber[tokenId]; + + // remove the subscriber + delete subscriber[tokenId]; + + bool success = _call( + address(_subscriber), abi.encodeCall(ISubscriber.notifyBurn, (tokenId, owner, info, liquidity, feesAccrued)) + ); + + if (!success) { + address(_subscriber).bubbleUpAndRevertWith( + ISubscriber.notifyBurn.selector, BurnNotificationReverted.selector + ); + } + } + function _notifyModifyLiquidity(uint256 tokenId, int256 liquidityChange, BalanceDelta feesAccrued) internal { ISubscriber _subscriber = subscriber[tokenId]; diff --git a/src/interfaces/INotifier.sol b/src/interfaces/INotifier.sol index abf6148c..9e7d2356 100644 --- a/src/interfaces/INotifier.sol +++ b/src/interfaces/INotifier.sol @@ -15,6 +15,8 @@ interface INotifier { error SubscriptionReverted(address subscriber, bytes reason); /// @notice Wraps the revert message of the subscriber contract on a reverting modify liquidity notification error ModifyLiquidityNotificationReverted(address subscriber, bytes reason); + /// @notice Wraps the revert message of the subscriber contract on a reverting burn notification + error BurnNotificationReverted(address subscriber, bytes reason); /// @notice Wraps the revert message of the subscriber contract on a reverting transfer notification error TransferNotificationReverted(address subscriber, bytes reason); /// @notice Thrown when a tokenId already has a subscriber diff --git a/src/interfaces/ISubscriber.sol b/src/interfaces/ISubscriber.sol index 0c410079..e1662998 100644 --- a/src/interfaces/ISubscriber.sol +++ b/src/interfaces/ISubscriber.sol @@ -2,6 +2,7 @@ pragma solidity ^0.8.0; import {BalanceDelta} from "@uniswap/v4-core/src/types/BalanceDelta.sol"; +import {PositionInfo} from "../libraries/PositionInfoLibrary.sol"; /// @notice Interface that a Subscriber contract should implement to receive updates from the v4 position manager interface ISubscriber { @@ -13,6 +14,14 @@ interface ISubscriber { /// @dev Because of EIP-150, solidity may only allocate 63/64 of gasleft() /// @param tokenId the token ID of the position function notifyUnsubscribe(uint256 tokenId) external; + /// @notice Called when a position is burned + /// @param tokenId the token ID of the position + /// @param owner the current owner of the tokenId + /// @param info information about the position + /// @param liquidity the amount of liquidity decreased in the position, may be 0 + /// @param feesAccrued the fees accrued by the position if liquidity was decreased + function notifyBurn(uint256 tokenId, address owner, PositionInfo info, uint256 liquidity, BalanceDelta feesAccrued) + external; /// @param tokenId the token ID of the position /// @param liquidityChange the change in liquidity on the underlying position /// @param feesAccrued the fees to be collected from the position as a result of the modifyLiquidity call diff --git a/test/mocks/MockBadSubscribers.sol b/test/mocks/MockBadSubscribers.sol index d6e6e0c3..0c506926 100644 --- a/test/mocks/MockBadSubscribers.sol +++ b/test/mocks/MockBadSubscribers.sol @@ -4,6 +4,7 @@ pragma solidity ^0.8.20; import {ISubscriber} from "../../src/interfaces/ISubscriber.sol"; import {PositionManager} from "../../src/PositionManager.sol"; import {BalanceDelta} from "@uniswap/v4-core/src/types/BalanceDelta.sol"; +import {PositionInfo} from "../../src/libraries/PositionInfoLibrary.sol"; /// @notice A subscriber contract that returns values from the subscriber entrypoints contract MockReturnDataSubscriber is ISubscriber { @@ -47,6 +48,12 @@ contract MockReturnDataSubscriber is ISubscriber { notifyModifyLiquidityCount++; } + function notifyBurn(uint256 tokenId, address owner, PositionInfo info, uint256 liquidity, BalanceDelta feesAccrued) + external + { + return; + } + function setReturnDataSize(uint256 _value) external { memPtr = _value; } @@ -85,6 +92,12 @@ contract MockRevertSubscriber is ISubscriber { revert TestRevert("notifyModifyLiquidity"); } + function notifyBurn(uint256 tokenId, address owner, PositionInfo info, uint256 liquidity, BalanceDelta feesAccrued) + external + { + return; + } + function setRevert(bool _shouldRevert) external { shouldRevert = _shouldRevert; } diff --git a/test/mocks/MockSubscriber.sol b/test/mocks/MockSubscriber.sol index ef4c2e86..4da187b5 100644 --- a/test/mocks/MockSubscriber.sol +++ b/test/mocks/MockSubscriber.sol @@ -4,6 +4,7 @@ pragma solidity ^0.8.20; import {ISubscriber} from "../../src/interfaces/ISubscriber.sol"; import {PositionManager} from "../../src/PositionManager.sol"; import {BalanceDelta} from "@uniswap/v4-core/src/types/BalanceDelta.sol"; +import {PositionInfo} from "../../src/libraries/PositionInfoLibrary.sol"; /// @notice A subscriber contract that ingests updates from the v4 position manager contract MockSubscriber is ISubscriber { @@ -12,6 +13,7 @@ contract MockSubscriber is ISubscriber { uint256 public notifySubscribeCount; uint256 public notifyUnsubscribeCount; uint256 public notifyModifyLiquidityCount; + uint256 public notifyBurnCount; int256 public liquidityChange; BalanceDelta public feesAccrued; @@ -44,4 +46,11 @@ contract MockSubscriber is ISubscriber { liquidityChange = _liquidityChange; feesAccrued = _feesAccrued; } + + function notifyBurn(uint256 tokenId, address owner, PositionInfo info, uint256 liquidity, BalanceDelta feesAccrued) + external + onlyByPosm + { + notifyBurnCount++; + } } diff --git a/test/position-managers/PositionManager.notifier.t.sol b/test/position-managers/PositionManager.notifier.t.sol index 599bfbe1..de25bc41 100644 --- a/test/position-managers/PositionManager.notifier.t.sol +++ b/test/position-managers/PositionManager.notifier.t.sol @@ -566,8 +566,8 @@ contract PositionManagerNotifierTest is Test, PosmTestSetup, GasSnapshot { lpm.modifyLiquidities(calls, _deadline); } - /// @notice burning a position will automatically notify unsubscribe - function test_burn_unsubscribe() public { + /// @notice burning a position will automatically notify burn + function test_notifyBurn_succeeds() public { uint256 tokenId = lpm.nextTokenId(); mint(config, 100e18, alice, ZERO_BYTES); @@ -583,12 +583,13 @@ contract PositionManagerNotifierTest is Test, PosmTestSetup, GasSnapshot { assertEq(lpm.positionInfo(tokenId).hasSubscriber(), true); assertEq(sub.notifyUnsubscribeCount(), 0); - // burn the position, causing an unsubscribe + // burn the position, causing a notifyBurn burn(tokenId, config, ZERO_BYTES); // position is now unsubscribed assertEq(lpm.positionInfo(tokenId).hasSubscriber(), false); - assertEq(sub.notifyUnsubscribeCount(), 1); + assertEq(sub.notifyUnsubscribeCount(), 0); + assertEq(sub.notifyBurnCount(), 1); } /// @notice Test that users cannot forcibly avoid unsubscribe logic via gas limits