From 3324bc99904ec8231baf46e4b434ad412499a303 Mon Sep 17 00:00:00 2001 From: Matthias <97468149+matthiasmatt@users.noreply.github.com> Date: Sat, 24 Feb 2024 20:02:40 +0100 Subject: [PATCH] feat: update default inflation rate (#1804) * feat: update default inflation rate * chore: changelog * fix: fix rounding issue --- CHANGELOG.md | 1 + x/inflation/keeper/inflation_test.go | 28 ++++---- x/inflation/simulation/genesis.go | 47 ++++++++++++++ .../types/inflation_calculation_test.go | 64 +++++++++++++------ x/inflation/types/params.go | 18 +++--- 5 files changed, 115 insertions(+), 43 deletions(-) create mode 100644 x/inflation/simulation/genesis.go diff --git a/CHANGELOG.md b/CHANGELOG.md index 2860c607c..54ed9a83c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -59,6 +59,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 * [#1786](https://github.com/NibiruChain/nibiru/pull/1786) - fix(inflation): fix inflation off-by 2 error * [#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 +* [#1804](https://github.com/NibiruChain/nibiru/pull/1804) - fix(inflation): update default parameters ### Improvements diff --git a/x/inflation/keeper/inflation_test.go b/x/inflation/keeper/inflation_test.go index 497f24244..f652ac352 100644 --- a/x/inflation/keeper/inflation_test.go +++ b/x/inflation/keeper/inflation_test.go @@ -37,12 +37,12 @@ func TestMintAndAllocateInflation(t *testing.T) { { name: "pass", coinsToMint: sdk.NewCoin(denoms.NIBI, sdk.NewInt(1_000_000)), - expectedStakingAmt: sdk.NewCoin(denoms.NIBI, sdk.NewInt(277_572)), - expectedStrategicAmt: sdk.NewCoin(denoms.NIBI, sdk.NewInt(370_837)), - expectedCommunityAmt: sdk.NewCoin(denoms.NIBI, sdk.NewInt(351_591)), - expectedStakingRewardsBalance: sdk.NewCoin(denoms.NIBI, sdk.NewInt(277_572)), - expectedStrategicReservesBalance: sdk.NewCoin(denoms.NIBI, sdk.NewInt(370_837)), - expectedCommunityPoolBalance: sdk.NewDecCoins(sdk.NewDecCoin(denoms.NIBI, sdk.NewInt(351_591))), + expectedStakingAmt: sdk.NewCoin(denoms.NIBI, sdk.NewInt(281_250)), + expectedStrategicAmt: sdk.NewCoin(denoms.NIBI, sdk.NewInt(363_925)), + expectedCommunityAmt: sdk.NewCoin(denoms.NIBI, sdk.NewInt(354_825)), + expectedStakingRewardsBalance: sdk.NewCoin(denoms.NIBI, sdk.NewInt(281_250)), + expectedStrategicReservesBalance: sdk.NewCoin(denoms.NIBI, sdk.NewInt(363_925)), + expectedCommunityPoolBalance: sdk.NewDecCoins(sdk.NewDecCoin(denoms.NIBI, sdk.NewInt(354_825))), rootAccount: "nibi1qyqf35fkhn73hjr70442fctpq8prpqr9ysj9sn", }, { @@ -59,12 +59,12 @@ func TestMintAndAllocateInflation(t *testing.T) { { name: "pass - no root account", coinsToMint: sdk.NewCoin(denoms.NIBI, sdk.NewInt(1_000_000)), - expectedStakingAmt: sdk.NewCoin(denoms.NIBI, sdk.NewInt(277_572)), - expectedStrategicAmt: sdk.NewCoin(denoms.NIBI, sdk.NewInt(370_837)), - expectedCommunityAmt: sdk.NewCoin(denoms.NIBI, sdk.NewInt(351_591)), - expectedStakingRewardsBalance: sdk.NewCoin(denoms.NIBI, sdk.NewInt(277_572)), - expectedStrategicReservesBalance: sdk.NewCoin(denoms.NIBI, sdk.NewInt(370_837)), - expectedCommunityPoolBalance: sdk.NewDecCoins(sdk.NewDecCoin(denoms.NIBI, sdk.NewInt(351_591))), + expectedStakingAmt: sdk.NewCoin(denoms.NIBI, sdk.NewInt(281_250)), + expectedStrategicAmt: sdk.NewCoin(denoms.NIBI, sdk.NewInt(363_925)), + expectedCommunityAmt: sdk.NewCoin(denoms.NIBI, sdk.NewInt(354_825)), + expectedStakingRewardsBalance: sdk.NewCoin(denoms.NIBI, sdk.NewInt(281_250)), + expectedStrategicReservesBalance: sdk.NewCoin(denoms.NIBI, sdk.NewInt(363_925)), + expectedCommunityPoolBalance: sdk.NewDecCoins(sdk.NewDecCoin(denoms.NIBI, sdk.NewInt(354_825))), rootAccount: "", }, } @@ -154,7 +154,7 @@ func TestGetCirculatingSupplyAndInflationRate(t *testing.T) { params.InflationEnabled = true nibiruApp.InflationKeeper.Params.Set(ctx, params) }, - sdk.MustNewDecFromStr("27.095518287362700000"), + sdk.MustNewDecFromStr("26.741197359810099000"), }, { "low supply", @@ -164,7 +164,7 @@ func TestGetCirculatingSupplyAndInflationRate(t *testing.T) { params.InflationEnabled = true nibiruApp.InflationKeeper.Params.Set(ctx, params) }, - sdk.MustNewDecFromStr("54.191036574725400000"), + sdk.MustNewDecFromStr("53.482394719620198000"), }, } for _, tc := range testCases { diff --git a/x/inflation/simulation/genesis.go b/x/inflation/simulation/genesis.go new file mode 100644 index 000000000..25add08db --- /dev/null +++ b/x/inflation/simulation/genesis.go @@ -0,0 +1,47 @@ +package simulation + +// DONTCOVER + +import ( + "encoding/json" + "fmt" + + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/types/module" + + "github.com/NibiruChain/nibiru/x/inflation/types" +) + +// RandomizedGenState generates a random GenesisState for distribution +func RandomizedGenState(simState *module.SimulationState) { + inflationGenesis := types.GenesisState{ + Params: types.Params{ + InflationEnabled: true, + PolynomialFactors: []sdk.Dec{ + sdk.MustNewDecFromStr("-0.00014851"), + sdk.MustNewDecFromStr("0.07501029"), + sdk.MustNewDecFromStr("-19.04983993"), + sdk.MustNewDecFromStr("3158.89198346"), + sdk.MustNewDecFromStr("-338072.17402939"), + sdk.MustNewDecFromStr("17999834.20786474"), + }, + InflationDistribution: types.InflationDistribution{ + CommunityPool: sdk.NewDecWithPrec(35_142714, 8), // 35.142714% + StakingRewards: sdk.NewDecWithPrec(27_855672, 8), // 27.855672% + StrategicReserves: sdk.NewDecWithPrec(37_001614, 8), // 37.001614% + }, + EpochsPerPeriod: 30, + PeriodsPerYear: 12, + MaxPeriod: 8 * 12, + }, + Period: 0, + SkippedEpochs: 0, + } + + bz, err := json.MarshalIndent(&inflationGenesis, "", " ") + if err != nil { + panic(err) + } + fmt.Printf("Selected randomly generated x/inflation parameters:\n%s\n", bz) + simState.GenState[types.ModuleName] = simState.Cdc.MustMarshalJSON(&inflationGenesis) +} diff --git a/x/inflation/types/inflation_calculation_test.go b/x/inflation/types/inflation_calculation_test.go index dcda9310c..72a87580d 100644 --- a/x/inflation/types/inflation_calculation_test.go +++ b/x/inflation/types/inflation_calculation_test.go @@ -10,30 +10,30 @@ import ( // These numbers are for year n month 1 var ExpectedYearlyInflation = []sdk.Dec{ - sdk.NewDec(195_895_391_000_000), - sdk.NewDec(156_348_637_000_000), - sdk.NewDec(124_785_459_000_000), - sdk.NewDec(99_594_157_000_000), - sdk.NewDec(79_488_398_000_000), - sdk.NewDec(63_441_527_000_000), - sdk.NewDec(50_634_148_000_000), - sdk.NewDec(40_412_283_000_000), + sdk.NewDec(193_333_719e6), + sdk.NewDec(154_304_107e6), + sdk.NewDec(123_153_673e6), + sdk.NewDec(98_291_791e6), + sdk.NewDec(78_448_949e6), + sdk.NewDec(62_611_919e6), + sdk.NewDec(49_972_019e6), + sdk.NewDec(39_883_823e6), } // ExpectedTotalInflation is the total amount of NIBI tokens (in unibi) that // should be minted via inflation for the network to reach its target supply. -// The value 810.6 million is equivalent to: +// The value 800M is equivalent to: // = (Community allocation of total supply) - (Community supply at start) // = (60% of the total supply) - (Community supply at start) // = (60% of 1.5 billion) - (Community supply at start) -// = 810.6 million NIBI -var ExpectedTotalInflation = sdk.NewDec(810_600_000_000_000) +// = 800 million NIBI +var ExpectedTotalInflation = sdk.NewDec(800_000_000e6) func TestCalculateEpochMintProvision(t *testing.T) { params := DefaultParams() params.InflationEnabled = true - epochId := uint64(0) + period := uint64(0) totalInflation := sdk.ZeroDec() // Only the first 8 years have inflation with default params but we run @@ -42,20 +42,45 @@ func TestCalculateEpochMintProvision(t *testing.T) { yearlyInflation := sdk.ZeroDec() for month := uint64(0); month < 12; month++ { for day := uint64(0); day < 30; day++ { - epochMintProvisions := CalculateEpochMintProvision(params, epochId) + epochMintProvisions := CalculateEpochMintProvision(params, period) yearlyInflation = yearlyInflation.Add(epochMintProvisions) } - epochId++ + period++ } // Should be within 0.0098% if year < uint64(len(ExpectedYearlyInflation)) { - require.NoError(t, withingRange(yearlyInflation, ExpectedYearlyInflation[year])) + require.NoError(t, withinRange(ExpectedYearlyInflation[year], yearlyInflation)) } else { require.Equal(t, yearlyInflation, sdk.ZeroDec()) } totalInflation = totalInflation.Add(yearlyInflation) } - require.NoError(t, withingRange(totalInflation, ExpectedTotalInflation)) + require.NoError(t, withinRange(ExpectedTotalInflation, totalInflation)) +} + +func TestCalculateEpochMintProvisionInflationNotEnabled(t *testing.T) { + params := DefaultParams() + params.InflationEnabled = false + + epochId := uint64(0) + totalInflation := sdk.ZeroDec() + + // Only the first 8 years have inflation with default params but we run + // for 10 years expecting 0 inflation + for year := uint64(0); year < 10; year++ { + yearlyInflation := sdk.ZeroDec() + for month := uint64(0); month < 12; month++ { + for day := uint64(0); day < 30; day++ { + epochMintProvisions := CalculateEpochMintProvision(params, epochId) + yearlyInflation = yearlyInflation.Add(epochMintProvisions) + } + epochId++ + } + + require.Equal(t, yearlyInflation, sdk.ZeroDec()) + totalInflation = totalInflation.Add(yearlyInflation) + } + require.Equal(t, totalInflation, sdk.ZeroDec()) } func TestCalculateEpochMintProvision_ZeroEpochs(t *testing.T) { @@ -66,12 +91,11 @@ func TestCalculateEpochMintProvision_ZeroEpochs(t *testing.T) { require.Equal(t, epochMintProvisions, sdk.ZeroDec()) } -// withingRange returns an error if the actual value is not within the expected value +/- tolerance +// withinRange returns an error if the actual value is not within the expected value +/- tolerance // tolerance is a percentage set to 0.01% by default -func withingRange(expected, actual sdk.Dec) error { +func withinRange(expected, actual sdk.Dec) error { tolerance := sdk.NewDecWithPrec(1, 4) - is_within := expected.Sub(actual).Abs().Quo(expected).LTE(tolerance) - if !is_within { + if expected.Sub(actual).Abs().Quo(expected).GT(tolerance) { tolerancePercent := tolerance.Mul(sdk.NewDec(100)) return fmt.Errorf("expected %s to be within %s%% of %s", actual.String(), tolerancePercent.String(), expected.String()) } diff --git a/x/inflation/types/params.go b/x/inflation/types/params.go index 1302c2411..0c60f3ab0 100644 --- a/x/inflation/types/params.go +++ b/x/inflation/types/params.go @@ -20,17 +20,17 @@ var ( var ( DefaultInflation = false DefaultPolynomialFactors = []sdk.Dec{ - sdk.MustNewDecFromStr("-0.00014903"), - sdk.MustNewDecFromStr("0.07527647"), - sdk.MustNewDecFromStr("-19.11742154"), - sdk.MustNewDecFromStr("3170.0969905"), - sdk.MustNewDecFromStr("-339271.31060432"), - sdk.MustNewDecFromStr("18063678.8582418"), + sdk.MustNewDecFromStr("-0.000147085524"), + sdk.MustNewDecFromStr("0.074291982762"), + sdk.MustNewDecFromStr("-18.867415611180"), + sdk.MustNewDecFromStr("3128.641926954698"), + sdk.MustNewDecFromStr("-334834.740631598223"), + sdk.MustNewDecFromStr("17827464.906540066004"), } DefaultInflationDistribution = InflationDistribution{ - CommunityPool: sdk.NewDecWithPrec(35_159141, 8), // 35.159141% - StakingRewards: sdk.NewDecWithPrec(27_757217, 8), // 27.757217% - StrategicReserves: sdk.NewDecWithPrec(37_083642, 8), // 37.083642% + CommunityPool: sdk.NewDecWithPrec(35_4825, 6), // 35.4825% + StakingRewards: sdk.NewDecWithPrec(28_1250, 6), // 28.1250% + StrategicReserves: sdk.NewDecWithPrec(36_3925, 6), // 36.3925% } DefaultEpochsPerPeriod = uint64(30) DefaultPeriodsPerYear = uint64(12)