Skip to content

Commit

Permalink
merge main
Browse files Browse the repository at this point in the history
  • Loading branch information
snreynolds committed Aug 8, 2024
2 parents df9c726 + 17f1a49 commit aca8e35
Show file tree
Hide file tree
Showing 41 changed files with 158 additions and 70 deletions.
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
154942
Original file line number Diff line number Diff line change
@@ -1 +1 @@
151490
153944
Original file line number Diff line number Diff line change
@@ -1 +1 @@
134288
136742
Original file line number Diff line number Diff line change
@@ -1 +1 @@
130387
132841
Original file line number Diff line number Diff line change
@@ -1 +1 @@
171303
173757
Original file line number Diff line number Diff line change
@@ -1 +1 @@
141259
143713
2 changes: 1 addition & 1 deletion .forge-snapshots/PositionManager_mint_native.snap
Original file line number Diff line number Diff line change
@@ -1 +1 @@
340665
340673
Original file line number Diff line number Diff line change
@@ -1 +1 @@
349157
349165
Original file line number Diff line number Diff line change
@@ -1 +1 @@
348459
348467
2 changes: 1 addition & 1 deletion .forge-snapshots/PositionManager_mint_onSameTickLower.snap
Original file line number Diff line number Diff line change
@@ -1 +1 @@
318647
318655
2 changes: 1 addition & 1 deletion .forge-snapshots/PositionManager_mint_onSameTickUpper.snap
Original file line number Diff line number Diff line change
@@ -1 +1 @@
319289
319297
2 changes: 1 addition & 1 deletion .forge-snapshots/PositionManager_mint_sameRange.snap
Original file line number Diff line number Diff line change
@@ -1 +1 @@
244871
244879
Original file line number Diff line number Diff line change
@@ -1 +1 @@
374689
374697
Original file line number Diff line number Diff line change
@@ -1 +1 @@
324665
324673
2 changes: 1 addition & 1 deletion .forge-snapshots/PositionManager_mint_withClose.snap
Original file line number Diff line number Diff line change
@@ -1 +1 @@
375965
375973
2 changes: 1 addition & 1 deletion .forge-snapshots/PositionManager_mint_withSettlePair.snap
Original file line number Diff line number Diff line change
@@ -1 +1 @@
375105
375113
Original file line number Diff line number Diff line change
@@ -1 +1 @@
420439
420447
7 changes: 4 additions & 3 deletions src/PositionManager.sol
Original file line number Diff line number Diff line change
Expand Up @@ -196,7 +196,7 @@ contract PositionManager is
uint128 amount0Max,
uint128 amount1Max,
bytes calldata hookData
) internal onlyValidConfig(tokenId, config) {
) internal onlyIfApproved(msgSender(), tokenId) onlyValidConfig(tokenId, config) {
// Note: The tokenId is used as the salt for this position, so every minted position has unique storage in the pool manager.
BalanceDelta liquidityDelta = _modifyLiquidity(config, liquidity.toInt256(), bytes32(tokenId), hookData);
liquidityDelta.validateMaxInNegative(amount0Max, amount1Max);
Expand Down Expand Up @@ -314,7 +314,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 @@ -326,7 +327,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, PositionConfigLibrary} from "../libraries/PositionConfig
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 @@ -74,12 +75,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
24 changes: 0 additions & 24 deletions test/position-managers/IncreaseLiquidity.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -294,30 +294,6 @@ contract IncreaseLiquidityTest is Test, PosmTestSetup, Fuzzers {
assertEq(currency1.balanceOf(alice), balance1BeforeAlice);
}

function test_increaseLiquidity_withUnapprovedCaller() public {
// Alice provides liquidity
// Bob increases Alice's liquidity without being approved
uint256 liquidityAlice = 3_000e18;

// alice provides liquidity
vm.startPrank(alice);
uint256 tokenIdAlice = lpm.nextTokenId();
mint(config, liquidityAlice, alice, ZERO_BYTES);
vm.stopPrank();

uint128 oldLiquidity = lpm.getPositionLiquidity(tokenIdAlice, config);

// bob can increase liquidity for alice even though he is not the owner / not approved
vm.startPrank(bob);
increaseLiquidity(tokenIdAlice, config, 100e18, ZERO_BYTES);
vm.stopPrank();

uint128 newLiquidity = lpm.getPositionLiquidity(tokenIdAlice, config);

// assert liqudity increased by the correct amount
assertEq(newLiquidity, oldLiquidity + uint128(100e18));
}

function test_increaseLiquidity_sameRange_withExcessFees() public {
// Alice and Bob provide liquidity on the same range
// Alice uses half her fees to increase liquidity. The other half are collected to her wallet.
Expand Down
40 changes: 37 additions & 3 deletions test/position-managers/Permit.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,27 @@ contract PermitTest is Test, PosmTestSetup {
);
}

function test_permit_increaseLiquidity() public {
uint256 liquidityAlice = 1e18;
uint256 tokenIdAlice = lpm.nextTokenId();
vm.prank(alice);
mint(config, liquidityAlice, alice, ZERO_BYTES);

// alice gives bob permissions
permit(alicePK, tokenIdAlice, bob, 1);

// bob can increase liquidity on alice's token
uint256 liquidityToAdd = 0.4444e18;
vm.startPrank(bob);
increaseLiquidity(tokenIdAlice, config, liquidityToAdd, ZERO_BYTES);
vm.stopPrank();

// alice's position increased liquidity
uint256 liquidity = lpm.getPositionLiquidity(tokenIdAlice, config);

assertEq(liquidity, liquidityAlice + liquidityToAdd);
}

function test_permit_decreaseLiquidity() public {
uint256 liquidityAlice = 1e18;
vm.prank(alice);
Expand Down Expand Up @@ -143,9 +164,22 @@ contract PermitTest is Test, PosmTestSetup {
vm.stopPrank();
}

// unapproved callers can increase others' positions
// see `test_increaseLiquidity_withUnapprovedCaller()`
// function test_noPermit_increaseLiquidityRevert() public {}
/// @dev unapproved callers CANNOT increase others' positions
function test_noPermit_increaseLiquidityRevert() public {
// increase fails if the owner did not permit
uint256 liquidityAlice = 1e18;
vm.prank(alice);
mint(config, liquidityAlice, alice, ZERO_BYTES);
uint256 tokenIdAlice = lpm.nextTokenId() - 1;

// bob cannot increase liquidity on alice's token
uint256 liquidityToAdd = 0.4444e18;
bytes memory decrease = getIncreaseEncoded(tokenIdAlice, config, liquidityToAdd, ZERO_BYTES);
vm.startPrank(bob);
vm.expectRevert(abi.encodeWithSelector(IPositionManager.NotApproved.selector, address(bob)));
lpm.modifyLiquidities(decrease, _deadline);
vm.stopPrank();
}

function test_noPermit_decreaseLiquidityRevert() public {
// decreaseLiquidity fails if the owner did not permit
Expand Down
Loading

0 comments on commit aca8e35

Please sign in to comment.