From 8d63d64ae5ca8d930087c595f9fa112162359c52 Mon Sep 17 00:00:00 2001 From: Matthias <97468149+matthiasmatt@users.noreply.github.com> Date: Thu, 15 Feb 2024 17:39:59 +0100 Subject: [PATCH] fix(inflation): num skipped epochs tracking (#1797) * fix: fix bug on inflation * chore: changelog * fix: add bool to see wether inflation ever started * fix: epoch off by one error * chore: unwire epochs keeper from inflation keeper * fix: off by one tests --------- Co-authored-by: Kevin Yang <5478483+k-yang@users.noreply.github.com> --- CHANGELOG.md | 1 + app/keepers.go | 2 +- proto/nibiru/inflation/v1/genesis.proto | 5 + x/inflation/client/cli/tx.go | 2 - x/inflation/keeper/hooks.go | 34 +++- x/inflation/keeper/hooks_test.go | 260 ++++++++++++------------ x/inflation/keeper/keeper.go | 3 - x/inflation/keeper/sudo.go | 13 +- x/inflation/types/events.go | 2 +- x/inflation/types/genesis.pb.go | 103 +++++++--- x/inflation/types/interfaces.go | 6 - x/inflation/types/params.go | 7 + x/inflation/types/params_test.go | 31 +-- 13 files changed, 265 insertions(+), 204 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5c2aa35ec..da529ac05 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -61,6 +61,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - [#1792](https://github.com/NibiruChain/nibiru/pull/1792) - fix(inflation): uncomment legacy amino register on app module basic - [#1795](https://github.com/NibiruChain/nibiru/pull/1795) - feat(inflation): add inflation tx cmds - [#1796](https://github.com/NibiruChain/nibiru/pull/1796) - fix(inflation): fix num skipped epoch when inflation is added to an existing chain +- [#1797](https://github.com/NibiruChain/nibiru/pull/1797) - fix(inflation): fix num skipped epoch updates logic #### Dapp modules: perp, spot, etc diff --git a/app/keepers.go b/app/keepers.go index b0412f8d7..10418a946 100644 --- a/app/keepers.go +++ b/app/keepers.go @@ -379,7 +379,7 @@ func (app *NibiruApp) InitKeepers( app.InflationKeeper = inflationkeeper.NewKeeper( appCodec, keys[inflationtypes.StoreKey], app.GetSubspace(inflationtypes.ModuleName), - app.AccountKeeper, app.BankKeeper, app.DistrKeeper, app.stakingKeeper, app.SudoKeeper, authtypes.FeeCollectorName, app.EpochsKeeper, + app.AccountKeeper, app.BankKeeper, app.DistrKeeper, app.stakingKeeper, app.SudoKeeper, authtypes.FeeCollectorName, ) app.EpochsKeeper.SetHooks( diff --git a/proto/nibiru/inflation/v1/genesis.proto b/proto/nibiru/inflation/v1/genesis.proto index e72fff223..773bfaef5 100644 --- a/proto/nibiru/inflation/v1/genesis.proto +++ b/proto/nibiru/inflation/v1/genesis.proto @@ -42,4 +42,9 @@ message Params { // max_period is the maximum number of periods that have inflation being // paid off. After this period, inflation will be disabled. uint64 max_period = 6; + + // has_inflation_started is the parameter that indicates if inflation has + // started. It's set to false at the starts, and stays at true when we toggle + // inflation on. It's used to track num skipped epochs + bool has_inflation_started = 7; } diff --git a/x/inflation/client/cli/tx.go b/x/inflation/client/cli/tx.go index 5c3f1253e..a66b46db0 100644 --- a/x/inflation/client/cli/tx.go +++ b/x/inflation/client/cli/tx.go @@ -1,7 +1,6 @@ package cli import ( - "fmt" "strings" "github.com/cosmos/cosmos-sdk/client" @@ -126,7 +125,6 @@ $ nibid tx oracle edit-params --staking-proportion 0.6 --community-pool-proporti if polynomialFactors, _ := cmd.Flags().GetString("polynomial-factors"); polynomialFactors != "" { polynomialFactorsArr := strings.Split(polynomialFactors, ",") - fmt.Println(polynomialFactorsArr) realPolynomialFactors := make([]sdk.Dec, len(polynomialFactorsArr)) for i, factor := range polynomialFactorsArr { factorDec := sdk.MustNewDecFromStr(factor) diff --git a/x/inflation/keeper/hooks.go b/x/inflation/keeper/hooks.go index e186ad2e1..420ec0b5f 100644 --- a/x/inflation/keeper/hooks.go +++ b/x/inflation/keeper/hooks.go @@ -27,14 +27,22 @@ func (k Keeper) AfterEpochEnd(ctx sdk.Context, epochIdentifier string, epochNumb // Skip inflation if it is disabled and increment number of skipped epochs if !params.InflationEnabled { - prevSkippedEpochs := k.NumSkippedEpochs.Next(ctx) + var prevSkippedEpochs uint64 + if !params.HasInflationStarted { + // If the inflation never started, we use epochNumber as the number of skipped epochs + // to avoid missing periods when we upgrade a chain. + k.NumSkippedEpochs.Set(ctx, epochNumber) + prevSkippedEpochs = epochNumber + } else { + prevSkippedEpochs = k.NumSkippedEpochs.Next(ctx) + } k.Logger(ctx).Debug( "skipping inflation mint and allocation", "height", ctx.BlockHeight(), "epoch-id", epochIdentifier, "epoch-number", epochNumber, - "skipped-epochs", prevSkippedEpochs+1, + "skipped-epochs", prevSkippedEpochs, ) return } @@ -76,15 +84,19 @@ func (k Keeper) AfterEpochEnd(ctx sdk.Context, epochIdentifier string, epochNumb // where inflation minted tokens. // // Examples: - // Given, epochNumber = 1, period = 0, epochPerPeriod = 365, skippedEpochs = 0 - // => 1 - 365 * 0 - 0 < 365 --- nothing to do here - // Given, epochNumber = 741, period = 1, epochPerPeriod = 365, skippedEpochs = 10 - // => 741 - 1 * 365 - 10 > 365 --- a period has passed! we set a new period - peek := k.NumSkippedEpochs.Peek(ctx) + // Given, epochNumber = 1, period = 0, epochPerPeriod = 30, skippedEpochs = 0 + // => 1 - 30 * 0 - 0 < 30 --- nothing to do here + // Given, epochNumber = 70, period = 1, epochPerPeriod = 30, skippedEpochs = 10 + // => 70 - 1 * 30 - 10 >= 30 --- a period has ended! we set a new period + // Given, epochNumber = 42099, period = 0, epochPerPeriod = 30, skippedEpochs = 42069 + // => 42099 - 0 * 30 - 42069 >= 30 --- a period has ended! we set a new period + numSkippedEpochs := k.NumSkippedEpochs.Peek(ctx) if int64(epochNumber)- int64(epochsPerPeriod*period)- - int64(peek) >= int64(epochsPerPeriod)-1 { - k.CurrentPeriod.Next(ctx) + int64(numSkippedEpochs) >= int64(epochsPerPeriod) { + prevPeriod := k.CurrentPeriod.Next(ctx) + + k.Logger(ctx).Info(fmt.Sprintf("setting new period: %d", prevPeriod+1)) } defer func() { @@ -124,8 +136,8 @@ func (k Keeper) AfterEpochEnd(ctx sdk.Context, epochIdentifier string, epochNumb ctx.EventManager().EmitEvent( sdk.NewEvent( - types.EventTypeMint, - sdk.NewAttribute(types.AttributeEpochNumber, fmt.Sprintf("%d", epochNumber)), + types.EventTypeInflation, + sdk.NewAttribute(types.AttributeEpochNumber, fmt.Sprintf("%d", epochNumber-numSkippedEpochs)), sdk.NewAttribute(types.AttributeKeyEpochProvisions, epochMintProvision.String()), sdk.NewAttribute(sdk.AttributeKeyAmount, mintedCoin.Amount.String()), ), diff --git a/x/inflation/keeper/hooks_test.go b/x/inflation/keeper/hooks_test.go index fc56e7037..c6f5b431f 100644 --- a/x/inflation/keeper/hooks_test.go +++ b/x/inflation/keeper/hooks_test.go @@ -40,167 +40,159 @@ func TestEpochIdentifierAfterEpochEnd(t *testing.T) { // are handled correctly. func TestPeriodChangesSkippedEpochsAfterEpochEnd(t *testing.T) { nibiruApp, ctx := testapp.NewNibiruTestAppAndContext() - epochsPerPeriod := nibiruApp.InflationKeeper.GetEpochsPerPeriod(ctx) + inflationKeeper := nibiruApp.InflationKeeper testCases := []struct { - name string - currentPeriod uint64 - height uint64 - epochIdentifier string - skippedEpochs uint64 - InflationEnabled bool - periodChanges bool + name string + currentPeriod uint64 + currentEpochNumber uint64 + epochIdentifier string + skippedEpochs uint64 + InflationEnabled bool + periodChanges bool }{ { - name: "SkippedEpoch set DayEpochID disabledInflation", - currentPeriod: 0, - height: epochsPerPeriod - 10, // so it's within range - epochIdentifier: epochstypes.DayEpochID, - skippedEpochs: 0, - InflationEnabled: false, - periodChanges: false, + name: "SkippedEpoch set DayEpochID disabledInflation", + currentPeriod: 0, + currentEpochNumber: 20, // so it's within range + epochIdentifier: epochstypes.DayEpochID, + skippedEpochs: 19, + InflationEnabled: false, + periodChanges: false, }, { - name: "SkippedEpoch set WeekEpochID disabledInflation ", - currentPeriod: 0, - height: epochsPerPeriod - 10, // so it's within range - epochIdentifier: epochstypes.WeekEpochID, - skippedEpochs: 0, - InflationEnabled: false, - periodChanges: false, + name: "SkippedEpoch set WeekEpochID disabledInflation ", + currentPeriod: 0, + currentEpochNumber: 20, // so it's within range + epochIdentifier: epochstypes.WeekEpochID, + skippedEpochs: 19, + InflationEnabled: false, + periodChanges: false, }, { - name: "[Period 0] disabledInflation", - currentPeriod: 0, - height: epochsPerPeriod - 10, // so it's within range - epochIdentifier: epochstypes.DayEpochID, - skippedEpochs: 0, - InflationEnabled: false, - periodChanges: false, + name: "[Period 0] disabledInflation", + currentPeriod: 0, + currentEpochNumber: 20, // so it's within range + epochIdentifier: epochstypes.DayEpochID, + skippedEpochs: 19, + InflationEnabled: false, + periodChanges: false, }, { - name: "[Period 0] period stays the same under epochs per period", - currentPeriod: 0, - height: epochsPerPeriod - 10, // so it's within range - epochIdentifier: epochstypes.DayEpochID, - skippedEpochs: 0, - InflationEnabled: true, - periodChanges: false, + name: "[Period 0] period stays the same under epochs per period", + currentPeriod: 0, + currentEpochNumber: 29, // so it's within range + epochIdentifier: epochstypes.DayEpochID, + skippedEpochs: 0, + InflationEnabled: true, + periodChanges: false, }, { - name: "[Period 0] period changes once enough epochs have passed", - currentPeriod: 0, - height: epochsPerPeriod + 1, - epochIdentifier: epochstypes.DayEpochID, - skippedEpochs: 0, - InflationEnabled: true, - periodChanges: true, + name: "[Period 0] period changes once enough epochs have passed", + currentPeriod: 0, + currentEpochNumber: 30, + epochIdentifier: epochstypes.DayEpochID, + skippedEpochs: 0, + InflationEnabled: true, + periodChanges: true, }, { - name: "[Period 1] period stays the same under the epoch per period", - currentPeriod: 1, - height: 2*epochsPerPeriod - 2, // period change is at the end of epoch 59 - epochIdentifier: epochstypes.DayEpochID, - skippedEpochs: 0, - InflationEnabled: true, - periodChanges: false, + name: "[Period 1] period stays the same under the epoch per period", + currentPeriod: 1, + currentEpochNumber: 59, // period change is at the end of epoch 59 + epochIdentifier: epochstypes.DayEpochID, + skippedEpochs: 0, + InflationEnabled: true, + periodChanges: false, }, { - name: "[Period 1] period changes once enough epochs have passed", - currentPeriod: 1, - height: 2*epochsPerPeriod + 1, - epochIdentifier: epochstypes.DayEpochID, - skippedEpochs: 0, - InflationEnabled: true, - periodChanges: true, + name: "[Period 1] period changes once enough epochs have passed", + currentPeriod: 1, + currentEpochNumber: 60, + epochIdentifier: epochstypes.DayEpochID, + skippedEpochs: 0, + InflationEnabled: true, + periodChanges: true, }, { - name: "[Period 0] with skipped epochs - period stays the same under epochs per period", - currentPeriod: 0, - height: epochsPerPeriod - 1, - epochIdentifier: epochstypes.DayEpochID, - skippedEpochs: 10, - InflationEnabled: true, - periodChanges: false, + name: "[Period 0] with skipped epochs - period stays the same under epochs per period", + currentPeriod: 0, + currentEpochNumber: 30, + epochIdentifier: epochstypes.DayEpochID, + skippedEpochs: 1, + InflationEnabled: true, + periodChanges: false, }, { - name: "[Period 0] with skipped epochs - period stays the same under epochs per period", - currentPeriod: 0, - height: epochsPerPeriod + 1, - epochIdentifier: epochstypes.DayEpochID, - skippedEpochs: 10, - InflationEnabled: true, - periodChanges: false, + name: "[Period 0] with skipped epochs - period changes once enough epochs have passed", + currentPeriod: 0, + currentEpochNumber: 40, + epochIdentifier: epochstypes.DayEpochID, + skippedEpochs: 10, + InflationEnabled: true, + periodChanges: true, }, { - name: "[Period 0] with skipped epochs - period changes once enough epochs have passed", - currentPeriod: 0, - height: epochsPerPeriod + 11, - epochIdentifier: epochstypes.DayEpochID, - skippedEpochs: 10, - InflationEnabled: true, - periodChanges: true, + name: "[Period 1] with skipped epochs - period stays the same under epochs per period", + currentPeriod: 1, + currentEpochNumber: 69, + epochIdentifier: epochstypes.DayEpochID, + skippedEpochs: 10, + InflationEnabled: true, + periodChanges: false, }, { - name: "[Period 1] with skipped epochs - period stays the same under epochs per period", - currentPeriod: 1, - height: 2*epochsPerPeriod + 1, - epochIdentifier: epochstypes.DayEpochID, - skippedEpochs: 10, - InflationEnabled: true, - periodChanges: false, - }, - { - name: "[Period 1] with skipped epochs - period changes once enough epochs have passed", - currentPeriod: 1, - height: 2*epochsPerPeriod + 11, - epochIdentifier: epochstypes.DayEpochID, - skippedEpochs: 10, - InflationEnabled: true, - periodChanges: true, + name: "[Period 1] with skipped epochs - period changes once enough epochs have passed", + currentPeriod: 1, + currentEpochNumber: 70, + epochIdentifier: epochstypes.DayEpochID, + skippedEpochs: 10, + InflationEnabled: true, + periodChanges: true, }, } for _, tc := range testCases { t.Run(fmt.Sprintf("Case %s", tc.name), func(t *testing.T) { - params := nibiruApp.InflationKeeper.GetParams(ctx) + params := inflationKeeper.GetParams(ctx) params.InflationEnabled = tc.InflationEnabled - nibiruApp.InflationKeeper.Params.Set(ctx, params) + params.HasInflationStarted = tc.InflationEnabled + inflationKeeper.Params.Set(ctx, params) - nibiruApp.InflationKeeper.NumSkippedEpochs.Set(ctx, tc.skippedEpochs) - nibiruApp.InflationKeeper.CurrentPeriod.Set(ctx, tc.currentPeriod) + inflationKeeper.NumSkippedEpochs.Set(ctx, tc.skippedEpochs) + inflationKeeper.CurrentPeriod.Set(ctx, tc.currentPeriod) - currentSkippedEpochs := nibiruApp.InflationKeeper.NumSkippedEpochs.Peek(ctx) - currentPeriod := nibiruApp.InflationKeeper.CurrentPeriod.Peek(ctx) - originalProvision := nibiruApp.InflationKeeper.GetEpochMintProvision(ctx) + // original values + prevSkippedEpochs := inflationKeeper.NumSkippedEpochs.Peek(ctx) + prevPeriod := inflationKeeper.CurrentPeriod.Peek(ctx) + originalProvision := inflationKeeper.GetEpochMintProvision(ctx) // Perform Epoch Hooks futureCtx := ctx.WithBlockTime(time.Now().Add(time.Minute)) - nibiruApp.EpochsKeeper.BeforeEpochStart(futureCtx, tc.epochIdentifier, tc.height) - nibiruApp.EpochsKeeper.AfterEpochEnd(futureCtx, tc.epochIdentifier, tc.height) + nibiruApp.EpochsKeeper.BeforeEpochStart(futureCtx, tc.epochIdentifier, tc.currentEpochNumber) + nibiruApp.EpochsKeeper.AfterEpochEnd(futureCtx, tc.epochIdentifier, tc.currentEpochNumber) - skippedEpochs := nibiruApp.InflationKeeper.NumSkippedEpochs.Peek(ctx) - period := nibiruApp.InflationKeeper.CurrentPeriod.Peek(ctx) + // new values + newSkippedEpochs := inflationKeeper.NumSkippedEpochs.Peek(ctx) + newPeriod := inflationKeeper.CurrentPeriod.Peek(ctx) if tc.periodChanges { - newProvision := nibiruApp.InflationKeeper.GetEpochMintProvision(ctx) + newProvision := inflationKeeper.GetEpochMintProvision(ctx) expectedProvision := types.CalculateEpochMintProvision( - nibiruApp.InflationKeeper.GetParams(ctx), - period, + inflationKeeper.GetParams(ctx), + newPeriod, ) require.Equal(t, expectedProvision, newProvision) // mint provisions will change require.NotEqual(t, newProvision, originalProvision) - require.Equal(t, currentSkippedEpochs, skippedEpochs) - require.Equal(t, currentPeriod+1, period) + require.Equal(t, prevSkippedEpochs, newSkippedEpochs) + require.Equal(t, prevPeriod+1, newPeriod) } else { - require.Equal(t, currentPeriod, period, "period should not change but it did") - if !tc.InflationEnabled { + require.Equal(t, prevPeriod, newPeriod, "period should not change but it did") + if !tc.InflationEnabled && tc.epochIdentifier == epochstypes.DayEpochID { // Check for epochIdentifier for skippedEpoch increment - if tc.epochIdentifier == epochstypes.DayEpochID { - require.Equal(t, currentSkippedEpochs+1, skippedEpochs) - } + require.EqualValues(t, prevSkippedEpochs+1, newSkippedEpochs) } } }) @@ -222,14 +214,16 @@ func TestManual(t *testing.T) { // We turn it on again and check if the balance is increasing again with the correct amount nibiruApp, ctx := testapp.NewNibiruTestAppAndContext() + inflationKeeper := nibiruApp.InflationKeeper - params := nibiruApp.InflationKeeper.GetParams(ctx) - epochNumber := uint64(0) + params := inflationKeeper.GetParams(ctx) + epochNumber := uint64(1) params.InflationEnabled = false + params.HasInflationStarted = false params.EpochsPerPeriod = 30 - // y = 30 * x + 30 -> 3 nibi per epoch for period 0, 6 nibi per epoch for period 1 + // y = 3 * x + 3 -> 3 nibi per epoch for period 0, 6 nibi per epoch for period 1 params.PolynomialFactors = []sdk.Dec{sdk.NewDec(3), sdk.NewDec(3)} params.InflationDistribution = types.InflationDistribution{ CommunityPool: sdk.ZeroDec(), @@ -237,15 +231,17 @@ func TestManual(t *testing.T) { StrategicReserves: sdk.ZeroDec(), } - nibiruApp.InflationKeeper.Params.Set(ctx, params) + inflationKeeper.Params.Set(ctx, params) require.Equal(t, sdk.ZeroInt(), GetBalanceStaking(ctx, nibiruApp)) for i := 0; i < 42069; i++ { - nibiruApp.InflationKeeper.AfterEpochEnd(ctx, epochstypes.DayEpochID, epochNumber) + inflationKeeper.AfterEpochEnd(ctx, epochstypes.DayEpochID, epochNumber) epochNumber++ } require.Equal(t, sdk.ZeroInt(), GetBalanceStaking(ctx, nibiruApp)) + require.EqualValues(t, uint64(0), inflationKeeper.CurrentPeriod.Peek(ctx)) + require.EqualValues(t, uint64(42069), inflationKeeper.NumSkippedEpochs.Peek(ctx)) nibiruApp.EpochsKeeper.Epochs.Insert(ctx, epochstypes.DayEpochID, epochstypes.EpochInfo{ Identifier: epochstypes.DayEpochID, @@ -257,34 +253,42 @@ func TestManual(t *testing.T) { CurrentEpochStartHeight: 0, }, ) - err := nibiruApp.InflationKeeper.Sudo().ToggleInflation(ctx, true, testapp.DefaultSudoRoot()) + err := inflationKeeper.Sudo().ToggleInflation(ctx, true, testapp.DefaultSudoRoot()) require.NoError(t, err) + // Period 0 - inflate 3M NIBI over 30 epochs or 100k uNIBI per epoch for i := 0; i < 30; i++ { - nibiruApp.InflationKeeper.AfterEpochEnd(ctx, epochstypes.DayEpochID, epochNumber) + inflationKeeper.AfterEpochEnd(ctx, epochstypes.DayEpochID, epochNumber) require.Equal(t, sdk.NewInt(100_000).Mul(sdk.NewInt(int64(i+1))), GetBalanceStaking(ctx, nibiruApp)) epochNumber++ } require.Equal(t, sdk.NewInt(3_000_000), GetBalanceStaking(ctx, nibiruApp)) + require.EqualValues(t, uint64(1), inflationKeeper.CurrentPeriod.Peek(ctx)) + require.EqualValues(t, uint64(42069), inflationKeeper.NumSkippedEpochs.Peek(ctx)) - err = nibiruApp.InflationKeeper.Sudo().ToggleInflation(ctx, false, testapp.DefaultSudoRoot()) + err = inflationKeeper.Sudo().ToggleInflation(ctx, false, testapp.DefaultSudoRoot()) require.NoError(t, err) for i := 0; i < 42069; i++ { - nibiruApp.InflationKeeper.AfterEpochEnd(ctx, epochstypes.DayEpochID, epochNumber) + inflationKeeper.AfterEpochEnd(ctx, epochstypes.DayEpochID, epochNumber) epochNumber++ } require.Equal(t, sdk.NewInt(3_000_000), GetBalanceStaking(ctx, nibiruApp)) + require.EqualValues(t, uint64(1), inflationKeeper.CurrentPeriod.Peek(ctx)) + require.EqualValues(t, uint64(84138), inflationKeeper.NumSkippedEpochs.Peek(ctx)) - err = nibiruApp.InflationKeeper.Sudo().ToggleInflation(ctx, true, testapp.DefaultSudoRoot()) + err = inflationKeeper.Sudo().ToggleInflation(ctx, true, testapp.DefaultSudoRoot()) require.NoError(t, err) - // Period 1 - we do 200_000 per periods now + // Period 1 - inflate 6M NIBI over 30 epochs or 200k uNIBI per epoch for i := 0; i < 30; i++ { - nibiruApp.InflationKeeper.AfterEpochEnd(ctx, epochstypes.DayEpochID, epochNumber) + inflationKeeper.AfterEpochEnd(ctx, epochstypes.DayEpochID, epochNumber) require.Equal(t, sdk.NewInt(3_000_000).Add(sdk.NewInt(200_000).Mul(sdk.NewInt(int64(i+1)))), GetBalanceStaking(ctx, nibiruApp)) epochNumber++ } - require.EqualValues(t, epochNumber, uint64(2*42069+60)) require.Equal(t, sdk.NewInt(9_000_000), GetBalanceStaking(ctx, nibiruApp)) + require.EqualValues(t, uint64(2), inflationKeeper.CurrentPeriod.Peek(ctx)) + require.EqualValues(t, uint64(84138), inflationKeeper.NumSkippedEpochs.Peek(ctx)) + + require.EqualValues(t, uint64(1+2*42069+60), epochNumber) } diff --git a/x/inflation/keeper/keeper.go b/x/inflation/keeper/keeper.go index bffe6a258..29dbe5c14 100644 --- a/x/inflation/keeper/keeper.go +++ b/x/inflation/keeper/keeper.go @@ -23,7 +23,6 @@ type Keeper struct { distrKeeper types.DistrKeeper stakingKeeper types.StakingKeeper sudoKeeper types.SudoKeeper - epochsKeeper types.EpochsKeeper feeCollectorName string CurrentPeriod collections.Sequence @@ -42,7 +41,6 @@ func NewKeeper( stakingKeeper types.StakingKeeper, sudoKeeper types.SudoKeeper, feeCollectorName string, - epochsKeeper types.EpochsKeeper, ) Keeper { // ensure mint module account is set if addr := accountKeeper.GetModuleAddress(types.ModuleName); addr == nil { @@ -58,7 +56,6 @@ func NewKeeper( distrKeeper: distributionKeeper, stakingKeeper: stakingKeeper, sudoKeeper: sudoKeeper, - epochsKeeper: epochsKeeper, feeCollectorName: feeCollectorName, CurrentPeriod: collections.NewSequence(storeKey, 0), NumSkippedEpochs: collections.NewSequence(storeKey, 1), diff --git a/x/inflation/keeper/sudo.go b/x/inflation/keeper/sudo.go index 9f9506ed6..91f882b31 100644 --- a/x/inflation/keeper/sudo.go +++ b/x/inflation/keeper/sudo.go @@ -5,7 +5,6 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" - epochstypes "github.com/NibiruChain/nibiru/x/epochs/types" inflationtypes "github.com/NibiruChain/nibiru/x/inflation/types" ) @@ -58,16 +57,8 @@ func (k sudoExtension) ToggleInflation( } params.InflationEnabled = enabled - if k.NumSkippedEpochs.Peek(ctx) == 0 { - // update skipped epochs since this means that inflation could have - // added to the chain after launch - - epochInfo, err := k.epochsKeeper.GetEpochInfo(ctx, epochstypes.DayEpochID) - if err != nil { - return err - } - - k.NumSkippedEpochs.Set(ctx, epochInfo.CurrentEpoch) + if enabled && !params.HasInflationStarted { + params.HasInflationStarted = true } k.Params.Set(ctx, params) diff --git a/x/inflation/types/events.go b/x/inflation/types/events.go index 5f6374c54..3a6febaa7 100644 --- a/x/inflation/types/events.go +++ b/x/inflation/types/events.go @@ -2,7 +2,7 @@ package types // Minting module event types const ( - EventTypeMint = ModuleName + EventTypeInflation = ModuleName AttributeKeyEpochProvisions = "epoch_provisions" AttributeEpochNumber = "epoch_number" diff --git a/x/inflation/types/genesis.pb.go b/x/inflation/types/genesis.pb.go index 61e7d72ce..522028269 100644 --- a/x/inflation/types/genesis.pb.go +++ b/x/inflation/types/genesis.pb.go @@ -107,6 +107,10 @@ type Params struct { // max_period is the maximum number of periods that have inflation being // paid off. After this period, inflation will be disabled. MaxPeriod uint64 `protobuf:"varint,6,opt,name=max_period,json=maxPeriod,proto3" json:"max_period,omitempty"` + // has_inflation_started is the parameter that indicates if inflation has + // started. It's set to false at the starts, and stays at true when we toggle + // inflation on. It's used to track num skipped epochs + HasInflationStarted bool `protobuf:"varint,7,opt,name=has_inflation_started,json=hasInflationStarted,proto3" json:"has_inflation_started,omitempty"` } func (m *Params) Reset() { *m = Params{} } @@ -177,6 +181,13 @@ func (m *Params) GetMaxPeriod() uint64 { return 0 } +func (m *Params) GetHasInflationStarted() bool { + if m != nil { + return m.HasInflationStarted + } + return false +} + func init() { proto.RegisterType((*GenesisState)(nil), "nibiru.inflation.v1.GenesisState") proto.RegisterType((*Params)(nil), "nibiru.inflation.v1.Params") @@ -185,35 +196,36 @@ func init() { func init() { proto.RegisterFile("nibiru/inflation/v1/genesis.proto", fileDescriptor_2d00e2bb98c08f74) } var fileDescriptor_2d00e2bb98c08f74 = []byte{ - // 438 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x6c, 0x92, 0xcf, 0x6e, 0xd4, 0x30, - 0x10, 0xc6, 0x37, 0xdb, 0x25, 0xa2, 0x2e, 0x94, 0xae, 0x81, 0x2a, 0x2a, 0x22, 0x5d, 0x8a, 0x40, - 0x51, 0x11, 0xb6, 0x5a, 0x4e, 0x5c, 0x97, 0x16, 0xd4, 0x0b, 0x8a, 0xc2, 0x09, 0x24, 0x14, 0x39, - 0x89, 0x9b, 0xb5, 0x9a, 0xc4, 0x96, 0xed, 0xad, 0x76, 0xdf, 0x80, 0x23, 0x8f, 0xd5, 0x63, 0x8f, - 0x88, 0x43, 0x85, 0x76, 0xdf, 0x80, 0x27, 0xa8, 0xd6, 0xf6, 0xfe, 0x39, 0xe4, 0x94, 0xcc, 0xcc, - 0x6f, 0xbe, 0x19, 0x7f, 0x1a, 0xf0, 0xaa, 0x61, 0x19, 0x93, 0x63, 0xcc, 0x9a, 0xcb, 0x8a, 0x68, - 0xc6, 0x1b, 0x7c, 0x7d, 0x82, 0x4b, 0xda, 0x50, 0xc5, 0x14, 0x12, 0x92, 0x6b, 0x0e, 0x9f, 0x5a, - 0x04, 0xad, 0x10, 0x74, 0x7d, 0x72, 0xf0, 0xac, 0xe4, 0x25, 0x37, 0x75, 0xbc, 0xf8, 0xb3, 0xe8, - 0xc1, 0xeb, 0x36, 0xb5, 0x75, 0x9f, 0x81, 0x8e, 0x7e, 0x79, 0xe0, 0xd1, 0x17, 0x3b, 0xe1, 0x9b, - 0x26, 0x9a, 0xc2, 0x8f, 0xc0, 0x17, 0x44, 0x92, 0x5a, 0x05, 0xde, 0xc0, 0x8b, 0x76, 0x4e, 0x5f, - 0xa0, 0x96, 0x89, 0x28, 0x36, 0xc8, 0xb0, 0x77, 0x73, 0x77, 0xd8, 0x49, 0x5c, 0x03, 0xdc, 0x07, - 0xbe, 0xa0, 0x92, 0xf1, 0x22, 0xe8, 0x0e, 0xbc, 0xa8, 0x97, 0xb8, 0x08, 0xbe, 0x01, 0xbb, 0xea, - 0x8a, 0x09, 0x41, 0x8b, 0x94, 0x0a, 0x9e, 0x8f, 0x54, 0xb0, 0x65, 0xea, 0x8f, 0x5d, 0xf6, 0xdc, - 0x24, 0x8f, 0xfe, 0x77, 0x81, 0x6f, 0x75, 0xe1, 0x3b, 0xd0, 0x5f, 0x8d, 0x4b, 0x69, 0x43, 0xb2, - 0x8a, 0x16, 0x66, 0x9f, 0x87, 0xc9, 0xde, 0xaa, 0x70, 0x6e, 0xf3, 0xf0, 0x27, 0x80, 0x82, 0x57, - 0xd3, 0x86, 0xd7, 0x8c, 0x54, 0xe9, 0x25, 0xc9, 0x35, 0x97, 0x2a, 0xe8, 0x0e, 0xb6, 0xa2, 0xed, - 0x21, 0x5a, 0x2c, 0xf8, 0xf7, 0xee, 0xf0, 0x6d, 0xc9, 0xf4, 0x68, 0x9c, 0xa1, 0x9c, 0xd7, 0x38, - 0xe7, 0xaa, 0xe6, 0xca, 0x7d, 0xde, 0xab, 0xe2, 0x0a, 0xeb, 0xa9, 0xa0, 0x0a, 0x9d, 0xd1, 0x3c, - 0xe9, 0xaf, 0x95, 0x3e, 0x5b, 0x21, 0x58, 0x82, 0xfd, 0xf5, 0x2e, 0x05, 0x53, 0x5a, 0xb2, 0x6c, - 0xbc, 0x08, 0xcc, 0x2b, 0x76, 0x4e, 0x8f, 0x5b, 0x0d, 0xba, 0x58, 0x06, 0x67, 0x1b, 0x1d, 0xce, - 0xaf, 0xe7, 0xac, 0xad, 0x08, 0x8f, 0x41, 0xdf, 0xda, 0x93, 0x0a, 0x2a, 0x53, 0xe7, 0x64, 0xcf, - 0x38, 0xf5, 0xc4, 0x16, 0x62, 0x2a, 0x63, 0x6b, 0x69, 0x04, 0xf6, 0x2c, 0x60, 0xe1, 0x29, 0x25, - 0x32, 0x78, 0x60, 0xd0, 0x5d, 0x97, 0x8f, 0xa9, 0xfc, 0x4e, 0x89, 0x84, 0x2f, 0x01, 0xa8, 0xc9, - 0x64, 0x29, 0xe7, 0x1b, 0x66, 0xbb, 0x26, 0x13, 0x2b, 0x34, 0xbc, 0xb8, 0x99, 0x85, 0xde, 0xed, - 0x2c, 0xf4, 0xfe, 0xcd, 0x42, 0xef, 0xf7, 0x3c, 0xec, 0xdc, 0xce, 0xc3, 0xce, 0x9f, 0x79, 0xd8, - 0xf9, 0x81, 0x37, 0x2c, 0xfb, 0x6a, 0x5e, 0xf8, 0x69, 0x44, 0x58, 0x83, 0xdd, 0x55, 0x4d, 0x36, - 0xee, 0xca, 0xf8, 0x97, 0xf9, 0xe6, 0xa2, 0x3e, 0xdc, 0x07, 0x00, 0x00, 0xff, 0xff, 0x1c, 0x56, - 0x6e, 0x63, 0xc6, 0x02, 0x00, 0x00, + // 461 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x6c, 0x52, 0xc1, 0x6e, 0x13, 0x31, + 0x10, 0xcd, 0x36, 0x61, 0xa1, 0x2e, 0x94, 0xc6, 0xa5, 0xd5, 0xaa, 0x88, 0x6d, 0x28, 0x02, 0x45, + 0x45, 0xac, 0xd5, 0x70, 0xe2, 0x1a, 0x5a, 0x50, 0x2f, 0x28, 0x4a, 0x4f, 0x20, 0xa1, 0x95, 0x77, + 0x77, 0xba, 0x6b, 0x35, 0xbb, 0xb6, 0x6c, 0xa7, 0x4a, 0xfe, 0x80, 0x23, 0x5f, 0xc1, 0xb7, 0xf4, + 0xd8, 0x23, 0xe2, 0x50, 0xa1, 0xe4, 0x47, 0xaa, 0xd8, 0x6e, 0x92, 0xc3, 0x9e, 0xec, 0x99, 0xf7, + 0xe6, 0xcd, 0xcc, 0xd3, 0xa0, 0xd7, 0x15, 0x4b, 0x98, 0x1c, 0x13, 0x56, 0x5d, 0x8e, 0xa8, 0x66, + 0xbc, 0x22, 0xd7, 0x27, 0x24, 0x87, 0x0a, 0x14, 0x53, 0x91, 0x90, 0x5c, 0x73, 0xbc, 0x6b, 0x29, + 0xd1, 0x92, 0x12, 0x5d, 0x9f, 0x1c, 0xbc, 0xc8, 0x79, 0xce, 0x0d, 0x4e, 0x16, 0x3f, 0x4b, 0x3d, + 0x78, 0x53, 0xa7, 0xb6, 0xaa, 0x33, 0xa4, 0xa3, 0x5f, 0x1e, 0x7a, 0xfa, 0xd5, 0x76, 0xb8, 0xd0, + 0x54, 0x03, 0xfe, 0x84, 0x7c, 0x41, 0x25, 0x2d, 0x55, 0xe0, 0x75, 0xbc, 0xee, 0x56, 0xef, 0x65, + 0x54, 0xd3, 0x31, 0x1a, 0x18, 0x4a, 0xbf, 0x75, 0x73, 0x77, 0xd8, 0x18, 0xba, 0x02, 0xbc, 0x8f, + 0x7c, 0x01, 0x92, 0xf1, 0x2c, 0xd8, 0xe8, 0x78, 0xdd, 0xd6, 0xd0, 0x45, 0xf8, 0x2d, 0xda, 0x56, + 0x57, 0x4c, 0x08, 0xc8, 0x62, 0x10, 0x3c, 0x2d, 0x54, 0xd0, 0x34, 0xf8, 0x33, 0x97, 0x3d, 0x33, + 0xc9, 0xa3, 0x3f, 0x4d, 0xe4, 0x5b, 0x5d, 0xfc, 0x1e, 0xb5, 0x97, 0xed, 0x62, 0xa8, 0x68, 0x32, + 0x82, 0xcc, 0xcc, 0xf3, 0x64, 0xb8, 0xb3, 0x04, 0xce, 0x6c, 0x1e, 0xff, 0x44, 0x58, 0xf0, 0xd1, + 0xb4, 0xe2, 0x25, 0xa3, 0xa3, 0xf8, 0x92, 0xa6, 0x9a, 0x4b, 0x15, 0x6c, 0x74, 0x9a, 0xdd, 0xcd, + 0x7e, 0xb4, 0x18, 0xf0, 0xdf, 0xdd, 0xe1, 0xbb, 0x9c, 0xe9, 0x62, 0x9c, 0x44, 0x29, 0x2f, 0x49, + 0xca, 0x55, 0xc9, 0x95, 0x7b, 0x3e, 0xa8, 0xec, 0x8a, 0xe8, 0xa9, 0x00, 0x15, 0x9d, 0x42, 0x3a, + 0x6c, 0xaf, 0x94, 0xbe, 0x58, 0x21, 0x9c, 0xa3, 0xfd, 0xd5, 0x2c, 0x19, 0x53, 0x5a, 0xb2, 0x64, + 0xbc, 0x08, 0xcc, 0x16, 0x5b, 0xbd, 0xe3, 0x5a, 0x83, 0xce, 0x1f, 0x82, 0xd3, 0xb5, 0x0a, 0xe7, + 0xd7, 0x1e, 0xab, 0x03, 0xf1, 0x31, 0x6a, 0x5b, 0x7b, 0x62, 0x01, 0x32, 0x76, 0x4e, 0xb6, 0x8c, + 0x53, 0xcf, 0x2d, 0x30, 0x00, 0x39, 0xb0, 0x96, 0x76, 0xd1, 0x8e, 0x25, 0x58, 0xf2, 0x14, 0xa8, + 0x0c, 0x1e, 0x19, 0xea, 0xb6, 0xcb, 0x0f, 0x40, 0x7e, 0x07, 0x2a, 0xf1, 0x2b, 0x84, 0x4a, 0x3a, + 0x79, 0x90, 0xf3, 0x0d, 0x67, 0xb3, 0xa4, 0x13, 0x27, 0xd4, 0x43, 0x7b, 0x05, 0x55, 0xf1, 0x6a, + 0x43, 0xa5, 0xa9, 0xd4, 0x90, 0x05, 0x8f, 0x8d, 0xdb, 0xbb, 0x05, 0x55, 0xcb, 0x55, 0x2e, 0x2c, + 0xd4, 0x3f, 0xbf, 0x99, 0x85, 0xde, 0xed, 0x2c, 0xf4, 0xfe, 0xcf, 0x42, 0xef, 0xf7, 0x3c, 0x6c, + 0xdc, 0xce, 0xc3, 0xc6, 0xdf, 0x79, 0xd8, 0xf8, 0x41, 0xd6, 0x6c, 0xfe, 0x66, 0x5c, 0xf9, 0x5c, + 0x50, 0x56, 0x11, 0x77, 0x89, 0x93, 0xb5, 0x5b, 0x34, 0x9e, 0x27, 0xbe, 0xb9, 0xc2, 0x8f, 0xf7, + 0x01, 0x00, 0x00, 0xff, 0xff, 0xc8, 0x43, 0x3a, 0xc4, 0xfa, 0x02, 0x00, 0x00, } func (m *GenesisState) Marshal() (dAtA []byte, err error) { @@ -279,6 +291,16 @@ func (m *Params) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l + if m.HasInflationStarted { + i-- + if m.HasInflationStarted { + dAtA[i] = 1 + } else { + dAtA[i] = 0 + } + i-- + dAtA[i] = 0x38 + } if m.MaxPeriod != 0 { i = encodeVarintGenesis(dAtA, i, uint64(m.MaxPeriod)) i-- @@ -385,6 +407,9 @@ func (m *Params) Size() (n int) { if m.MaxPeriod != 0 { n += 1 + sovGenesis(uint64(m.MaxPeriod)) } + if m.HasInflationStarted { + n += 2 + } return n } @@ -690,6 +715,26 @@ func (m *Params) Unmarshal(dAtA []byte) error { break } } + case 7: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field HasInflationStarted", wireType) + } + var v int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenesis + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + m.HasInflationStarted = bool(v != 0) default: iNdEx = preIndex skippy, err := skipGenesis(dAtA[iNdEx:]) diff --git a/x/inflation/types/interfaces.go b/x/inflation/types/interfaces.go index ca4bebd1b..2233ac4e0 100644 --- a/x/inflation/types/interfaces.go +++ b/x/inflation/types/interfaces.go @@ -4,8 +4,6 @@ import ( sdkmath "cosmossdk.io/math" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/x/auth/types" - - epochsTypes "github.com/NibiruChain/nibiru/x/epochs/types" ) // AccountKeeper defines the contract required for account APIs. @@ -46,7 +44,3 @@ type SudoKeeper interface { GetRootAddr(ctx sdk.Context) (sdk.AccAddress, error) CheckPermissions(contract sdk.AccAddress, ctx sdk.Context) error } - -type EpochsKeeper interface { - GetEpochInfo(ctx sdk.Context, epochIdentifier string) (epochsTypes.EpochInfo, error) -} diff --git a/x/inflation/types/params.go b/x/inflation/types/params.go index 22be79154..18b044492 100644 --- a/x/inflation/types/params.go +++ b/x/inflation/types/params.go @@ -9,6 +9,7 @@ import ( var ( KeyInflationEnabled = []byte("InflationEnabled") + KeyHasInflationStarted = []byte("HasInflationStarted") KeyPolynomialFactors = []byte("PolynomialFactors") KeyInflationDistribution = []byte("InflationDistribution") KeyEpochsPerPeriod = []byte("EpochsPerPeriod") @@ -40,6 +41,7 @@ func NewParams( polynomialCalculation []sdk.Dec, inflationDistribution InflationDistribution, inflationEnabled bool, + hasInflationStarted bool, epochsPerPeriod, periodsPerYear, maxPeriod uint64, @@ -48,6 +50,7 @@ func NewParams( PolynomialFactors: polynomialCalculation, InflationDistribution: inflationDistribution, InflationEnabled: inflationEnabled, + HasInflationStarted: hasInflationStarted, EpochsPerPeriod: epochsPerPeriod, PeriodsPerYear: periodsPerYear, MaxPeriod: maxPeriod, @@ -60,6 +63,7 @@ func DefaultParams() Params { PolynomialFactors: DefaultPolynomialFactors, InflationDistribution: DefaultInflationDistribution, InflationEnabled: DefaultInflation, + HasInflationStarted: DefaultInflation, EpochsPerPeriod: DefaultEpochsPerPeriod, PeriodsPerYear: DefaultPeriodsPerYear, MaxPeriod: DefaultMaxPeriod, @@ -163,6 +167,9 @@ func (p Params) Validate() error { if err := validateUint64(p.MaxPeriod); err != nil { return err } + if err := validateBool(p.HasInflationStarted); err != nil { + return err + } return validateBool(p.InflationEnabled) } diff --git a/x/inflation/types/params_test.go b/x/inflation/types/params_test.go index e51ecf1bd..4f668b087 100644 --- a/x/inflation/types/params_test.go +++ b/x/inflation/types/params_test.go @@ -26,6 +26,7 @@ func TestParamsValidate(t *testing.T) { inflationtypes.DefaultPolynomialFactors, inflationtypes.DefaultInflationDistribution, true, + true, inflationtypes.DefaultEpochsPerPeriod, inflationtypes.DefaultPeriodsPerYear, inflationtypes.DefaultMaxPeriod, @@ -38,6 +39,7 @@ func TestParamsValidate(t *testing.T) { PolynomialFactors: inflationtypes.DefaultPolynomialFactors, InflationDistribution: inflationtypes.DefaultInflationDistribution, InflationEnabled: true, + HasInflationStarted: true, EpochsPerPeriod: inflationtypes.DefaultEpochsPerPeriod, PeriodsPerYear: inflationtypes.DefaultPeriodsPerYear, }, @@ -49,6 +51,7 @@ func TestParamsValidate(t *testing.T) { PolynomialFactors: []sdk.Dec{}, InflationDistribution: inflationtypes.DefaultInflationDistribution, InflationEnabled: true, + HasInflationStarted: true, EpochsPerPeriod: inflationtypes.DefaultEpochsPerPeriod, PeriodsPerYear: inflationtypes.DefaultPeriodsPerYear, }, @@ -63,9 +66,10 @@ func TestParamsValidate(t *testing.T) { CommunityPool: sdk.NewDecWithPrec(133333, 6), StrategicReserves: sdk.NewDecWithPrec(333333, 6), }, - InflationEnabled: true, - EpochsPerPeriod: inflationtypes.DefaultEpochsPerPeriod, - PeriodsPerYear: inflationtypes.DefaultPeriodsPerYear, + InflationEnabled: true, + HasInflationStarted: true, + EpochsPerPeriod: inflationtypes.DefaultEpochsPerPeriod, + PeriodsPerYear: inflationtypes.DefaultPeriodsPerYear, }, true, }, @@ -78,9 +82,10 @@ func TestParamsValidate(t *testing.T) { CommunityPool: sdk.NewDecWithPrec(133333, 6), StrategicReserves: sdk.OneDec().Neg(), }, - InflationEnabled: true, - EpochsPerPeriod: inflationtypes.DefaultEpochsPerPeriod, - PeriodsPerYear: inflationtypes.DefaultPeriodsPerYear, + InflationEnabled: true, + HasInflationStarted: true, + EpochsPerPeriod: inflationtypes.DefaultEpochsPerPeriod, + PeriodsPerYear: inflationtypes.DefaultPeriodsPerYear, }, true, }, @@ -93,9 +98,10 @@ func TestParamsValidate(t *testing.T) { CommunityPool: sdk.OneDec().Neg(), StrategicReserves: sdk.NewDecWithPrec(333333, 6), }, - InflationEnabled: true, - EpochsPerPeriod: inflationtypes.DefaultEpochsPerPeriod, - PeriodsPerYear: inflationtypes.DefaultPeriodsPerYear, + InflationEnabled: true, + HasInflationStarted: true, + EpochsPerPeriod: inflationtypes.DefaultEpochsPerPeriod, + PeriodsPerYear: inflationtypes.DefaultPeriodsPerYear, }, true, }, @@ -108,9 +114,10 @@ func TestParamsValidate(t *testing.T) { CommunityPool: sdk.NewDecWithPrec(133333, 6), StrategicReserves: sdk.NewDecWithPrec(333333, 6), }, - InflationEnabled: true, - EpochsPerPeriod: inflationtypes.DefaultEpochsPerPeriod, - PeriodsPerYear: inflationtypes.DefaultPeriodsPerYear, + InflationEnabled: true, + HasInflationStarted: true, + EpochsPerPeriod: inflationtypes.DefaultEpochsPerPeriod, + PeriodsPerYear: inflationtypes.DefaultPeriodsPerYear, }, true, },