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

feat: incentive accumulator migration #7416

Merged
merged 38 commits into from
Feb 9, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
38 commits
Select commit Hold shift + click to select a range
246e5f1
feat: scaling factor for pool uptime accumulator
p0mvn Feb 2, 2024
99022a2
changelog
p0mvn Feb 3, 2024
213cec6
updates
p0mvn Feb 5, 2024
04a91c6
updates
p0mvn Feb 5, 2024
880e3d1
Merge branch 'main' into roman/pool-incentive-scaling-factor
p0mvn Feb 5, 2024
1367d0c
handle overflows
p0mvn Feb 5, 2024
748edd8
Apply suggestions from code review
p0mvn Feb 5, 2024
3158f90
updates
p0mvn Feb 5, 2024
f76b9cb
Apply suggestions from code review
p0mvn Feb 5, 2024
f254a26
fix test and clean up
p0mvn Feb 5, 2024
e36f4a1
spelling
p0mvn Feb 5, 2024
9e10789
future proof multiplication overflow
p0mvn Feb 6, 2024
de4b9ba
clean up
p0mvn Feb 6, 2024
8a43a0b
comment
p0mvn Feb 6, 2024
bab4173
lint
p0mvn Feb 6, 2024
fea2d75
Merge branch 'main' into roman/pool-incentive-scaling-factor
p0mvn Feb 7, 2024
5ac3e97
rename
p0mvn Feb 7, 2024
2d49b83
feat: incentive accumulator upgrade handler migration
p0mvn Feb 6, 2024
c5decc9
lint
p0mvn Feb 6, 2024
b1ee555
go mod
p0mvn Feb 6, 2024
32aa8c9
fix test
p0mvn Feb 6, 2024
53bd32d
implement TestMigrateAccumulatorToScalingFactor
p0mvn Feb 7, 2024
c65aaa8
basic genesis test
p0mvn Feb 7, 2024
b58ccbf
fix comment
p0mvn Feb 7, 2024
c03d5e8
clean up tests
p0mvn Feb 7, 2024
e1f07d3
clean up helpers
p0mvn Feb 7, 2024
52b389a
add test for get position IDs by pool ID
p0mvn Feb 7, 2024
3f30364
test for getIncentiveScalingFactorForPool
p0mvn Feb 7, 2024
0004a14
upgrade handler test and tick migration
p0mvn Feb 7, 2024
ab7fa11
update spec
p0mvn Feb 7, 2024
99e3a8d
Merge branch 'main' into roman/upgrade-handler-migration
p0mvn Feb 7, 2024
c9bc00f
Merge branch 'main' into roman/upgrade-handler-migration
p0mvn Feb 8, 2024
7778fe1
updates
p0mvn Feb 8, 2024
68020b1
updates
p0mvn Feb 8, 2024
06c3ad1
feat/fix: add more pools to migrate, fix key parsing bug, add more lo…
p0mvn Feb 9, 2024
56b8146
introduce helper
p0mvn Feb 9, 2024
4ef439b
Update x/concentrated-liquidity/pool.go
p0mvn Feb 9, 2024
71b47b6
Merge branch 'main' into roman/upgrade-handler-migration
mergify[bot] Feb 9, 2024
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
Prev Previous commit
Next Next commit
feat: incentive accumulator upgrade handler migration
  • Loading branch information
p0mvn committed Feb 7, 2024
commit 2d49b83b8e18d53718d74e743412bc9b4faf35e9
46 changes: 46 additions & 0 deletions app/upgrades/v23/upgrades.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package v23

import (
"sort"

sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/types/module"
upgradetypes "github.com/cosmos/cosmos-sdk/x/upgrade/types"
Expand All @@ -9,8 +11,12 @@ import (

"github.com/osmosis-labs/osmosis/v22/app/keepers"
"github.com/osmosis-labs/osmosis/v22/app/upgrades"
concentratedliquidity "github.com/osmosis-labs/osmosis/v22/x/concentrated-liquidity"
concentratedtypes "github.com/osmosis-labs/osmosis/v22/x/concentrated-liquidity/types"
)

const mainnetChainID = "osmosis-1"

func CreateUpgradeHandler(
mm *module.Manager,
configurator module.Configurator,
Expand All @@ -27,6 +33,46 @@ func CreateUpgradeHandler(

keepers.IncentivesKeeper.SetParam(ctx, incentivestypes.KeyInternalUptime, incentivestypes.DefaultConcentratedUptime)

// Snapshot the pool ID migration threshold
// Get the next pool ID
nextPoolId := keepers.PoolManagerKeeper.GetNextPoolId(ctx)

lastPoolID := nextPoolId - 1

keepers.ConcentratedLiquidityKeeper.SetIncentivePoolIDMigrationThreshold(ctx, lastPoolID)

// We only perform the migration on mainnet pools since we hard-coded the pool IDs to migrate
// in the types package. To ensure correctness, we will spin up a state-exported mainnet testnet
// with the same chain ID.
if ctx.ChainID() == mainnetChainID {
if err := migrateMainnetPools(ctx, *keepers.ConcentratedLiquidityKeeper); err != nil {
return nil, err
}
}

return migrations, nil
}
}

// migrateMainnetPools migrates the specified mainnet pools to the new accumulator scaling factor.
func migrateMainnetPools(ctx sdk.Context, concentratedKeeper concentratedliquidity.Keeper) error {

poolIDsToMigrate := make([]uint64, 0, len(concentratedtypes.MigratedIncentiveAccumulatorPoolIDs))
for poolID := range concentratedtypes.MigratedIncentiveAccumulatorPoolIDs {
poolIDsToMigrate = append(poolIDsToMigrate, poolID)
}

// Sort for determinism
sort.Slice(poolIDsToMigrate, func(i, j int) bool {
return poolIDsToMigrate[i] < poolIDsToMigrate[j]
})

// Migrate concentrated pools
for _, poolId := range poolIDsToMigrate {
if err := concentratedKeeper.MigrateAccumulatorToScalingFactor(ctx, poolId); err != nil {
return err
}
}

return nil
}
13 changes: 13 additions & 0 deletions osmoutils/accum/accum.go
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,19 @@ func MakeAccumulatorWithValueAndShare(accumStore store.KVStore, accumName string
return setAccumulator(&newAccum, accumValue, totalShares)
}

// OverwriteAccumulatorUnsafe overwrites the accumulator with the given name in accumStore.
// Use with caution as this method is only meant for use in migrations.
func OverwriteAccumulatorUnsafe(accumStore store.KVStore, accumName string, accumValue sdk.DecCoins, totalShares osmomath.Dec) error {
if !accumStore.Has(formatAccumPrefixKey(accumName)) {
return errors.New("Accumulator with given name does not exist in store")
}

newAccum := AccumulatorObject{accumStore, accumName, accumValue, totalShares}
p0mvn marked this conversation as resolved.
Show resolved Hide resolved

// Stores accumulator in state
return setAccumulator(&newAccum, accumValue, totalShares)
}

// Gets the current value of the accumulator corresponding to accumName in accumStore
func GetAccumulator(accumStore store.KVStore, accumName string) (*AccumulatorObject, error) {
accumContent := AccumulatorContent{}
Expand Down
4 changes: 4 additions & 0 deletions proto/osmosis/concentratedliquidity/v1beta1/genesis.proto
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,10 @@ message GenesisState {

uint64 next_incentive_record_id = 5
[ (gogoproto.moretags) = "yaml:\"next_incentive_record_id\"" ];

uint64 incentives_accumulator_pool_id_migration_threshold = 6
[ (gogoproto.moretags) =
"yaml:\"incentives_accumulator_pool_id_migration_threshold\"" ];
}

message AccumObject {
Expand Down
10 changes: 6 additions & 4 deletions x/concentrated-liquidity/export_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ var (
TwoHundredFooCoins = sdk.NewDecCoin("foo", osmomath.NewInt(200))
TwoHundredBarCoins = sdk.NewDecCoin("bar", osmomath.NewInt(200))
PerUnitLiqScalingFactor = perUnitLiqScalingFactor

OneDecScalingFactor = oneDecScalingFactor
)

func (k Keeper) SetPool(ctx sdk.Context, pool types.ConcentratedPoolExtension) error {
Expand Down Expand Up @@ -232,8 +234,8 @@ func (k Keeper) CreateUptimeAccumulators(ctx sdk.Context, poolId uint64) error {
return k.createUptimeAccumulators(ctx, poolId)
}

func CalcAccruedIncentivesForAccum(ctx sdk.Context, accumUptime time.Duration, qualifyingLiquidity osmomath.Dec, timeElapsed osmomath.Dec, poolIncentiveRecords []types.IncentiveRecord) (sdk.DecCoins, []types.IncentiveRecord, error) {
return calcAccruedIncentivesForAccum(ctx, accumUptime, qualifyingLiquidity, timeElapsed, poolIncentiveRecords, 0)
func CalcAccruedIncentivesForAccum(ctx sdk.Context, accumUptime time.Duration, qualifyingLiquidity osmomath.Dec, timeElapsed osmomath.Dec, poolIncentiveRecords []types.IncentiveRecord, scalingFactorForPool osmomath.Dec) (sdk.DecCoins, []types.IncentiveRecord, error) {
return calcAccruedIncentivesForAccum(ctx, accumUptime, qualifyingLiquidity, timeElapsed, poolIncentiveRecords, 0, scalingFactorForPool)
}

func (k Keeper) UpdateGivenPoolUptimeAccumulatorsToNow(ctx sdk.Context, pool types.ConcentratedPoolExtension, uptimeAccums []*accum.AccumulatorObject) error {
Expand Down Expand Up @@ -346,8 +348,8 @@ func (k Keeper) GetPoolHookContract(ctx sdk.Context, poolId uint64, actionPrefix
return k.getPoolHookContract(ctx, poolId, actionPrefix)
}

func ScaleUpTotalEmittedAmount(totalEmittedAmount osmomath.Dec) (scaledTotalEmittedAmount osmomath.Dec, err error) {
return scaleUpTotalEmittedAmount(totalEmittedAmount)
func ScaleUpTotalEmittedAmount(totalEmittedAmount osmomath.Dec, scalingFactor osmomath.Dec) (scaledTotalEmittedAmount osmomath.Dec, err error) {
return scaleUpTotalEmittedAmount(totalEmittedAmount, scalingFactor)
}

func ComputeTotalIncentivesToEmit(timeElapsedSeconds osmomath.Dec, emissionRate osmomath.Dec) (totalEmittedAmount osmomath.Dec, err error) {
Expand Down
9 changes: 9 additions & 0 deletions x/concentrated-liquidity/genesis.go
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,8 @@ func (k Keeper) InitGenesis(ctx sdk.Context, genState genesis.GenesisState) {

// set total liquidity
k.setTotalLiquidity(ctx, totalLiquidity)

k.SetIncentivePoolIDMigrationThreshold(ctx, genState.IncentivesAccumulatorPoolIdMigrationThreshold)
}

// ExportGenesis returns the concentrated-liquidity module's exported genesis state.
Expand Down Expand Up @@ -230,12 +232,19 @@ func (k Keeper) ExportGenesis(ctx sdk.Context) *genesis.GenesisState {
})
}

// Get the incentive pool ID migration threshold
incentivesAccumulatorPoolIDMigrationThreshold, err := k.GetIncentivePoolIDMigrationThreshold(ctx)
if err != nil {
panic(err)
}

return &genesis.GenesisState{
Params: k.GetParams(ctx),
PoolData: poolData,
PositionData: positionData,
NextPositionId: k.GetNextPositionId(ctx),
NextIncentiveRecordId: k.GetNextIncentiveRecordId(ctx),
IncentivesAccumulatorPoolIdMigrationThreshold: incentivesAccumulatorPoolIDMigrationThreshold,
}
}

Expand Down
63 changes: 57 additions & 6 deletions x/concentrated-liquidity/incentives.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,10 @@ import (
//
// More analysis on the choice of scaling factor can be found here:
// https://hackmd.io/o3oqT8VhSPKAiqNl_mlxXQ
var perUnitLiqScalingFactor = osmomath.NewDec(1e15).MulMut(osmomath.NewDec(1e12))
var (
perUnitLiqScalingFactor = osmomath.NewDec(1e15).MulMut(osmomath.NewDec(1e12))
oneDecScalingFactor = osmomath.OneDec()
)

// createUptimeAccumulators creates accumulator objects in store for each supported uptime for the given poolId.
// The accumulators are initialized with the default (zero) values.
Expand Down Expand Up @@ -191,6 +194,11 @@ func (k Keeper) updateGivenPoolUptimeAccumulatorsToNow(ctx sdk.Context, pool typ
return err
}

incentiveScalingFactorForPool, err := k.getIncentiveScalingFactorForPool(ctx, poolId)
if err != nil {
return err
}

// We optimistically assume that all liquidity on the active tick qualifies and handle
// uptime-related checks in forfeiting logic.

Expand All @@ -200,7 +208,7 @@ func (k Keeper) updateGivenPoolUptimeAccumulatorsToNow(ctx sdk.Context, pool typ
for uptimeIndex := range uptimeAccums {
// Get relevant uptime-level values
curUptimeDuration := types.SupportedUptimes[uptimeIndex]
incentivesToAddToCurAccum, updatedPoolRecords, err := calcAccruedIncentivesForAccum(ctx, curUptimeDuration, qualifyingLiquidity, timeElapsedSec, poolIncentiveRecords, poolId)
incentivesToAddToCurAccum, updatedPoolRecords, err := calcAccruedIncentivesForAccum(ctx, curUptimeDuration, qualifyingLiquidity, timeElapsedSec, poolIncentiveRecords, poolId, incentiveScalingFactorForPool)
if err != nil {
return err
}
Expand Down Expand Up @@ -233,7 +241,7 @@ func (k Keeper) updateGivenPoolUptimeAccumulatorsToNow(ctx sdk.Context, pool typ
// Returns the IncentivesPerLiquidity value and an updated list of IncentiveRecords that
// reflect emitted incentives
// Returns error if the qualifying liquidity/time elapsed are zero.
func calcAccruedIncentivesForAccum(ctx sdk.Context, accumUptime time.Duration, liquidityInAccum osmomath.Dec, timeElapsed osmomath.Dec, poolIncentiveRecords []types.IncentiveRecord, poolID uint64) (sdk.DecCoins, []types.IncentiveRecord, error) {
func calcAccruedIncentivesForAccum(ctx sdk.Context, accumUptime time.Duration, liquidityInAccum osmomath.Dec, timeElapsed osmomath.Dec, poolIncentiveRecords []types.IncentiveRecord, poolID uint64, incentiveScalingFactorForPool osmomath.Dec) (sdk.DecCoins, []types.IncentiveRecord, error) {
if !liquidityInAccum.IsPositive() || !timeElapsed.IsPositive() {
return sdk.DecCoins{}, []types.IncentiveRecord{}, types.QualifyingLiquidityOrTimeElapsedNotPositiveError{QualifyingLiquidity: liquidityInAccum, TimeElapsed: timeElapsed}
}
Expand All @@ -260,7 +268,7 @@ func calcAccruedIncentivesForAccum(ctx sdk.Context, accumUptime time.Duration, l

// We scale up the remaining rewards to avoid truncation to zero
// when dividing by the liquidity in the accumulator.
scaledTotalEmittedAmount, err := scaleUpTotalEmittedAmount(totalEmittedAmount)
scaledTotalEmittedAmount, err := scaleUpTotalEmittedAmount(totalEmittedAmount, incentiveScalingFactorForPool)
if err != nil {
ctx.Logger().Info(types.IncentiveOverflowPlaceholderName, "pool_id", poolID, "incentive_id", incentiveRecord.IncentiveId, "time_elapsed", timeElapsed, "emission_rate", incentiveRecordBody.EmissionRate, "error", err.Error())
// Silently ignore the truncated incentive record to avoid halting the entire accumulator update.
Expand Down Expand Up @@ -295,7 +303,7 @@ func calcAccruedIncentivesForAccum(ctx sdk.Context, accumUptime time.Duration, l

// We scale up the remaining rewards to avoid truncation to zero
// when dividing by the liquidity in the accumulator.
remainingRewardsScaled, err := scaleUpTotalEmittedAmount(remainingRewards)
remainingRewardsScaled, err := scaleUpTotalEmittedAmount(remainingRewards, incentiveScalingFactorForPool)
if err != nil {
ctx.Logger().Info(types.IncentiveOverflowPlaceholderName, "pool_id", poolID, "incentive_id", incentiveRecord.IncentiveId, "time_elapsed", timeElapsed, "emission_rate", incentiveRecordBody.EmissionRate, "error", err.Error())
// Silently ignore the truncated incentive record to avoid halting the entire accumulator update.
Expand All @@ -320,7 +328,7 @@ func calcAccruedIncentivesForAccum(ctx sdk.Context, accumUptime time.Duration, l

// scaleUpTotalEmittedAmount scales up the total emitted amount to avoid truncation to zero.
// Returns error if the total emitted amount is too high and causes overflow when applying scaling factor.
func scaleUpTotalEmittedAmount(totalEmittedAmount osmomath.Dec) (scaledTotalEmittedAmount osmomath.Dec, err error) {
func scaleUpTotalEmittedAmount(totalEmittedAmount osmomath.Dec, scalingFactor osmomath.Dec) (scaledTotalEmittedAmount osmomath.Dec, err error) {
defer func() {
r := recover()

Expand Down Expand Up @@ -1032,3 +1040,46 @@ func emitAccumulatorUpdateTelemetry(ctx sdk.Context, truncatedPlaceholder, emitt
ctx.Logger().Info(emittedPlaceholder, "pool_id", poolID, "total_liq", liquidityInAccum, "per_unit_liq", rewardsPerUnitOfLiquidity, "total_amt", rewardsTotal, extraKeyVals)
}
}

func (k Keeper) getIncentiveScalingFactorForPool(ctx sdk.Context, poolID uint64) (osmomath.Dec, error) {
migrationThreshold, err := k.GetIncentivePoolIDMigrationThreshold(ctx)
if err != nil {
return osmomath.Dec{}, err
}

if poolID > migrationThreshold {
p0mvn marked this conversation as resolved.
Show resolved Hide resolved
return perUnitLiqScalingFactor, nil
}

_, isMigrated := types.MigratedIncentiveAccumulatorPoolIDs[poolID]

if isMigrated {
return perUnitLiqScalingFactor, nil
}

return oneDecScalingFactor, nil
}

// SetIncentivePoolIDMigrationThreshold sets the pool ID migration threshold to the last pool ID.
func (k Keeper) SetIncentivePoolIDMigrationThreshold(ctx sdk.Context, poolIDThreshold uint64) {

// Set the pool ID migration threshold to the last pool ID
store := ctx.KVStore(k.storeKey)

store.Set(types.KeyIncentiveAccumulatorMigrationThreshold, sdk.Uint64ToBigEndian(poolIDThreshold))
}

// GetIncentivePoolIDMigrationThreshold returns the pool ID migration threshold.
func (k Keeper) GetIncentivePoolIDMigrationThreshold(ctx sdk.Context) (uint64, error) {
store := ctx.KVStore(k.storeKey)

bz := store.Get(types.KeyIncentiveAccumulatorMigrationThreshold)

if bz == nil {
return 0, fmt.Errorf("incentive accumulator migration threshold not found")
}

threshold := sdk.BigEndianToUint64(bz)

return threshold, nil
}
6 changes: 3 additions & 3 deletions x/concentrated-liquidity/incentives_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -734,7 +734,7 @@ func (s *KeeperTestSuite) TestCalcAccruedIncentivesForAccum() {
s.PrepareConcentratedPool()

// system under test
actualResult, updatedPoolRecords, err := cl.CalcAccruedIncentivesForAccum(s.Ctx, tc.accumUptime, tc.qualifyingLiquidity, osmomath.NewDec(int64(tc.timeElapsed)).Quo(osmomath.MustNewDecFromStr("1000000000")), tc.poolIncentiveRecords)
actualResult, updatedPoolRecords, err := cl.CalcAccruedIncentivesForAccum(s.Ctx, tc.accumUptime, tc.qualifyingLiquidity, osmomath.NewDec(int64(tc.timeElapsed)).Quo(osmomath.MustNewDecFromStr("1000000000")), tc.poolIncentiveRecords, cl.OneDecScalingFactor)
if tc.expectedPass {
s.Require().NoError(err)

Expand Down Expand Up @@ -3682,11 +3682,11 @@ func (s *KeeperTestSuite) TestIncentiveTruncation() {
// This test shows that the scaling factor is applied correctly to the total incentive amount.
// If overflow occurs, the function returns error as opposed to panicking.
func (s *KeeperTestSuite) TestScaledUpTotalIncentiveAmount() {
scaledIncentiveAmount, err := cl.ScaleUpTotalEmittedAmount(osmomath.NewDec(1))
scaledIncentiveAmount, err := cl.ScaleUpTotalEmittedAmount(osmomath.NewDec(1), cl.PerUnitLiqScalingFactor)
s.Require().NoError(err)
s.Require().Equal(osmomath.NewDec(1).Mul(cl.PerUnitLiqScalingFactor), scaledIncentiveAmount)

_, err = cl.ScaleUpTotalEmittedAmount(oneE60Dec)
_, err = cl.ScaleUpTotalEmittedAmount(oneE60Dec, cl.PerUnitLiqScalingFactor)
s.Require().Error(err)
s.Require().ErrorContains(err, "overflow")
}
Expand Down
52 changes: 52 additions & 0 deletions x/concentrated-liquidity/pool.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import (

"github.com/osmosis-labs/osmosis/osmomath"
"github.com/osmosis-labs/osmosis/osmoutils"
"github.com/osmosis-labs/osmosis/osmoutils/accum"
"github.com/osmosis-labs/osmosis/v22/x/concentrated-liquidity/model"
types "github.com/osmosis-labs/osmosis/v22/x/concentrated-liquidity/types"
lockuptypes "github.com/osmosis-labs/osmosis/v22/x/lockup/types"
Expand Down Expand Up @@ -418,3 +419,54 @@ func (k Keeper) GetUserUnbondingPositions(ctx sdk.Context, address sdk.AccAddres
}
return userPositionsWithPeriodLocks, nil
}

func (k Keeper) MigrateAccumulatorToScalingFactor(ctx sdk.Context, poolId uint64) error {
// Get pool-global incentive accumulator
uptimeAccums, err := k.GetUptimeAccumulators(ctx, poolId)
if err != nil {
return err
}

// Get all position IDs belonging to the pool
positionIDs, err := k.GetAllPositionIdsForPoolId(ctx, types.KeyPoolPosition(poolId), poolId)
if err != nil {
return err
}

// For each uptime accimulator, multiply the value by the per-unit liquidity scaling factor
p0mvn marked this conversation as resolved.
Show resolved Hide resolved
// and overwrite the accumulator with the new value.
p0mvn marked this conversation as resolved.
Show resolved Hide resolved
for uptimeIndex, uptimeAccum := range uptimeAccums {
value := uptimeAccum.GetValue().MulDecTruncate(perUnitLiqScalingFactor)
if err := accum.OverwriteAccumulatorUnsafe(ctx.KVStore(k.storeKey), types.KeyUptimeAccumulator(poolId, uint64(uptimeIndex)), value, uptimeAccum.GetTotalShares()); err != nil {
return err
}

// For each position ID, multiply the value by the per-unit liquidity scaling factor
// and overwrite the accumulator with the new value.
for _, positionID := range positionIDs {

positionPrefix := types.KeyPositionId(positionID)

if !uptimeAccum.HasPosition(string(positionPrefix)) {
return fmt.Errorf("position ID %d not found in uptime accumulator %d in pool %d", positionID, uptimeIndex, poolId)
}

positionSnapshot, err := uptimeAccum.GetPosition(string(positionPrefix))
if err != nil {
return err
}

positionSnapshotValue := positionSnapshot.GetAccumValuePerShare()

// Multiply the value by the per-unit liquidity scaling factor
newValue := positionSnapshotValue.MulDecTruncate(perUnitLiqScalingFactor)
p0mvn marked this conversation as resolved.
Show resolved Hide resolved

// Overwrite the position accumulator with the new value
if err := uptimeAccum.SetPositionIntervalAccumulation(string(positionPrefix), newValue); err != nil {
return err
}
}
}

return nil
}
2 changes: 1 addition & 1 deletion x/concentrated-liquidity/position_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -314,7 +314,7 @@ func (s *KeeperTestSuite) TestInitOrUpdatePosition() {
// Track how much the current uptime accum has grown by
actualUptimeAccumDelta[uptimeIndex] = newUptimeAccumValues[uptimeIndex].Sub(initUptimeAccumValues[uptimeIndex])
if timeElapsedSec.IsPositive() {
expectedGrowthCurAccum, _, err := cl.CalcAccruedIncentivesForAccum(s.Ctx, uptime, test.param.liquidityDelta, timeElapsedSec, expectedIncentiveRecords)
expectedGrowthCurAccum, _, err := cl.CalcAccruedIncentivesForAccum(s.Ctx, uptime, test.param.liquidityDelta, timeElapsedSec, expectedIncentiveRecords, cl.OneDecScalingFactor)
s.Require().NoError(err)
expectedUptimeAccumValueGrowth[uptimeIndex] = expectedGrowthCurAccum
}
Expand Down
2 changes: 2 additions & 0 deletions x/concentrated-liquidity/types/genesis/genesis.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ func DefaultGenesis() *GenesisState {
Params: types.DefaultParams(),
NextPositionId: 1,
NextIncentiveRecordId: 1,
// By default, the migration threshold is set to 0, which means no pools are migrated.
IncentivesAccumulatorPoolIdMigrationThreshold: 0,
}
}

Expand Down
Loading