Skip to content

Commit

Permalink
feat: telemetry for spread factor truncation (#7408)
Browse files Browse the repository at this point in the history
* feat: telemetry for spread factor truncation

* helper for telemetry updates

* reuse telemetry helper

(cherry picked from commit f056947)
  • Loading branch information
p0mvn authored and mergify[bot] committed Feb 3, 2024
1 parent 4508d63 commit 35865d7
Show file tree
Hide file tree
Showing 4 changed files with 43 additions and 11 deletions.
4 changes: 2 additions & 2 deletions x/concentrated-liquidity/export_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -204,8 +204,8 @@ func (k Keeper) AddToPosition(ctx sdk.Context, owner sdk.AccAddress, positionId
return k.addToPosition(ctx, owner, positionId, amount0Added, amount1Added, amount0Min, amount1Min)
}

func (ss *SwapState) UpdateSpreadRewardGrowthGlobal(spreadRewardChargeTotal osmomath.Dec) {
ss.updateSpreadRewardGrowthGlobal(spreadRewardChargeTotal)
func (ss *SwapState) UpdateSpreadRewardGrowthGlobal(spreadRewardChargeTotal osmomath.Dec) osmomath.Dec {
return ss.updateSpreadRewardGrowthGlobal(spreadRewardChargeTotal)
}

// Test helpers.
Expand Down
27 changes: 22 additions & 5 deletions x/concentrated-liquidity/incentives.go
Original file line number Diff line number Diff line change
Expand Up @@ -246,11 +246,8 @@ func calcAccruedIncentivesForAccum(ctx sdk.Context, accumUptime time.Duration, l
// Note that we truncate to ensure we do not overdistribute incentives
incentivesPerLiquidity := totalEmittedAmount.QuoTruncate(liquidityInAccum)

// If truncation occurs, we emit events to alert us of the issue.
if incentivesPerLiquidity.IsZero() && !totalEmittedAmount.IsZero() {
telemetry.IncrCounter(1, types.IncentiveTruncationPlaceholderName)
ctx.Logger().Error(types.IncentiveTruncationPlaceholderName, "pool_id", poolID, "total_liq", liquidityInAccum, "per_unit_liq", incentivesPerLiquidity, "total_amt", totalEmittedAmount)
}
// Emit telemetry for accumulator updates
emitAccumulatorUpdateTelemetry(ctx, types.IncentiveTruncationPlaceholderName, types.IncentiveEmissionPlaceholderName, incentivesPerLiquidity, totalEmittedAmount, poolID, liquidityInAccum)

emittedIncentivesPerLiquidity := sdk.NewDecCoinFromDec(incentiveRecordBody.RemainingCoin.Denom, incentivesPerLiquidity)

Expand All @@ -271,6 +268,10 @@ func calcAccruedIncentivesForAccum(ctx sdk.Context, accumUptime time.Duration, l
// When the returned records are set in state, all records with remaining rewards of zero will be cleared.
remainingIncentivesPerLiquidity := remainingRewards.QuoTruncate(liquidityInAccum)
emittedIncentivesPerLiquidity = sdk.NewDecCoinFromDec(incentiveRecordBody.RemainingCoin.Denom, remainingIncentivesPerLiquidity)

// Emit telemetry for accumulator updates
emitAccumulatorUpdateTelemetry(ctx, types.IncentiveTruncationPlaceholderName, types.IncentiveEmissionPlaceholderName, remainingIncentivesPerLiquidity, remainingRewards, poolID, liquidityInAccum)

incentivesToAddToCurAccum = incentivesToAddToCurAccum.Add(emittedIncentivesPerLiquidity)

copyPoolIncentiveRecords[incentiveIndex].IncentiveRecordBody.RemainingCoin.Amount = osmomath.ZeroDec()
Expand Down Expand Up @@ -925,3 +926,19 @@ func (k Keeper) getLargestAuthorizedUptimeDuration(ctx sdk.Context) time.Duratio
func (k Keeper) getLargestSupportedUptimeDuration() time.Duration {
return getLargestDuration(types.SupportedUptimes)
}

// emitAccumulatorUpdateTelemetry emits telemetry for accumulator updates
// It detects whether an accumulator update does not occur when expected due to truncation or does occur and emits the appropriate telemetry
func emitAccumulatorUpdateTelemetry(ctx sdk.Context, truncatedPlaceholder, emittedPlaceholder string, rewardsPerUnitOfLiquidity, rewardsTotal osmomath.Dec, poolID uint64, liquidityInAccum osmomath.Dec, extraKeyVals ...interface{}) {
// If truncation occurs, we emit events to alert us of the issue.
if rewardsPerUnitOfLiquidity.IsZero() && !rewardsTotal.IsZero() {
telemetry.IncrCounter(1, truncatedPlaceholder)
ctx.Logger().Error(truncatedPlaceholder, "pool_id", poolID, "total_liq", liquidityInAccum, "per_unit_liq", rewardsPerUnitOfLiquidity, "total_amt", rewardsTotal, extraKeyVals)

// We emit events for these pools specifically as they are at the border of truncation in terms of liquidity
// TODO: remove these after scaling factor approach is implemented
} else if poolID == (1423) || poolID == (1213) {
telemetry.IncrCounter(1, emittedPlaceholder)
ctx.Logger().Info(emittedPlaceholder, "pool_id", poolID, "total_liq", liquidityInAccum, "per_unit_liq", rewardsPerUnitOfLiquidity, "total_amt", rewardsTotal, extraKeyVals)
}
}
19 changes: 15 additions & 4 deletions x/concentrated-liquidity/swaps.go
Original file line number Diff line number Diff line change
Expand Up @@ -112,15 +112,20 @@ var (
// between the ticks. This is possible when there are only 2 positions with no overlapping ranges.
// As a result, the range from the end of position one to the beginning of position
// two has no liquidity and can be skipped.
func (ss *SwapState) updateSpreadRewardGrowthGlobal(spreadRewardChargeTotal osmomath.Dec) {
//
// Returbs the spread factors accrued per unit of liquidity.
func (ss *SwapState) updateSpreadRewardGrowthGlobal(spreadRewardChargeTotal osmomath.Dec) osmomath.Dec {
ss.globalSpreadRewardGrowth = ss.globalSpreadRewardGrowth.Add(spreadRewardChargeTotal)
if ss.liquidity.IsZero() {
return
return osmomath.ZeroDec()
}
// We round down here since we want to avoid overdistributing (the "spread factor charge" refers to
// the total spread factors that will be accrued to the spread factor accumulator)
spreadFactorsAccruedPerUnitOfLiquidity := spreadRewardChargeTotal.QuoTruncate(ss.liquidity)

ss.globalSpreadRewardGrowthPerUnitLiquidity.AddMut(spreadFactorsAccruedPerUnitOfLiquidity)

return spreadFactorsAccruedPerUnitOfLiquidity
}

func (k Keeper) SwapExactAmountIn(
Expand Down Expand Up @@ -429,7 +434,10 @@ func (k Keeper) computeOutAmtGivenIn(
}

// Update the spread reward growth for the entire swap using the total spread factors charged.
swapState.updateSpreadRewardGrowthGlobal(spreadRewardCharge)
spreadFactorsAccruedPerUnitOfLiquidity := swapState.updateSpreadRewardGrowthGlobal(spreadRewardCharge)

// Emit telemetry to detect spread reward truncation.
emitAccumulatorUpdateTelemetry(ctx, types.SpreadFactorTruncationPlaceholderName, types.SpreadRewardEmissionPlaceholderName, spreadFactorsAccruedPerUnitOfLiquidity, spreadRewardCharge, poolId, swapState.liquidity, "is_out_given_in", true)

ctx.Logger().Debug("cl calc out given in")
emitSwapDebugLogs(ctx, swapState, computedSqrtPrice, amountIn, amountOut, spreadRewardCharge)
Expand Down Expand Up @@ -554,7 +562,10 @@ func (k Keeper) computeInAmtGivenOut(
return SwapResult{}, PoolUpdates{}, err
}

swapState.updateSpreadRewardGrowthGlobal(spreadRewardChargeTotal)
spreadFactorsAccruedPerUnitOfLiquidity := swapState.updateSpreadRewardGrowthGlobal(spreadRewardChargeTotal)

// Emit telemetry to detect spread reward truncation.
emitAccumulatorUpdateTelemetry(ctx, types.SpreadFactorTruncationPlaceholderName, types.SpreadRewardEmissionPlaceholderName, spreadFactorsAccruedPerUnitOfLiquidity, spreadRewardChargeTotal, poolId, swapState.liquidity, "is_out_given_in", false)

ctx.Logger().Debug("cl calc in given out")
emitSwapDebugLogs(ctx, swapState, computedSqrtPrice, amountIn, amountOut, spreadRewardChargeTotal)
Expand Down
4 changes: 4 additions & 0 deletions x/concentrated-liquidity/types/events.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,5 +49,9 @@ const (
AttributeKeyUptimeGrowthOppositeDirectionOfLastTraversal = "uptime_growth"
AttributeNewOwner = "new_owner"

IncentiveEmissionPlaceholderName = "concentrated_liquidity_incentive_emission"
IncentiveTruncationPlaceholderName = "concentrated_liquidity_incentive_truncation"

SpreadRewardEmissionPlaceholderName = "concentrated_liquidity_spread_reward_emission"
SpreadFactorTruncationPlaceholderName = "concentrated_liquidity_sptread_factor_truncation"
)

0 comments on commit 35865d7

Please sign in to comment.