-
Notifications
You must be signed in to change notification settings - Fork 608
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
(v18: feat) Volume-Split, setup gauges to split evenly #6085
Changes from all commits
6812b45
57a4b1a
7b330ba
58dde1a
c99cb1d
2fe6334
cad538f
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -266,6 +266,70 @@ func (k Keeper) distributeSyntheticInternal( | |
return k.distributeInternal(ctx, gauge, sortedAndTrimmedQualifiedLocks, distrInfo) | ||
} | ||
|
||
// AllocateAcrossGauges gets all the active groupGauges and distributes tokens evenly based on the internalGauges set for that | ||
// groupGauge. After each iteration we update the groupGauge by modifying filledEpoch and distributed coins. | ||
func (k Keeper) AllocateAcrossGauges(ctx sdk.Context) error { | ||
currTime := ctx.BlockTime() | ||
|
||
groupGauges, err := k.GetAllGroupGauges(ctx) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
for _, groupGauge := range groupGauges { | ||
gauge, err := k.GetGaugeByID(ctx, groupGauge.GroupGaugeId) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Err what are we actually getting here? Don't we already have the group gauge? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
if err != nil { | ||
return err | ||
} | ||
|
||
// only allow distribution if the GroupGauge is Active | ||
if gauge.IsActiveGauge(currTime) { | ||
coinsToDistributePerInternalGauge, coinsToDistributeThisEpoch, err := k.calcSplitPolicyCoins(ctx, groupGauge.SplittingPolicy, gauge, groupGauge) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
for _, internalGaugeId := range groupGauge.InternalIds { | ||
err = k.AddToGaugeRewardsFromGauge(ctx, groupGauge.GroupGaugeId, coinsToDistributePerInternalGauge, internalGaugeId) | ||
if err != nil { | ||
return err | ||
} | ||
} | ||
|
||
// we distribute tokens from groupGauge to internal gauge therefore update groupGauge fields | ||
// updates filledEpoch and distributedCoins | ||
k.updateGaugePostDistribute(ctx, *gauge, coinsToDistributeThisEpoch) | ||
} | ||
} | ||
|
||
return nil | ||
} | ||
|
||
// calcSplitPolicyCoins calculates tokens to split given a policy and groupGauge. | ||
// TODO: add volume split policy | ||
func (k Keeper) calcSplitPolicyCoins(ctx sdk.Context, policy types.SplittingPolicy, groupGauge *types.Gauge, groupGaugeObj types.GroupGauge) (sdk.Coins, sdk.Coins, error) { | ||
if policy == types.Evenly { | ||
remainCoins := groupGauge.Coins.Sub(groupGauge.DistributedCoins) | ||
|
||
var coinsDistPerInternalGauge, coinsDistThisEpoch sdk.Coins | ||
for _, coin := range remainCoins { | ||
epochDiff := groupGauge.NumEpochsPaidOver - groupGauge.FilledEpochs | ||
internalGaugeLen := len(groupGaugeObj.InternalIds) | ||
|
||
distPerEpoch := coin.Amount.Quo(sdk.NewIntFromUint64(epochDiff)) | ||
distPerGauge := distPerEpoch.Quo(sdk.NewInt(int64(internalGaugeLen))) | ||
|
||
coinsDistThisEpoch = coinsDistThisEpoch.Add(sdk.NewCoin(coin.Denom, distPerEpoch)) | ||
coinsDistPerInternalGauge = coinsDistPerInternalGauge.Add(sdk.NewCoin(coin.Denom, distPerGauge)) | ||
} | ||
|
||
return coinsDistPerInternalGauge, coinsDistThisEpoch, nil | ||
} else { | ||
return nil, nil, fmt.Errorf("GroupGauge id %d doesnot have enought coins to distribute.", &groupGauge.Id) | ||
} | ||
|
||
} | ||
|
||
// distributeInternal runs the distribution logic for a gauge, and adds the sends to | ||
// the distrInfo struct. It also updates the gauge for the distribution. | ||
// It handles any kind of gauges: | ||
|
@@ -285,6 +349,7 @@ func (k Keeper) distributeInternal( | |
totalDistrCoins := sdk.NewCoins() | ||
|
||
remainCoins := gauge.Coins.Sub(gauge.DistributedCoins) | ||
|
||
// if its a perpetual gauge, we set remaining epochs to 1. | ||
// otherwise is is a non perpetual gauge and we determine how many epoch payouts are left | ||
remainEpochs := uint64(1) | ||
|
@@ -329,7 +394,6 @@ func (k Keeper) distributeInternal( | |
// for ex: 10000uosmo to be distributed over 1day epoch will be 1000 tokens ÷ 86,400 seconds ≈ 0.01157 tokens per second (truncated) | ||
// Note: reason why we do millisecond conversion is because floats are non-deterministic. | ||
emissionRate := sdk.NewDecFromInt(remainAmountPerEpoch).QuoTruncate(sdk.NewDec(currentEpoch.Duration.Milliseconds()).QuoInt(sdk.NewInt(1000))) | ||
|
||
ctx.Logger().Debug("distributeInternal, CreateIncentiveRecord NoLock gauge", "module", types.ModuleName, "gaugeId", gauge.Id, "poolId", pool.GetId(), "remainCoinPerEpoch", remainCoinPerEpoch, "height", ctx.BlockHeight()) | ||
_, err := k.clk.CreateIncentive(ctx, | ||
pool.GetId(), | ||
|
@@ -346,7 +410,6 @@ func (k Keeper) distributeInternal( | |
if err != nil { | ||
return nil, err | ||
} | ||
|
||
totalDistrCoins = totalDistrCoins.Add(remainCoinPerEpoch) | ||
} | ||
} else { | ||
|
@@ -441,6 +504,11 @@ func (k Keeper) Distribute(ctx sdk.Context, gauges []types.Gauge) (sdk.Coins, er | |
ctx.Logger().Debug("distributeSyntheticInternal, gauge id %d, %d", "module", types.ModuleName, "gaugeId", gauge.Id, "height", ctx.BlockHeight()) | ||
gaugeDistributedCoins, err = k.distributeSyntheticInternal(ctx, gauge, filteredLocks, &distrInfo) | ||
} else { | ||
// Do not distribue if LockQueryType = Group, because if we distribute here we will be double distributing. | ||
if gauge.DistributeTo.LockQueryType == lockuptypes.ByGroup { | ||
continue | ||
} | ||
|
||
gaugeDistributedCoins, err = k.distributeInternal(ctx, gauge, filteredLocks, &distrInfo) | ||
} | ||
if err != nil { | ||
|
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.
We should include a splitting policy field here as an enum, even if it currently just evenly splits
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: https://github.com/osmosis-labs/osmosis/pull/6085/files#diff-ba512501fa081ff95a2b23175b9bba1ef438ff455e357e71ce884da0add490d5R54