diff --git a/app/app.go b/app/app.go index 4a4293ac..1007b6c1 100644 --- a/app/app.go +++ b/app/app.go @@ -588,7 +588,7 @@ func NewApp( committee.NewAppModule(app.committeeKeeper, app.accountKeeper), evmutil.NewAppModule(app.evmutilKeeper, app.bankKeeper, app.accountKeeper), // nil InflationCalculationFn, use SDK's default inflation function - mint.NewAppModule(appCodec, app.mintKeeper, app.accountKeeper, chaincfg.CustomInflationCalculateFn), + mint.NewAppModule(appCodec, app.mintKeeper, app.accountKeeper, chaincfg.InflationCalculateFn), council.NewAppModule(app.CouncilKeeper, app.stakingKeeper), das.NewAppModule(app.DasKeeper), ) diff --git a/chaincfg/mint.go b/chaincfg/mint.go index 1ecfe409..41962cb5 100644 --- a/chaincfg/mint.go +++ b/chaincfg/mint.go @@ -1,45 +1,78 @@ package chaincfg import ( + "github.com/shopspring/decimal" "github.com/tendermint/tendermint/libs/log" sdk "github.com/cosmos/cosmos-sdk/types" minttypes "github.com/cosmos/cosmos-sdk/x/mint/types" ) -func CustomInflationCalculateFn(ctx sdk.Context, minter minttypes.Minter, params minttypes.Params, bondedRatio sdk.Dec) sdk.Dec { +var ( + maxBondedRatio, _ = sdk.NewDecFromStr("1.0") + yMin, _ = sdk.NewDecFromStr("0.05") + + minBondedRatio, _ = sdk.NewDecFromStr("0.2") + yMax, _ = sdk.NewDecFromStr("0.15") // 15% at min bonded ratio + + decayRate, _ = sdk.NewDecFromStr("10") +) + +func InflationCalculateFn(ctx sdk.Context, minter minttypes.Minter, params minttypes.Params, bondedRatio sdk.Dec) sdk.Dec { logger := ctx.Logger() if logger == nil { panic("logger is nil") } - return customInflationCalculateFn(logger, minter, params, bondedRatio) + return inflationCalculateFn(logger, minter, params, bondedRatio) } -func customInflationCalculateFn(logger log.Logger, minter minttypes.Minter, params minttypes.Params, bondedRatio sdk.Dec) sdk.Dec { - // The target annual inflation rate is recalculated for each previsions cycle. The - // inflation is also subject to a rate change (positive or negative) depending on - // the distance from the desired ratio (67%). The maximum rate change possible is - // defined to be 13% per year, however the annual inflation is capped as between - // 7% and 20%. +func decExp(x sdk.Dec) sdk.Dec { + xDec := decimal.NewFromBigInt(x.BigInt(), -18) + expDec, _ := xDec.ExpTaylor(18) + expInt := expDec.Shift(18).BigInt() + return sdk.NewDecFromBigIntWithPrec(expInt, 18) +} - // (1 - bondedRatio/GoalBonded) * InflationRateChange - inflationRateChangePerYear := sdk.OneDec(). - Sub(bondedRatio.Quo(params.GoalBonded)). - Mul(params.InflationRateChange) - inflationRateChange := inflationRateChangePerYear.Quo(sdk.NewDec(int64(params.BlocksPerYear))) +func inflationCalculateFn(logger log.Logger, minter minttypes.Minter, params minttypes.Params, bondedRatio sdk.Dec) sdk.Dec { + var apy sdk.Dec + if bondedRatio.LT(minBondedRatio) { + apy = yMax + } else { + exp := decayRate.Neg().Mul(maxBondedRatio.Sub(minBondedRatio)) + c := decExp(exp) + d := yMin.Sub(yMax.Mul(c)).Quo(sdk.OneDec().Sub(c)) + expBonded := decayRate.Neg().Mul(bondedRatio.Sub(minBondedRatio)) + cBonded := decExp(expBonded) + e := yMax.Sub(d).Mul(cBonded) + apy = d.Add(e) + } + inflation := apy.Mul(bondedRatio) - // adjust the new annual inflation for this next cycle - inflation := minter.Inflation.Add(inflationRateChange) // note inflationRateChange may be negative - if inflation.GT(params.InflationMax) { - inflation = params.InflationMax - } - if inflation.LT(params.InflationMin) { - inflation = params.InflationMin - } + // // The target annual inflation rate is recalculated for each previsions cycle. The + // // inflation is also subject to a rate change (positive or negative) depending on + // // the distance from the desired ratio (67%). The maximum rate change possible is + // // defined to be 13% per year, however the annual inflation is capped as between + // // 7% and 20%. + + // // (1 - bondedRatio/GoalBonded) * InflationRateChange + // inflationRateChangePerYear := sdk.OneDec(). + // Sub(bondedRatio.Quo(params.GoalBonded)). + // Mul(params.InflationRateChange) + // inflationRateChange := inflationRateChangePerYear.Quo(sdk.NewDec(int64(params.BlocksPerYear))) + + // // adjust the new annual inflation for this next cycle + // inflation := minter.Inflation.Add(inflationRateChange) // note inflationRateChange may be negative + // if inflation.GT(params.InflationMax) { + // inflation = params.InflationMax + // } + // if inflation.LT(params.InflationMin) { + // inflation = params.InflationMin + // } logger.Info( "calculated new annual inflation", "bondedRatio", bondedRatio, + "apy", apy, "inflation", inflation, "params", params, "minter", minter, diff --git a/go.mod b/go.mod index 7dea770a..1f5921e0 100644 --- a/go.mod +++ b/go.mod @@ -165,6 +165,7 @@ require ( github.com/rs/zerolog v1.32.0 // indirect github.com/sasha-s/go-deadlock v0.3.1 // indirect github.com/shirou/gopsutil v3.21.4-0.20210419000835-c7a38de76ee5+incompatible // indirect + github.com/shopspring/decimal v1.4.0 // indirect github.com/spf13/afero v1.9.3 // indirect github.com/spf13/jwalterweatherman v1.1.0 // indirect github.com/spf13/pflag v1.0.5 // indirect diff --git a/go.sum b/go.sum index c6da9e20..2800ed09 100644 --- a/go.sum +++ b/go.sum @@ -1083,6 +1083,8 @@ github.com/segmentio/kafka-go v0.2.0/go.mod h1:X6itGqS9L4jDletMsxZ7Dz+JFWxM6JHfP github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo= github.com/shirou/gopsutil v3.21.4-0.20210419000835-c7a38de76ee5+incompatible h1:Bn1aCHHRnjv4Bl16T8rcaFjYSrGrIZvpiGO6P3Q4GpU= github.com/shirou/gopsutil v3.21.4-0.20210419000835-c7a38de76ee5+incompatible/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA= +github.com/shopspring/decimal v1.4.0 h1:bxl37RwXBklmTi0C79JfXCEBD1cqqHt0bbgBAGFp81k= +github.com/shopspring/decimal v1.4.0/go.mod h1:gawqmDU56v4yIKSwfBSFip1HdCCXN8/+DMd9qYNcwME= github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=