Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Provide feesAccrued to subscriber.notifyModifyLiquidity #282

Merged
merged 3 commits into from
Aug 6, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1 +1 @@
123220
123226
Original file line number Diff line number Diff line change
@@ -1 +1 @@
122727
122733
Original file line number Diff line number Diff line change
@@ -1 +1 @@
130298
130304
Original file line number Diff line number Diff line change
@@ -1 +1 @@
129805
129812
2 changes: 1 addition & 1 deletion .forge-snapshots/PositionManager_collect_native.snap
Original file line number Diff line number Diff line change
@@ -1 +1 @@
141690
141698
2 changes: 1 addition & 1 deletion .forge-snapshots/PositionManager_collect_sameRange.snap
Original file line number Diff line number Diff line change
@@ -1 +1 @@
150538
150546
2 changes: 1 addition & 1 deletion .forge-snapshots/PositionManager_collect_withClose.snap
Original file line number Diff line number Diff line change
@@ -1 +1 @@
150538
150546
2 changes: 1 addition & 1 deletion .forge-snapshots/PositionManager_collect_withTakePair.snap
Original file line number Diff line number Diff line change
@@ -1 +1 @@
149910
149918
Original file line number Diff line number Diff line change
@@ -1 +1 @@
108827
108833
Original file line number Diff line number Diff line change
@@ -1 +1 @@
116081
116089
Original file line number Diff line number Diff line change
@@ -1 +1 @@
115453
115461
2 changes: 1 addition & 1 deletion .forge-snapshots/PositionManager_decrease_burnEmpty.snap
Original file line number Diff line number Diff line change
@@ -1 +1 @@
134377
134384
Original file line number Diff line number Diff line change
@@ -1 +1 @@
127116
127123
Original file line number Diff line number Diff line change
@@ -1 +1 @@
128797
128805
2 changes: 1 addition & 1 deletion .forge-snapshots/PositionManager_decrease_take_take.snap
Original file line number Diff line number Diff line change
@@ -1 +1 @@
116614
116622
Original file line number Diff line number Diff line change
@@ -1 +1 @@
152488
152496
Original file line number Diff line number Diff line change
@@ -1 +1 @@
151490
151498
Original file line number Diff line number Diff line change
@@ -1 +1 @@
134288
134296
Original file line number Diff line number Diff line change
@@ -1 +1 @@
130387
130395
Original file line number Diff line number Diff line change
@@ -1 +1 @@
171303
171311
Original file line number Diff line number Diff line change
@@ -1 +1 @@
141259
141267
2 changes: 1 addition & 1 deletion .forge-snapshots/PositionManager_mint_native.snap
Original file line number Diff line number Diff line change
@@ -1 +1 @@
340631
340639
Original file line number Diff line number Diff line change
@@ -1 +1 @@
349123
349131
Original file line number Diff line number Diff line change
@@ -1 +1 @@
348425
348433
2 changes: 1 addition & 1 deletion .forge-snapshots/PositionManager_mint_onSameTickLower.snap
Original file line number Diff line number Diff line change
@@ -1 +1 @@
318613
318621
2 changes: 1 addition & 1 deletion .forge-snapshots/PositionManager_mint_onSameTickUpper.snap
Original file line number Diff line number Diff line change
@@ -1 +1 @@
319255
319263
2 changes: 1 addition & 1 deletion .forge-snapshots/PositionManager_mint_sameRange.snap
Original file line number Diff line number Diff line change
@@ -1 +1 @@
244837
244845
Original file line number Diff line number Diff line change
@@ -1 +1 @@
374655
374663
Original file line number Diff line number Diff line change
@@ -1 +1 @@
324631
324639
2 changes: 1 addition & 1 deletion .forge-snapshots/PositionManager_mint_withClose.snap
Original file line number Diff line number Diff line change
@@ -1 +1 @@
375931
375939
2 changes: 1 addition & 1 deletion .forge-snapshots/PositionManager_mint_withSettlePair.snap
Original file line number Diff line number Diff line change
@@ -1 +1 @@
375071
375079
Original file line number Diff line number Diff line change
@@ -1 +1 @@
420405
420413
5 changes: 3 additions & 2 deletions src/PositionManager.sol
Original file line number Diff line number Diff line change
Expand Up @@ -333,7 +333,8 @@ contract PositionManager is
bytes32 salt,
bytes calldata hookData
) internal returns (BalanceDelta liquidityDelta) {
(liquidityDelta,) = poolManager.modifyLiquidity(
BalanceDelta feesAccrued;
(liquidityDelta, feesAccrued) = poolManager.modifyLiquidity(
config.poolKey,
IPoolManager.ModifyLiquidityParams({
tickLower: config.tickLower,
Expand All @@ -345,7 +346,7 @@ contract PositionManager is
);

if (positionConfigs.hasSubscriber(uint256(salt))) {
_notifyModifyLiquidity(uint256(salt), config, liquidityChange);
_notifyModifyLiquidity(uint256(salt), config, liquidityChange, feesAccrued);
}
}

Expand Down
12 changes: 10 additions & 2 deletions src/base/Notifier.sol
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import {PositionConfig} from "../libraries/PositionConfig.sol";
import {BipsLibrary} from "../libraries/BipsLibrary.sol";
import {INotifier} from "../interfaces/INotifier.sol";
import {CustomRevert} from "@uniswap/v4-core/src/libraries/CustomRevert.sol";
import {BalanceDelta} from "@uniswap/v4-core/src/types/BalanceDelta.sol";

/// @notice Notifier is used to opt in to sending updates to external contracts about position modifications or transfers
abstract contract Notifier is INotifier {
Expand Down Expand Up @@ -57,12 +58,19 @@ abstract contract Notifier is INotifier {
emit Unsubscribed(tokenId, address(_subscriber));
}

function _notifyModifyLiquidity(uint256 tokenId, PositionConfig memory config, int256 liquidityChange) internal {
function _notifyModifyLiquidity(
uint256 tokenId,
PositionConfig memory config,
int256 liquidityChange,
BalanceDelta feesAccrued
) internal {
ISubscriber _subscriber = subscriber[tokenId];

bool success = _call(
address(_subscriber),
abi.encodeWithSelector(ISubscriber.notifyModifyLiquidity.selector, tokenId, config, liquidityChange)
abi.encodeWithSelector(
ISubscriber.notifyModifyLiquidity.selector, tokenId, config, liquidityChange, feesAccrued
)
);

if (!success) {
Expand Down
9 changes: 8 additions & 1 deletion src/interfaces/ISubscriber.sol
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
pragma solidity ^0.8.24;

import {PositionConfig} from "../libraries/PositionConfig.sol";
import {BalanceDelta} from "@uniswap/v4-core/src/types/BalanceDelta.sol";

/// @notice Interface that a Subscriber contract should implement to receive updates from the v4 position manager
interface ISubscriber {
Expand All @@ -16,7 +17,13 @@ interface ISubscriber {
/// @param tokenId the token ID of the position
/// @param config details about the position
/// @param liquidityChange the change in liquidity on the underlying position
function notifyModifyLiquidity(uint256 tokenId, PositionConfig memory config, int256 liquidityChange) external;
/// @param feesAccrued the fees to be collected from the position as a result of the modifyLiquidity call
function notifyModifyLiquidity(
uint256 tokenId,
PositionConfig memory config,
int256 liquidityChange,
BalanceDelta feesAccrued
) external;
/// @param tokenId the token ID of the position
/// @param previousOwner address of the old owner
/// @param newOwner address of the new owner
Expand Down
5 changes: 3 additions & 2 deletions test/mocks/MockBadSubscribers.sol
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ pragma solidity ^0.8.20;
import {ISubscriber} from "../../src/interfaces/ISubscriber.sol";
import {PositionConfig} from "../../src/libraries/PositionConfig.sol";
import {PositionManager} from "../../src/PositionManager.sol";
import {BalanceDelta} from "@uniswap/v4-core/src/types/BalanceDelta.sol";

/// @notice A subscriber contract that returns values from the subscriber entrypoints
contract MockReturnDataSubscriber is ISubscriber {
Expand Down Expand Up @@ -44,7 +45,7 @@ contract MockReturnDataSubscriber is ISubscriber {
}
}

function notifyModifyLiquidity(uint256, PositionConfig memory, int256) external onlyByPosm {
function notifyModifyLiquidity(uint256, PositionConfig memory, int256, BalanceDelta) external onlyByPosm {
notifyModifyLiquidityCount++;
}

Expand Down Expand Up @@ -86,7 +87,7 @@ contract MockRevertSubscriber is ISubscriber {
revert TestRevert("notifyUnsubscribe");
}

function notifyModifyLiquidity(uint256, PositionConfig memory, int256) external view onlyByPosm {
function notifyModifyLiquidity(uint256, PositionConfig memory, int256, BalanceDelta) external view onlyByPosm {
revert TestRevert("notifyModifyLiquidity");
}

Expand Down
10 changes: 9 additions & 1 deletion test/mocks/MockSubscriber.sol
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ pragma solidity ^0.8.20;
import {ISubscriber} from "../../src/interfaces/ISubscriber.sol";
import {PositionConfig} from "../../src/libraries/PositionConfig.sol";
import {PositionManager} from "../../src/PositionManager.sol";
import {BalanceDelta} from "@uniswap/v4-core/src/types/BalanceDelta.sol";

/// @notice A subscriber contract that ingests updates from the v4 position manager
contract MockSubscriber is ISubscriber {
Expand All @@ -13,6 +14,8 @@ contract MockSubscriber is ISubscriber {
uint256 public notifyUnsubscribeCount;
uint256 public notifyModifyLiquidityCount;
uint256 public notifyTransferCount;
int256 public liquidityChange;
BalanceDelta public feesAccrued;

bytes public subscribeData;
bytes public unsubscribeData;
Expand Down Expand Up @@ -40,8 +43,13 @@ contract MockSubscriber is ISubscriber {
unsubscribeData = data;
}

function notifyModifyLiquidity(uint256, PositionConfig memory, int256) external onlyByPosm {
function notifyModifyLiquidity(uint256, PositionConfig memory, int256 _liquidityChange, BalanceDelta _feesAccrued)
external
onlyByPosm
{
notifyModifyLiquidityCount++;
liquidityChange = _liquidityChange;
feesAccrued = _feesAccrued;
}

function notifyTransfer(uint256, address, address) external onlyByPosm {
Expand Down
29 changes: 29 additions & 0 deletions test/position-managers/PositionManager.notifier.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import {Plan, Planner} from "../shared/Planner.sol";
import {Actions} from "../../src/libraries/Actions.sol";
import {INotifier} from "../../src/interfaces/INotifier.sol";
import {MockReturnDataSubscriber, MockRevertSubscriber} from "../mocks/MockBadSubscribers.sol";
import {BalanceDelta, toBalanceDelta} from "@uniswap/v4-core/src/types/BalanceDelta.sol";

contract PositionManagerNotifierTest is Test, PosmTestSetup, GasSnapshot {
using PoolIdLibrary for PoolKey;
Expand Down Expand Up @@ -125,6 +126,34 @@ contract PositionManagerNotifierTest is Test, PosmTestSetup, GasSnapshot {
assertEq(sub.notifyModifyLiquidityCount(), 10);
}

function test_notifyModifyLiquidity_args() public {
uint256 tokenId = lpm.nextTokenId();
mint(config, 100e18, alice, ZERO_BYTES);

// donate to generate fee revenue, to be checked in subscriber
uint256 feeRevenue0 = 1e18;
uint256 feeRevenue1 = 0.1e18;
donateRouter.donate(config.poolKey, feeRevenue0, feeRevenue1, ZERO_BYTES);

// approve this contract to operate on alices liq
vm.startPrank(alice);
lpm.approve(address(this), tokenId);
vm.stopPrank();

lpm.subscribe(tokenId, config, address(sub), ZERO_BYTES);

assertEq(lpm.hasSubscriber(tokenId), true);
assertEq(address(lpm.subscriber(tokenId)), address(sub));

uint256 liquidityToAdd = 10e18;
increaseLiquidity(tokenId, config, liquidityToAdd, ZERO_BYTES);

assertEq(sub.notifyModifyLiquidityCount(), 1);
assertEq(sub.liquidityChange(), int256(liquidityToAdd));
assertEq(int256(sub.feesAccrued().amount0()), int256(feeRevenue0) - 1 wei);
assertEq(int256(sub.feesAccrued().amount1()), int256(feeRevenue1) - 1 wei);
}

function test_notifyTransfer_withTransferFrom_succeeds() public {
uint256 tokenId = lpm.nextTokenId();
mint(config, 100e18, alice, ZERO_BYTES);
Expand Down
Loading