-
Notifications
You must be signed in to change notification settings - Fork 45
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
[PART-1] enable hooks to return deltas to influence pool behavior #44
Conversation
@@ -135,27 +136,19 @@ contract BinPoolManager is IBinPoolManager, ProtocolFees, Extsload { | |||
whenNotPaused | |||
returns (BalanceDelta delta) | |||
{ | |||
if (amountIn == 0) revert InsufficientAmountIn(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This check has been moved from BinPool.sol
to here otherwise the call will revert if hook contract updates the actual amountIn
to 0 through beforeSwap
bytes calldata hookData | ||
) internal returns (BalanceDelta callerDelta, BalanceDelta hookDelta) { | ||
IBinHooks hooks = IBinHooks(address(key.hooks)); | ||
callerDelta = delta; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if skip i.e. caller is already hook, then callerDelta
is unchanged and hookDelta is 0
src/pool-bin/libraries/BinHooks.sol
Outdated
|
||
function beforeSwap(PoolKey memory key, bool swapForY, uint128 amountIn, bytes calldata hookData) | ||
internal | ||
returns (uint128 amountToSwap, int128 hookDeltaSpecified) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is uint128
because unlike cl-pool, in bin-pool users are always specifying exactlyIn amount
} | ||
} | ||
|
||
if (hookDeltaUnspecified != 0 || hookDeltaSpecified != 0) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This can still be true even "afterSwapReturnDelta" is disabled
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
is it better to rename hookDeltaSpecified
as beforeSwapHookDeltaSpecified
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
already updated in part3
revert Hooks.InvalidHookResponse(); | ||
} | ||
|
||
if (!key.parameters.hasOffsetEnabled(HOOKS_AFTER_SWAP_RETURNS_DELTA_OFFSET)) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Potentially optimization: skip decoding the second return value when afterSwapReturnDelta not set
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
add a //todo
comment in the code if possible for these cases
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
added in part3
ea853f2
to
395eb86
Compare
@@ -145,7 +142,7 @@ library CLPool { | |||
} | |||
|
|||
// Fees earned from LPing are removed from the pool balance. | |||
feeDelta = toBalanceDelta(feesOwed0.toInt128(), feesOwed1.toInt128()); | |||
feeDelta = toBalanceDelta(-feesOwed0.toInt128(), -feesOwed1.toInt128()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
feeDelta must be negative i.e. both feeDelta.amount0 <= 0
and feeDelta.amount1 <= 0
because that's the fee owed to the user by the pool. Our rule for BalanceDelta is:
- Positive number means user owes the pool
- Negative number means pool owes user
TO CONFIRM: If we want to flip to sign for all the delta across the repo
Do you mean that if we want to replicate no-op for swap/modifyLiquidity, the hook should ensure that |
yes, i guess so, see:
Another way could be using |
// Sentinel return value used to signify that a NoOp occurred. | ||
return (BalanceDeltaLibrary.MAXIMUM_DELTA, binId); | ||
} else if (selector != IBinHooks.beforeDonate.selector) { | ||
if (hooks.beforeDonate(msg.sender, key, amount0, amount1, hookData) != IBinHooks.beforeDonate.selector) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
im thinking if we can create an issue to refactor (not in this PR but after all parts are merged) -- eg. move all hook call to CLHooks/BinHooks to make it easier to read for the devs. what do you think?
// some are without CLHooks
ICLHooks hooks = ICLHooks(address(key.hooks));
if (key.parameters.shouldCall(HOOKS_BEFORE_DONATE_OFFSET, hooks)) {
if (hooks.beforeDonate(msg.sender, key, amount0, amount1, hookData) != ICLHooks.beforeDonate.selector) {
revert Hooks.InvalidHookResponse();
}
}
// some are using CLHooks
(delta, hookDelta) = CLHooks.afterModifyLiquidity(key, params, delta + feeDelta, hookData);
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Agree with that, it brings better readability
} | ||
|
||
if (hookDeltaUnspecified != 0 || hookDeltaSpecified != 0) { | ||
hookDelta = swapForY |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
curious why here is only checking for swapForY
while CLPool is checking amountSpecified as well (params.amountSpecified > 0 == params.zeroForOne)
ah got it. params.amountSpecified > 0 would tell us if its exactInput
or exactOutput
but for bin case, its always exactIn
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
exactly 😄
* feat: add salt to distinguish positions for same owner in cl-pool * feat: add salt to distinguish positions for same owner in bin-pool * optimiazaiton: small tweaks per comments * test: added salt != 0 cases * [PART-3] allow `beforeSwap` to return temp lpFee & delta for both sides (#47) * feat: finish updating for cl-pool * feat: finish updating for bin-pool * chore: correct comments removed unnecessary isValid function
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
re-approved since we merged part 3 and part 2 in this PR
This PR allows hooks contract to return extra parameter which can have impact on pool's behavior. More specifically:
beforeSwap
. Those two together work as a update to the balanceDelta i.e. through it payment can be transferred between user and hook contract.NO_OP feature has been removed because its functionality has overlapped with this feature:
value returned = -amtSpecified/amtIn
afterXXX
as userHowever, there are also some reasons that NO_OP might be the way to go: