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

Before after add/remove liquidity, remove all modifyPosition hooks #434

Merged
merged 31 commits into from
Dec 14, 2023
Merged
Show file tree
Hide file tree
Changes from 23 commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
8bf9f1b
Rip out beforeModifyPosition and after, add mints
zhongeric Nov 13, 2023
5babed0
forge fmt
zhongeric Nov 13, 2023
bb11369
Add explicit before/after mint hook calls
zhongeric Nov 13, 2023
de292c1
Add mintPosition
zhongeric Nov 14, 2023
c6a223c
fix wrong test assumption
zhongeric Nov 15, 2023
38a1e5d
forge fmt
zhongeric Nov 15, 2023
c7e4a72
natspec
zhongeric Nov 15, 2023
b24c159
Merge branch 'main' into before-after-mint
zhongeric Nov 17, 2023
90af549
chore: change mintPosition -> addLiquidity
rileydcampbell Nov 22, 2023
97779f5
merged changes
rileydcampbell Nov 24, 2023
b0fea97
fix tests
rileydcampbell Nov 27, 2023
25314e3
Merge branch 'main' of https://github.com/Uniswap/v4-core into before…
rileydcampbell Dec 6, 2023
3f4467d
Merge branch 'main' of https://github.com/Uniswap/v4-core into before…
rileydcampbell Dec 6, 2023
1a75990
More tests
rileydcampbell Dec 6, 2023
33e602d
More tests
rileydcampbell Dec 6, 2023
21514b4
Merge branch 'before-after-mint' of https://github.com/Uniswap/v4-cor…
rileydcampbell Dec 6, 2023
518737a
Change modify position params for PoolManager
rileydcampbell Dec 7, 2023
3fd4079
Merge branch 'main' of https://github.com/Uniswap/v4-core into before…
rileydcampbell Dec 7, 2023
cee4d82
Fixed PoolModifyPositionTest and some more breaking tests.
rileydcampbell Dec 7, 2023
0d37920
New gas snapshots
rileydcampbell Dec 7, 2023
17b439a
fix test comments
rileydcampbell Dec 7, 2023
689fab4
Merge branch 'main' of https://github.com/Uniswap/v4-core into before…
rileydcampbell Dec 8, 2023
399f250
fix: use bound instead of vm.assume
rileydcampbell Dec 8, 2023
6c497bc
pull in changes and refactor hook calls
rileydcampbell Dec 12, 2023
832e6b1
Merge branch 'main' of https://github.com/Uniswap/v4-core into before…
rileydcampbell Dec 12, 2023
435c914
fix tests
rileydcampbell Dec 12, 2023
389789c
addressed feedback
rileydcampbell Dec 12, 2023
8c5e457
Change entry point name and no hooks on liquidity delta zero
rileydcampbell Dec 13, 2023
1260a27
call before/afterRemove Liquidity hooks on zero liquidity delta
rileydcampbell Dec 13, 2023
43d5aea
fix naming
rileydcampbell Dec 14, 2023
e408681
change event name
rileydcampbell Dec 14, 2023
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
1 change: 1 addition & 0 deletions .forge-snapshots/addLiquidity with empty hook.snap
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
320193
1 change: 1 addition & 0 deletions .forge-snapshots/addLiquidity with native token.snap
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
202979
1 change: 1 addition & 0 deletions .forge-snapshots/addLiquidity.snap
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
202925
Original file line number Diff line number Diff line change
@@ -1 +1 @@
193083
193128
2 changes: 1 addition & 1 deletion .forge-snapshots/cached dynamic fee, no hooks.snap
Original file line number Diff line number Diff line change
@@ -1 +1 @@
148446
148469
2 changes: 1 addition & 1 deletion .forge-snapshots/donate gas with 1 token.snap
Original file line number Diff line number Diff line change
@@ -1 +1 @@
139060
139105
2 changes: 1 addition & 1 deletion .forge-snapshots/donate gas with 2 tokens.snap
Original file line number Diff line number Diff line change
@@ -1 +1 @@
186482
186572
2 changes: 1 addition & 1 deletion .forge-snapshots/initialize.snap
Original file line number Diff line number Diff line change
@@ -1 +1 @@
78563
78605
2 changes: 1 addition & 1 deletion .forge-snapshots/mintWithEmptyHookEOAInitiated.snap
Original file line number Diff line number Diff line change
@@ -1 +1 @@
250959
251938
2 changes: 1 addition & 1 deletion .forge-snapshots/modify position with noop.snap
Original file line number Diff line number Diff line change
@@ -1 +1 @@
56530
56865
2 changes: 1 addition & 1 deletion .forge-snapshots/poolManager bytecode size.snap
Original file line number Diff line number Diff line change
@@ -1 +1 @@
26329
26933
1 change: 1 addition & 0 deletions .forge-snapshots/removeLiquidity with empty hook.snap
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
105900
1 change: 1 addition & 0 deletions .forge-snapshots/removeLiquidity with native token.snap
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
211283
1 change: 1 addition & 0 deletions .forge-snapshots/removeLiquidity.snap
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
207550
2 changes: 1 addition & 1 deletion .forge-snapshots/simple swap with native.snap
Original file line number Diff line number Diff line change
@@ -1 +1 @@
197331
197354
2 changes: 1 addition & 1 deletion .forge-snapshots/simple swap.snap
Original file line number Diff line number Diff line change
@@ -1 +1 @@
205899
205922
2 changes: 1 addition & 1 deletion .forge-snapshots/simpleSwapEOAInitiated.snap
Original file line number Diff line number Diff line change
@@ -1 +1 @@
177187
177210
2 changes: 1 addition & 1 deletion .forge-snapshots/simpleSwapNativeEOAInitiated.snap
Original file line number Diff line number Diff line change
@@ -1 +1 @@
173849
173872
Original file line number Diff line number Diff line change
@@ -1 +1 @@
127924
127947
2 changes: 1 addition & 1 deletion .forge-snapshots/swap against liquidity.snap
Original file line number Diff line number Diff line change
@@ -1 +1 @@
115415
115438
2 changes: 1 addition & 1 deletion .forge-snapshots/swap burn claim for input.snap
Original file line number Diff line number Diff line change
@@ -1 +1 @@
134509
134487
1 change: 1 addition & 0 deletions .forge-snapshots/swap mint 1155 as output.snap
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
169598
2 changes: 1 addition & 1 deletion .forge-snapshots/swap mint output as claim.snap
Original file line number Diff line number Diff line change
@@ -1 +1 @@
218114
218137
2 changes: 1 addition & 1 deletion .forge-snapshots/swap with dynamic fee.snap
Original file line number Diff line number Diff line change
@@ -1 +1 @@
192325
192370
2 changes: 1 addition & 1 deletion .forge-snapshots/swap with hooks.snap
Original file line number Diff line number Diff line change
@@ -1 +1 @@
115393
115416
2 changes: 1 addition & 1 deletion .forge-snapshots/update dynamic fee in before swap.snap
Original file line number Diff line number Diff line change
@@ -1 +1 @@
198919
198941
94 changes: 78 additions & 16 deletions src/PoolManager.sol
Original file line number Diff line number Diff line change
Expand Up @@ -195,7 +195,54 @@ contract PoolManager is IPoolManager, Fees, NoDelegateCall, Claims {
}

/// @inheritdoc IPoolManager
function modifyPosition(
function addLiquidity(PoolKey memory key, IPoolManager.ModifyPositionParams memory params, bytes calldata hookData)
external
override
noDelegateCall
onlyByLocker
returns (BalanceDelta delta)
{
(bool set) = Lockers.setCurrentHook(key.hooks);

PoolId id = key.toId();
_checkPoolInitialized(id);

if (key.hooks.shouldCallBeforeAddLiquidity()) {
bytes4 selector = key.hooks.beforeAddLiquidity(msg.sender, key, params, hookData);
// Sentinel return value used to signify that a NoOp occurred.
if (key.hooks.isValidNoOpCall(selector)) {
// We only want to clear the current hook if it was set in setCurrentHook in this execution frame.
if (set) Lockers.clearCurrentHook();
return BalanceDeltaLibrary.MAXIMUM_DELTA;
} else if (selector != IHooks.beforeAddLiquidity.selector) {
revert Hooks.InvalidHookResponse();
}
}

delta = _modifyPosition(
key,
IPoolManager.PoolModifyPositionParams({
tickLower: params.tickLower,
tickUpper: params.tickUpper,
liquidityDelta: params.liquidityDelta.toInt128()
})
);

if (key.hooks.shouldCallAfterAddLiquidity()) {
if (
key.hooks.afterAddLiquidity(msg.sender, key, params, delta, hookData)
!= IHooks.afterAddLiquidity.selector
) {
revert Hooks.InvalidHookResponse();
}
}

// We only want to clear the current hook if it was set in setCurrentHook in this execution frame.
if (set) Lockers.clearCurrentHook();
}

/// @inheritdoc IPoolManager
function removeLiquidity(
PoolKey memory key,
IPoolManager.ModifyPositionParams memory params,
bytes calldata hookData
Expand All @@ -205,18 +252,45 @@ contract PoolManager is IPoolManager, Fees, NoDelegateCall, Claims {
PoolId id = key.toId();
_checkPoolInitialized(id);

if (key.hooks.shouldCallBeforeModifyPosition()) {
bytes4 selector = key.hooks.beforeModifyPosition(msg.sender, key, params, hookData);
if (key.hooks.shouldCallBeforeRemoveLiquidity()) {
bytes4 selector = key.hooks.beforeRemoveLiquidity(msg.sender, key, params, hookData);
// Sentinel return value used to signify that a NoOp occurred.
if (key.hooks.isValidNoOpCall(selector)) {
// We only want to clear the current hook if it was set in setCurrentHook in this execution frame.
if (set) Lockers.clearCurrentHook();
return BalanceDeltaLibrary.MAXIMUM_DELTA;
} else if (selector != IHooks.beforeModifyPosition.selector) {
} else if (selector != IHooks.beforeRemoveLiquidity.selector) {
revert Hooks.InvalidHookResponse();
}
}

delta = _modifyPosition(
key,
IPoolManager.PoolModifyPositionParams({
tickLower: params.tickLower,
tickUpper: params.tickUpper,
liquidityDelta: -params.liquidityDelta.toInt128()
rileydcampbell marked this conversation as resolved.
Show resolved Hide resolved
})
);

if (key.hooks.shouldCallAfterRemoveLiquidity()) {
if (
key.hooks.afterRemoveLiquidity(msg.sender, key, params, delta, hookData)
!= IHooks.afterRemoveLiquidity.selector
) {
revert Hooks.InvalidHookResponse();
}
}

// We only want to clear the current hook if it was set in setCurrentHook in this execution frame.
if (set) Lockers.clearCurrentHook();
}

function _modifyPosition(PoolKey memory key, IPoolManager.PoolModifyPositionParams memory params)
rileydcampbell marked this conversation as resolved.
Show resolved Hide resolved
internal
returns (BalanceDelta delta)
{
PoolId id = key.toId();
Pool.FeeAmounts memory feeAmounts;
(delta, feeAmounts) = pools[id].modifyPosition(
Pool.ModifyPositionParams({
rileydcampbell marked this conversation as resolved.
Show resolved Hide resolved
Expand Down Expand Up @@ -245,18 +319,6 @@ contract PoolManager is IPoolManager, Fees, NoDelegateCall, Claims {
}
}

if (key.hooks.shouldCallAfterModifyPosition()) {
if (
key.hooks.afterModifyPosition(msg.sender, key, params, delta, hookData)
!= IHooks.afterModifyPosition.selector
) {
revert Hooks.InvalidHookResponse();
}
}

// We only want to clear the current hook if it was set in setCurrentHook in this execution frame.
if (set) Lockers.clearCurrentHook();

emit ModifyPosition(id, msg.sender, params.tickLower, params.tickUpper, params.liquidityDelta);
}

Expand Down
43 changes: 35 additions & 8 deletions src/interfaces/IHooks.sol
Original file line number Diff line number Diff line change
Expand Up @@ -35,26 +35,53 @@ interface IHooks {
bytes calldata hookData
) external returns (bytes4);

/// @notice The hook called before a position is modified
/// @param sender The initial msg.sender for the modify position call
/// @notice The hook called before liquidity is added
/// @param sender The initial msg.sender for the add liquidity call
/// @param key The key for the pool
/// @param params The parameters for modifying the position
/// @param params The parameters for adding liquidity
/// @param hookData Arbitrary data handed into the PoolManager by the liquidty provider to be be passed on to the hook
/// @return bytes4 The function selector for the hook
function beforeModifyPosition(
function beforeAddLiquidity(
address sender,
PoolKey calldata key,
IPoolManager.ModifyPositionParams calldata params,
bytes calldata hookData
) external returns (bytes4);

/// @notice The hook called after a position is modified
/// @param sender The initial msg.sender for the modify position call
/// @notice The hook called after liquidity is added
/// @param sender The initial msg.sender for the add liquidity call
/// @param key The key for the pool
/// @param params The parameters for modifying the position
/// @param params The parameters for adding liquidity
/// @param hookData Arbitrary data handed into the PoolManager by the liquidty provider to be be passed on to the hook
/// @return bytes4 The function selector for the hook
function afterModifyPosition(
function afterAddLiquidity(
address sender,
PoolKey calldata key,
IPoolManager.ModifyPositionParams calldata params,
BalanceDelta delta,
bytes calldata hookData
) external returns (bytes4);

/// @notice The hook called before liquidity is removed
/// @param sender The initial msg.sender for the remove liquidity call
/// @param key The key for the pool
/// @param params The parameters for removing liquidity
/// @param hookData Arbitrary data handed into the PoolManager by the liquidty provider to be be passed on to the hook
/// @return bytes4 The function selector for the hook
function beforeRemoveLiquidity(
address sender,
PoolKey calldata key,
IPoolManager.ModifyPositionParams calldata params,
bytes calldata hookData
) external returns (bytes4);

/// @notice The hook called after liquidity is removed
/// @param sender The initial msg.sender for the remove liquidity call
/// @param key The key for the pool
/// @param params The parameters for removing liquidity
/// @param hookData Arbitrary data handed into the PoolManager by the liquidty provider to be be passed on to the hook
/// @return bytes4 The function selector for the hook
function afterRemoveLiquidity(
address sender,
PoolKey calldata key,
IPoolManager.ModifyPositionParams calldata params,
Expand Down
29 changes: 26 additions & 3 deletions src/interfaces/IPoolManager.sol
Original file line number Diff line number Diff line change
Expand Up @@ -146,16 +146,39 @@ interface IPoolManager is IFees, IClaims {
/// @return The data returned by the call to `ILockCallback(msg.sender).lockAcquired(data)`
function lock(address lockTarget, bytes calldata data) external payable returns (bytes memory);

struct ModifyPositionParams {
struct PoolModifyPositionParams {
rileydcampbell marked this conversation as resolved.
Show resolved Hide resolved
// the lower and upper tick of the position
int24 tickLower;
int24 tickUpper;
// how to modify the liquidity
int256 liquidityDelta;
}

/// @notice Modify the position for the given pool
function modifyPosition(PoolKey memory key, ModifyPositionParams memory params, bytes calldata hookData)
struct ModifyPositionParams {
// the lower and upper tick of the position
int24 tickLower;
int24 tickUpper;
// how to modify the liquidity
uint256 liquidityDelta;
}

/// @notice Add a new liquidity position in a pool
/// @dev Poke by calling with a zero liquidityDelta
/// @param key The pool to add a position in
/// @param params The parameters to pass into _modifyPosition
/// @param hookData Any data to pass to the callback, via `ILockCallback(msg.sender).lockAcquired(data)`
/// @return delta The balance delta of the position added
function addLiquidity(PoolKey memory key, ModifyPositionParams memory params, bytes calldata hookData)
external
returns (BalanceDelta);

/// @notice Remove a liquidity position in a pool
/// @dev Poke by calling with a zero liquidityDelta
/// @param key The pool to remove a position in
/// @param params The parameters to pass into _modifyPosition
/// @param hookData Any data to pass to the callback, via `ILockCallback(msg.sender).lockAcquired(data)`
/// @return delta The balance delta of the position removed
function removeLiquidity(PoolKey memory key, ModifyPositionParams memory params, bytes calldata hookData)
external
returns (BalanceDelta);

Expand Down
Loading