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

refactor: allow zero qualifying balancer shares in CL incentives #6162

Merged
merged 2 commits into from
Aug 25, 2023
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
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## Unreleased

### Bug Fixes

* [#6162](https://github.com/osmosis-labs/osmosis/pull/6162) allow zero qualifying balancer shares in CL incentives

### API breaks

* [#6071](https://github.com/osmosis-labs/osmosis/pull/6071) reduce number of returns for UpdatePosition and TicksToSqrtPrice functions
Expand Down
34 changes: 14 additions & 20 deletions x/concentrated-liquidity/incentives.go
Original file line number Diff line number Diff line change
Expand Up @@ -172,32 +172,24 @@ func (k Keeper) prepareBalancerPoolAsFullRange(ctx sdk.Context, clPoolId uint64,
// relaxed in the future.
// Note that we check denom compatibility later, and pool weights technically do not matter as they
// are analogous to changing the spot price, which is handled by our lower bounding.
if len(balancerPoolLiquidity) != 2 {
// Note that due to low share ratio, the balancer token liquidity may be truncated to zero.
// Balancer liquidity may also upgrade in-full to CL.
if len(balancerPoolLiquidity) > 2 {
return 0, sdk.ZeroDec(), types.ErrInvalidBalancerPoolLiquidityError{ClPoolId: clPoolId, BalancerPoolId: canonicalBalancerPoolId, BalancerPoolLiquidity: balancerPoolLiquidity}
}

// We ensure that the asset ordering is correct when passing Balancer assets into the CL pool.
var asset0Amount, asset1Amount sdk.Int
if balancerPoolLiquidity[0].Denom == clPool.GetToken0() {
asset0Amount = balancerPoolLiquidity[0].Amount
asset1Amount = balancerPoolLiquidity[1].Amount
denom0 := clPool.GetToken0()
denom1 := clPool.GetToken1()

// Ensure second denom matches (bal1 -> CL1)
if balancerPoolLiquidity[1].Denom != clPool.GetToken1() {
return 0, sdk.ZeroDec(), types.ErrInvalidBalancerPoolLiquidityError{ClPoolId: clPoolId, BalancerPoolId: canonicalBalancerPoolId, BalancerPoolLiquidity: balancerPoolLiquidity}
}
} else if balancerPoolLiquidity[0].Denom == clPool.GetToken1() {
asset0Amount = balancerPoolLiquidity[1].Amount
asset1Amount = balancerPoolLiquidity[0].Amount

// Ensure second denom matches (bal1 -> CL0)
if balancerPoolLiquidity[1].Denom != clPool.GetToken0() {
return 0, sdk.ZeroDec(), types.ErrInvalidBalancerPoolLiquidityError{ClPoolId: clPoolId, BalancerPoolId: canonicalBalancerPoolId, BalancerPoolLiquidity: balancerPoolLiquidity}
}
} else {
// This check's purpose is to confirm that denoms are the same.
clCoins := totalBalancerPoolLiquidity.FilterDenoms([]string{denom0, denom1})
if len(clCoins) != 2 {
return 0, sdk.ZeroDec(), types.ErrInvalidBalancerPoolLiquidityError{ClPoolId: clPoolId, BalancerPoolId: canonicalBalancerPoolId, BalancerPoolLiquidity: balancerPoolLiquidity}
}

asset0Amount := balancerPoolLiquidity.AmountOf(denom0)
asset1Amount := balancerPoolLiquidity.AmountOf(denom1)

// Calculate the amount of liquidity the Balancer amounts qualify in the CL pool. Note that since we use the CL spot price, this is
// safe against prices drifting apart between the two pools (we take the lower bound on the qualifying liquidity in this case).
// The `sqrtPriceLowerTick` and `sqrtPriceUpperTick` fields are set to the appropriate values for a full range position.
Expand Down Expand Up @@ -438,7 +430,9 @@ func (k Keeper) updateGivenPoolUptimeAccumulatorsToNow(ctx sdk.Context, pool typ
// Even though this exposes CL LPs to getting immediately diluted by a large Balancer position, this would
// require a lot of capital to be tied up in a two week bond, which is a viable tradeoff given the relative
// simplicity of this approach.
if balancerPoolId != 0 {
// It is possible that the balancer qualifying shares are zero if the bonded liquidity in the
// pool is extremely low. As a result, in that case we simply skip claiming.
if balancerPoolId != 0 && !qualifyingBalancerShares.IsZero() {
_, err := k.claimAndResetFullRangeBalancerPool(ctx, poolId, balancerPoolId, uptimeAccums)
if err != nil {
return err
Expand Down