mirror of
https://github.com/0glabs/0g-chain.git
synced 2024-11-14 12:05:18 +00:00
55 lines
1.7 KiB
Go
55 lines
1.7 KiB
Go
|
package keeper
|
||
|
|
||
|
import (
|
||
|
sdk "github.com/cosmos/cosmos-sdk/types"
|
||
|
)
|
||
|
|
||
|
// this is the same value used in the x/hard
|
||
|
const (
|
||
|
SecondsPerYear = uint64(31536000)
|
||
|
)
|
||
|
|
||
|
// AccumulateInflation calculates the number of coins that should be minted to match a yearly `rate`
|
||
|
// for interest compounded each second of the year over `secondsSinceLastMint` seconds.
|
||
|
// `basis` is the base amount of coins that is inflated.
|
||
|
func (k Keeper) AccumulateInflation(
|
||
|
ctx sdk.Context,
|
||
|
rate sdk.Dec,
|
||
|
basis sdk.Int,
|
||
|
secondsSinceLastMint float64,
|
||
|
) (sdk.Coins, error) {
|
||
|
bondDenom := k.BondDenom(ctx)
|
||
|
|
||
|
// calculate the rate factor based on apy & seconds passed since last block
|
||
|
inflationRate, err := CalculateInflationRate(rate, uint64(secondsSinceLastMint))
|
||
|
if err != nil {
|
||
|
return sdk.NewCoins(), err
|
||
|
}
|
||
|
|
||
|
amount := inflationRate.MulInt(basis).TruncateInt()
|
||
|
|
||
|
return sdk.NewCoins(sdk.NewCoin(bondDenom, amount)), nil
|
||
|
}
|
||
|
|
||
|
// CalculateInflationRate converts an APY into the factor corresponding with that APY's accumulation
|
||
|
// over a period of secondsPassed seconds.
|
||
|
func CalculateInflationRate(apy sdk.Dec, secondsPassed uint64) (sdk.Dec, error) {
|
||
|
perSecondInterestRate, err := apyToSpy(apy.Add(sdk.OneDec()))
|
||
|
if err != nil {
|
||
|
return sdk.ZeroDec(), err
|
||
|
}
|
||
|
rate := perSecondInterestRate.Power(secondsPassed)
|
||
|
return rate.Sub(sdk.OneDec()), nil
|
||
|
}
|
||
|
|
||
|
// apyToSpy converts the input annual interest rate. For example, 10% apy would be passed as 1.10.
|
||
|
// SPY = Per second compounded interest rate is how cosmos mathematically represents APY.
|
||
|
func apyToSpy(apy sdk.Dec) (sdk.Dec, error) {
|
||
|
// Note: any APY greater than 176.5 will cause an out-of-bounds error
|
||
|
root, err := apy.ApproxRoot(SecondsPerYear)
|
||
|
if err != nil {
|
||
|
return sdk.ZeroDec(), err
|
||
|
}
|
||
|
return root, nil
|
||
|
}
|