-
Notifications
You must be signed in to change notification settings - Fork 601
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
feat: uninitialize empty ticks #5883
Conversation
if err != nil { | ||
return nil, err | ||
} | ||
|
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.
drive by change
@@ -98,7 +98,7 @@ func (k Keeper) ComputeInAmtGivenOut( | |||
return k.computeInAmtGivenOut(ctx, desiredTokenOut, tokenInDenom, spreadFactor, priceLimit, poolId) | |||
} | |||
|
|||
func (k Keeper) InitOrUpdateTick(ctx sdk.Context, poolId uint64, currentTick int64, tickIndex int64, liquidityIn sdk.Dec, upper bool) (err error) { | |||
func (k Keeper) InitOrUpdateTick(ctx sdk.Context, poolId uint64, currentTick int64, tickIndex int64, liquidityIn sdk.Dec, upper bool) (tickIsEmpty bool, err error) { |
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 added as a return value so that we don't have to refetch the tick at the end of the withdraw method. It must be done at the end of the withdraw method, since if we delete the tick early, we will lose the fee/incentive info that is saved there that gets claimed after initOrUpdateTick is called in the WithdrawPosition method.
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 we delete the tick early, we will lose the fee/incentive info that is saved there that gets claimed after initOrUpdateTick is called in the WithdrawPosition method."
just curious:
when we withdrawPosition(entire position amount), we auto claim the left over fees/incentives and then delete tick right? if yes, then how could there be chance which we could lose fee/incentive that gets claimed after initOrUpdateTick is called
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.
What the comment meant was, it would have been cleaner to delete the tick as soon as we know its empty, but some tick data is still needed when withdrawing to claim those rewards so we need to delete as the last step (as it is in this PR)
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 LGTM just one question
Co-authored-by: Sishir Giri <[email protected]>
// WARNING: this method may mutate the pool, make sure to refetch the pool after calling this method. | ||
func (k Keeper) UpdatePosition(ctx sdk.Context, poolId uint64, owner sdk.AccAddress, lowerTick, upperTick int64, liquidityDelta sdk.Dec, joinTime time.Time, positionId uint64) (sdk.Int, sdk.Int, error) { | ||
func (k Keeper) UpdatePosition(ctx sdk.Context, poolId uint64, owner sdk.AccAddress, lowerTick, upperTick int64, liquidityDelta sdk.Dec, joinTime time.Time, positionId uint64) (sdk.Int, sdk.Int, bool, bool, error) { |
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.
Why don't we just have this method deal with deleting the tick? Why pass it up?
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.
@ValarDragon It needs to be passed up for the following reason:
We collect spread rewards when withdrawing an entire position
osmosis/x/concentrated-liquidity/lp.go
Lines 236 to 239 in 465399c
if requestedLiquidityAmountToWithdraw.Equal(position.Liquidity) { | |
if _, err := k.collectSpreadRewards(ctx, owner, positionId); err != nil { | |
return sdk.Int{}, sdk.Int{}, err | |
} |
This calls prepareClaimableSpreadRewards
osmosis/x/concentrated-liquidity/spread_rewards.go
Lines 175 to 178 in 465399c
spreadRewardsClaimed, err := k.prepareClaimableSpreadRewards(ctx, positionId) | |
if err != nil { | |
return sdk.Coins{}, err | |
} |
This calculates the spreadRewardGrowthOutside via the ticks
osmosis/x/concentrated-liquidity/spread_rewards.go
Lines 247 to 252 in 465399c
// Compute the spread reward growth outside of the range between the position's lower and upper ticks. | |
spreadRewardGrowthOutside, err := k.getSpreadRewardGrowthOutside(ctx, position.PoolId, position.LowerTick, position.UpperTick) | |
if err != nil { | |
return nil, err | |
} | |
If we delete tick info earlier, this will output an incorrect amount
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.
I see
* initial push uninitialize ticks * check tick fully removed * update CHANGELOG.md * add comments / clean up * Update x/concentrated-liquidity/lp.go Co-authored-by: Sishir Giri <[email protected]> --------- Co-authored-by: Sishir Giri <[email protected]>
Closes: #5867
What is the purpose of the change
We currently don't uninitialize a tick after it has been initialized. This causes extra unncecessary overhead when traversing ticks.
This PR uninitializes ticks after they have been drained. This is only done in withdrawPosition at the very end and cannot be done in initOrUpdateTick since fee/incentive info needs to be accessible when withdrawing.
NOTE:
This PR could also implement a traversal of existing CL pools and uninitialize empty ticks in the upgrade handler. If this is not done, then these ticks will forever be initialized. Its probably fine if this is left out, but we can talk about how we feel about including this.
Testing and Verifying
UpdatePosition, WithdrawPosition, and InitOrUpdateTick tests have been modified to check that empty ticks are removed from state, while partial withdraws do not remove the tick from state.
Documentation and Release Note
Unreleased
section ofCHANGELOG.md
?Where is the change documented?
x/{module}/README.md
)