0g-chain/x/hard/keeper/interest.go

318 lines
12 KiB
Go
Raw Permalink Normal View History

package keeper
import (
"math"
errorsmod "cosmossdk.io/errors"
feat: upgrade to Cosmos v0.46 (#1477) * Update cosmos-sdk to v0.45.10-kava * Add RegisterNodeService to app * Update cosmos proto files * Update cosmos proto files * Use tagged v0.45.10-kava-v0.19-0.21 cosmos version * update x/auth/legacy to x/auth/migrations * Delete rest packages and registration * Remove rest from proposal handlers * Remove legacy types referencing removed sdk types * Remove legacy tx broadcast handler * Update incentive staking hooks to return error * Remove grpc replace directive, use new grpc version * Fix storetypes import * Update tally_handler with updated gov types * Delete legacy types * Use new gov default config * Update RegisterTendermintService params Signed-off-by: drklee3 <derrick@dlee.dev> * Replace sdk.StoreKey with storetypes.StoreKey * Replace sdk.Int#ToDec with sdk.NewDecFromInt * Replace sdk.NewUintFromBigInt with sdkmath.NewUintFromBigInt Signed-off-by: drklee3 <derrick@dlee.dev> * Update most intances of govtypes to govv1beta1 * Unpack coin slice for Coins#Sub and Coins#SafeSub Signed-off-by: drklee3 <derrick@dlee.dev> * Update committee gov codec registration Signed-off-by: drklee3 <derrick@dlee.dev> * Update migrate utils period_vesting Coins#Sub Signed-off-by: drklee3 <derrick@dlee.dev> * Update Coin#Sub in community proposal handler Signed-off-by: drklee3 <derrick@dlee.dev> * Update Coin#Sub, FundModuleAccount/FundAccount in banktestutil Signed-off-by: drklee3 <derrick@dlee.dev> * Update community, earn, kavadist proposal gov registration * Update evm cli client EthSecp256k1Type check * AccAddressFromHex to AccAddressFromHexUnsafe * Add mint DefaultInflationCalculationFn to earn test * Update use of removed staking.NewHandler * Rename FlagIAVLFastNode -> FlagDisableIAVLFastNode * cmd: Update new snapshot app option Signed-off-by: drklee3 <derrick@dlee.dev> * cmd: Add tendermint default config, use cosmos rpc status command Signed-off-by: drklee3 <derrick@dlee.dev> * Update ethermint import path github.com/tharsis/ethermint -> github.com/evmos/ethermint * Upgrade ibc-go to v6 * Update proto dependencies Signed-off-by: drklee3 <derrick@dlee.dev> * Update Tally handler test with new gov types * Update helpers.GenTx -> helpers.GenSignedMockTx * Update evmkeeper.NewKeeper params Signed-off-by: drklee3 <derrick@dlee.dev> * Update ante authz, tests * Add feemarket transient key, pass subspaces to evm/feemarket keepers * Update new ante decorators * Add new addModuleInitFlags to server commands * Pass codec to keyring.New in genaccounts * Pass codec to client keys add * Add SendCoins to evmutil bank_keeper * Use github.com/cosmos/iavl@v0.19.5 * Add ante HandlerOptions * Add unimplemented SendCoins to evmutil bank keeper Ethermint x/evm does not use this method * Update init-new-chain script to disable post-london blocks * Modify test genesis states to append 1 validator * Update tally handler test to use string values * Prevent querying balance for empty sdk.AccAddress in auction bidding test * Set default bond denom to ukava * Remove overwritten bank genesis total supply in committee proposal test Signed-off-by: drklee3 <derrick@dlee.dev> * Use ukava for testing staked balance * Disable minting in community proposal handler test Previously stake denom is used, which resulted in 0 minted coins * Update hard APYToSPY test expected value Increased iterations in sdk.ApproxRoot, updated closer to real value * Fix NewDecCoinsFromCoins bug in incentive collectDerivativeStakingRewards * Allow bkava earn incentive test values to match within small margin for rounding Signed-off-by: drklee3 <derrick@dlee.dev> * Update invalid denom in issuance message coin validation Colons are now valid in denoms Signed-off-by: drklee3 <derrick@dlee.dev> * Remove genesis validator in incentive delegation tests * Update pricefeed market test for invalid denom Signed-off-by: drklee3 <derrick@dlee.dev> * Update incentive delegator rewards test without genesis validator Signed-off-by: drklee3 <derrick@dlee.dev> * Add validator to export test * Clear bank state in minting tests Signed-off-by: drklee3 <derrick@dlee.dev> * Remove validator for no stake tally test Signed-off-by: drklee3 <derrick@dlee.dev> * Clear incentive state before InitGenesis in incentive genesis export test * Update swagger Signed-off-by: drklee3 <derrick@dlee.dev> * Update ethermint version to match replaced version * Remove legacy swagger * Add NewEthEmitEventDecorator * Remove redundant func for AddModuleInitFlags * Remove unused addBankBalanceForAddress func * Add SetIAVLLazyLoading option to app cmd * Use legacy.RegisterAminoMsg for committee msg concrete registration * Remove unnecessary Amino field * Add evm_util bankkeeper SendCoins comment * Update test method ResetBankState to DeleteGenesisValidatorCoins to be more clear * Validate incentive params.RewardsPerSecond to be non-zero * Validate swap pools to disallow colons in token denoms * Register all legacy amino types on gov modulecdc * Remove redundant Comittee interface registration * Pin goleveldb to v1.0.1-0.20210819022825-2ae1ddf74ef7 Causes failed to load state at height errors * Update ethermint to new pinned version with minGasPrices parse error fix * Update cosmos fork dependcy commit to include reverted account constructor patch * Update Cosmos v0.46.11 and cometbft v0.34.27 * Bump minimum go version to 1.19 * Update tendermint proto * Update internal testnet genesis * Move NewCanTransferDecorator before NewEthGasConsumeDecorator * Add hard borrow store tests (#1514) * add store tests for Borrow type * refactor Deposit tests to match * Fix old bep3 tests (#1515) * Update Ethermint to 1b17445 to fix duplicate proto registration * Add custom status command to use snake_case and stdout * Add SetInflation helper * Reduce ambiguity with evm CanSignEthTx error * Remove init genesis validator claim in test * Add disabled evmante.NewMinGasPriceDecorator with x/feemarket note * chore: use tagged versions for Cosmos and Ethermint forks * update kvtool & increase wait for ibc transfer test --------- Signed-off-by: drklee3 <derrick@dlee.dev> Co-authored-by: Ruaridh <rhuairahrighairidh@users.noreply.github.com> Co-authored-by: Robert Pirtle <astropirtle@gmail.com>
2023-04-04 00:08:45 +00:00
sdkmath "cosmossdk.io/math"
sdk "github.com/cosmos/cosmos-sdk/types"
2020-12-21 17:18:55 +00:00
"github.com/kava-labs/kava/x/hard/types"
)
var (
scalingFactor = 1e18
secondsPerYear = 31536000
)
// ApplyInterestRateUpdates translates the current interest rate models from the params to the store,
// with each money market accruing interest.
func (k Keeper) ApplyInterestRateUpdates(ctx sdk.Context) {
denomSet := map[string]bool{}
params := k.GetParams(ctx)
for _, mm := range params.MoneyMarkets {
// Set any new money markets in the store
moneyMarket, found := k.GetMoneyMarket(ctx, mm.Denom)
if !found {
moneyMarket = mm
k.SetMoneyMarket(ctx, mm.Denom, moneyMarket)
}
// Accrue interest according to the current money markets in the store
err := k.AccrueInterest(ctx, mm.Denom)
if err != nil {
panic(err)
}
// Update the interest rate in the store if the params have changed
if !moneyMarket.Equal(mm) {
k.SetMoneyMarket(ctx, mm.Denom, mm)
}
denomSet[mm.Denom] = true
}
// Edge case: money markets removed from params that still exist in the store
k.IterateMoneyMarkets(ctx, func(denom string, i types.MoneyMarket) bool {
if !denomSet[denom] {
// Accrue interest according to current store money market
err := k.AccrueInterest(ctx, denom)
if err != nil {
panic(err)
}
// Delete the money market from the store
k.DeleteMoneyMarket(ctx, denom)
}
return false
})
}
// AccrueInterest applies accrued interest to total borrows and reserves by calculating
// interest from the last checkpoint time and writing the updated values to the store.
func (k Keeper) AccrueInterest(ctx sdk.Context, denom string) error {
previousAccrualTime, found := k.GetPreviousAccrualTime(ctx, denom)
if !found {
k.SetPreviousAccrualTime(ctx, denom, ctx.BlockTime())
return nil
}
timeElapsed := int64(math.RoundToEven(
ctx.BlockTime().Sub(previousAccrualTime).Seconds(),
))
if timeElapsed == 0 {
return nil
}
// Get current protocol state and hold in memory as 'prior'
macc := k.accountKeeper.GetModuleAccount(ctx, types.ModuleName)
cashPrior := k.bankKeeper.GetBalance(ctx, macc.GetAddress(), denom).Amount
borrowedPrior := sdk.NewCoin(denom, sdk.ZeroInt())
borrowedCoinsPrior, foundBorrowedCoinsPrior := k.GetBorrowedCoins(ctx)
if foundBorrowedCoinsPrior {
borrowedPrior = sdk.NewCoin(denom, borrowedCoinsPrior.AmountOf(denom))
}
if borrowedPrior.IsZero() {
k.SetPreviousAccrualTime(ctx, denom, ctx.BlockTime())
return nil
}
reservesPrior, foundReservesPrior := k.GetTotalReserves(ctx)
if !foundReservesPrior {
newReservesPrior := sdk.NewCoins()
k.SetTotalReserves(ctx, newReservesPrior)
reservesPrior = newReservesPrior
}
borrowInterestFactorPrior, foundBorrowInterestFactorPrior := k.GetBorrowInterestFactor(ctx, denom)
if !foundBorrowInterestFactorPrior {
newBorrowInterestFactorPrior := sdk.MustNewDecFromStr("1.0")
k.SetBorrowInterestFactor(ctx, denom, newBorrowInterestFactorPrior)
borrowInterestFactorPrior = newBorrowInterestFactorPrior
}
supplyInterestFactorPrior, foundSupplyInterestFactorPrior := k.GetSupplyInterestFactor(ctx, denom)
if !foundSupplyInterestFactorPrior {
newSupplyInterestFactorPrior := sdk.MustNewDecFromStr("1.0")
k.SetSupplyInterestFactor(ctx, denom, newSupplyInterestFactorPrior)
supplyInterestFactorPrior = newSupplyInterestFactorPrior
}
// Fetch money market from the store
mm, found := k.GetMoneyMarket(ctx, denom)
if !found {
return errorsmod.Wrapf(types.ErrMoneyMarketNotFound, "%s", denom)
}
// GetBorrowRate calculates the current interest rate based on utilization (the fraction of supply that has been borrowed)
borrowRateApy, err := CalculateBorrowRate(mm.InterestRateModel, sdk.NewDecFromInt(cashPrior), sdk.NewDecFromInt(borrowedPrior.Amount), sdk.NewDecFromInt(reservesPrior.AmountOf(denom)))
if err != nil {
return err
}
// Convert from APY to SPY, expressed as (1 + borrow rate)
borrowRateSpy, err := APYToSPY(sdk.OneDec().Add(borrowRateApy))
if err != nil {
return err
}
// Calculate borrow interest factor and update
borrowInterestFactor := CalculateBorrowInterestFactor(borrowRateSpy, sdkmath.NewInt(timeElapsed))
interestBorrowAccumulated := (borrowInterestFactor.Mul(sdk.NewDecFromInt(borrowedPrior.Amount)).TruncateInt()).Sub(borrowedPrior.Amount)
if interestBorrowAccumulated.IsZero() && borrowRateApy.IsPositive() {
// don't accumulate if borrow interest is rounding to zero
return nil
}
totalBorrowInterestAccumulated := sdk.NewCoins(sdk.NewCoin(denom, interestBorrowAccumulated))
feat: upgrade to Cosmos v0.46 (#1477) * Update cosmos-sdk to v0.45.10-kava * Add RegisterNodeService to app * Update cosmos proto files * Update cosmos proto files * Use tagged v0.45.10-kava-v0.19-0.21 cosmos version * update x/auth/legacy to x/auth/migrations * Delete rest packages and registration * Remove rest from proposal handlers * Remove legacy types referencing removed sdk types * Remove legacy tx broadcast handler * Update incentive staking hooks to return error * Remove grpc replace directive, use new grpc version * Fix storetypes import * Update tally_handler with updated gov types * Delete legacy types * Use new gov default config * Update RegisterTendermintService params Signed-off-by: drklee3 <derrick@dlee.dev> * Replace sdk.StoreKey with storetypes.StoreKey * Replace sdk.Int#ToDec with sdk.NewDecFromInt * Replace sdk.NewUintFromBigInt with sdkmath.NewUintFromBigInt Signed-off-by: drklee3 <derrick@dlee.dev> * Update most intances of govtypes to govv1beta1 * Unpack coin slice for Coins#Sub and Coins#SafeSub Signed-off-by: drklee3 <derrick@dlee.dev> * Update committee gov codec registration Signed-off-by: drklee3 <derrick@dlee.dev> * Update migrate utils period_vesting Coins#Sub Signed-off-by: drklee3 <derrick@dlee.dev> * Update Coin#Sub in community proposal handler Signed-off-by: drklee3 <derrick@dlee.dev> * Update Coin#Sub, FundModuleAccount/FundAccount in banktestutil Signed-off-by: drklee3 <derrick@dlee.dev> * Update community, earn, kavadist proposal gov registration * Update evm cli client EthSecp256k1Type check * AccAddressFromHex to AccAddressFromHexUnsafe * Add mint DefaultInflationCalculationFn to earn test * Update use of removed staking.NewHandler * Rename FlagIAVLFastNode -> FlagDisableIAVLFastNode * cmd: Update new snapshot app option Signed-off-by: drklee3 <derrick@dlee.dev> * cmd: Add tendermint default config, use cosmos rpc status command Signed-off-by: drklee3 <derrick@dlee.dev> * Update ethermint import path github.com/tharsis/ethermint -> github.com/evmos/ethermint * Upgrade ibc-go to v6 * Update proto dependencies Signed-off-by: drklee3 <derrick@dlee.dev> * Update Tally handler test with new gov types * Update helpers.GenTx -> helpers.GenSignedMockTx * Update evmkeeper.NewKeeper params Signed-off-by: drklee3 <derrick@dlee.dev> * Update ante authz, tests * Add feemarket transient key, pass subspaces to evm/feemarket keepers * Update new ante decorators * Add new addModuleInitFlags to server commands * Pass codec to keyring.New in genaccounts * Pass codec to client keys add * Add SendCoins to evmutil bank_keeper * Use github.com/cosmos/iavl@v0.19.5 * Add ante HandlerOptions * Add unimplemented SendCoins to evmutil bank keeper Ethermint x/evm does not use this method * Update init-new-chain script to disable post-london blocks * Modify test genesis states to append 1 validator * Update tally handler test to use string values * Prevent querying balance for empty sdk.AccAddress in auction bidding test * Set default bond denom to ukava * Remove overwritten bank genesis total supply in committee proposal test Signed-off-by: drklee3 <derrick@dlee.dev> * Use ukava for testing staked balance * Disable minting in community proposal handler test Previously stake denom is used, which resulted in 0 minted coins * Update hard APYToSPY test expected value Increased iterations in sdk.ApproxRoot, updated closer to real value * Fix NewDecCoinsFromCoins bug in incentive collectDerivativeStakingRewards * Allow bkava earn incentive test values to match within small margin for rounding Signed-off-by: drklee3 <derrick@dlee.dev> * Update invalid denom in issuance message coin validation Colons are now valid in denoms Signed-off-by: drklee3 <derrick@dlee.dev> * Remove genesis validator in incentive delegation tests * Update pricefeed market test for invalid denom Signed-off-by: drklee3 <derrick@dlee.dev> * Update incentive delegator rewards test without genesis validator Signed-off-by: drklee3 <derrick@dlee.dev> * Add validator to export test * Clear bank state in minting tests Signed-off-by: drklee3 <derrick@dlee.dev> * Remove validator for no stake tally test Signed-off-by: drklee3 <derrick@dlee.dev> * Clear incentive state before InitGenesis in incentive genesis export test * Update swagger Signed-off-by: drklee3 <derrick@dlee.dev> * Update ethermint version to match replaced version * Remove legacy swagger * Add NewEthEmitEventDecorator * Remove redundant func for AddModuleInitFlags * Remove unused addBankBalanceForAddress func * Add SetIAVLLazyLoading option to app cmd * Use legacy.RegisterAminoMsg for committee msg concrete registration * Remove unnecessary Amino field * Add evm_util bankkeeper SendCoins comment * Update test method ResetBankState to DeleteGenesisValidatorCoins to be more clear * Validate incentive params.RewardsPerSecond to be non-zero * Validate swap pools to disallow colons in token denoms * Register all legacy amino types on gov modulecdc * Remove redundant Comittee interface registration * Pin goleveldb to v1.0.1-0.20210819022825-2ae1ddf74ef7 Causes failed to load state at height errors * Update ethermint to new pinned version with minGasPrices parse error fix * Update cosmos fork dependcy commit to include reverted account constructor patch * Update Cosmos v0.46.11 and cometbft v0.34.27 * Bump minimum go version to 1.19 * Update tendermint proto * Update internal testnet genesis * Move NewCanTransferDecorator before NewEthGasConsumeDecorator * Add hard borrow store tests (#1514) * add store tests for Borrow type * refactor Deposit tests to match * Fix old bep3 tests (#1515) * Update Ethermint to 1b17445 to fix duplicate proto registration * Add custom status command to use snake_case and stdout * Add SetInflation helper * Reduce ambiguity with evm CanSignEthTx error * Remove init genesis validator claim in test * Add disabled evmante.NewMinGasPriceDecorator with x/feemarket note * chore: use tagged versions for Cosmos and Ethermint forks * update kvtool & increase wait for ibc transfer test --------- Signed-off-by: drklee3 <derrick@dlee.dev> Co-authored-by: Ruaridh <rhuairahrighairidh@users.noreply.github.com> Co-authored-by: Robert Pirtle <astropirtle@gmail.com>
2023-04-04 00:08:45 +00:00
reservesNew := sdk.NewDecFromInt(interestBorrowAccumulated).Mul(mm.ReserveFactor).TruncateInt()
borrowInterestFactorNew := borrowInterestFactorPrior.Mul(borrowInterestFactor)
k.SetBorrowInterestFactor(ctx, denom, borrowInterestFactorNew)
// Calculate supply interest factor and update
supplyInterestNew := interestBorrowAccumulated.Sub(reservesNew)
feat: upgrade to Cosmos v0.46 (#1477) * Update cosmos-sdk to v0.45.10-kava * Add RegisterNodeService to app * Update cosmos proto files * Update cosmos proto files * Use tagged v0.45.10-kava-v0.19-0.21 cosmos version * update x/auth/legacy to x/auth/migrations * Delete rest packages and registration * Remove rest from proposal handlers * Remove legacy types referencing removed sdk types * Remove legacy tx broadcast handler * Update incentive staking hooks to return error * Remove grpc replace directive, use new grpc version * Fix storetypes import * Update tally_handler with updated gov types * Delete legacy types * Use new gov default config * Update RegisterTendermintService params Signed-off-by: drklee3 <derrick@dlee.dev> * Replace sdk.StoreKey with storetypes.StoreKey * Replace sdk.Int#ToDec with sdk.NewDecFromInt * Replace sdk.NewUintFromBigInt with sdkmath.NewUintFromBigInt Signed-off-by: drklee3 <derrick@dlee.dev> * Update most intances of govtypes to govv1beta1 * Unpack coin slice for Coins#Sub and Coins#SafeSub Signed-off-by: drklee3 <derrick@dlee.dev> * Update committee gov codec registration Signed-off-by: drklee3 <derrick@dlee.dev> * Update migrate utils period_vesting Coins#Sub Signed-off-by: drklee3 <derrick@dlee.dev> * Update Coin#Sub in community proposal handler Signed-off-by: drklee3 <derrick@dlee.dev> * Update Coin#Sub, FundModuleAccount/FundAccount in banktestutil Signed-off-by: drklee3 <derrick@dlee.dev> * Update community, earn, kavadist proposal gov registration * Update evm cli client EthSecp256k1Type check * AccAddressFromHex to AccAddressFromHexUnsafe * Add mint DefaultInflationCalculationFn to earn test * Update use of removed staking.NewHandler * Rename FlagIAVLFastNode -> FlagDisableIAVLFastNode * cmd: Update new snapshot app option Signed-off-by: drklee3 <derrick@dlee.dev> * cmd: Add tendermint default config, use cosmos rpc status command Signed-off-by: drklee3 <derrick@dlee.dev> * Update ethermint import path github.com/tharsis/ethermint -> github.com/evmos/ethermint * Upgrade ibc-go to v6 * Update proto dependencies Signed-off-by: drklee3 <derrick@dlee.dev> * Update Tally handler test with new gov types * Update helpers.GenTx -> helpers.GenSignedMockTx * Update evmkeeper.NewKeeper params Signed-off-by: drklee3 <derrick@dlee.dev> * Update ante authz, tests * Add feemarket transient key, pass subspaces to evm/feemarket keepers * Update new ante decorators * Add new addModuleInitFlags to server commands * Pass codec to keyring.New in genaccounts * Pass codec to client keys add * Add SendCoins to evmutil bank_keeper * Use github.com/cosmos/iavl@v0.19.5 * Add ante HandlerOptions * Add unimplemented SendCoins to evmutil bank keeper Ethermint x/evm does not use this method * Update init-new-chain script to disable post-london blocks * Modify test genesis states to append 1 validator * Update tally handler test to use string values * Prevent querying balance for empty sdk.AccAddress in auction bidding test * Set default bond denom to ukava * Remove overwritten bank genesis total supply in committee proposal test Signed-off-by: drklee3 <derrick@dlee.dev> * Use ukava for testing staked balance * Disable minting in community proposal handler test Previously stake denom is used, which resulted in 0 minted coins * Update hard APYToSPY test expected value Increased iterations in sdk.ApproxRoot, updated closer to real value * Fix NewDecCoinsFromCoins bug in incentive collectDerivativeStakingRewards * Allow bkava earn incentive test values to match within small margin for rounding Signed-off-by: drklee3 <derrick@dlee.dev> * Update invalid denom in issuance message coin validation Colons are now valid in denoms Signed-off-by: drklee3 <derrick@dlee.dev> * Remove genesis validator in incentive delegation tests * Update pricefeed market test for invalid denom Signed-off-by: drklee3 <derrick@dlee.dev> * Update incentive delegator rewards test without genesis validator Signed-off-by: drklee3 <derrick@dlee.dev> * Add validator to export test * Clear bank state in minting tests Signed-off-by: drklee3 <derrick@dlee.dev> * Remove validator for no stake tally test Signed-off-by: drklee3 <derrick@dlee.dev> * Clear incentive state before InitGenesis in incentive genesis export test * Update swagger Signed-off-by: drklee3 <derrick@dlee.dev> * Update ethermint version to match replaced version * Remove legacy swagger * Add NewEthEmitEventDecorator * Remove redundant func for AddModuleInitFlags * Remove unused addBankBalanceForAddress func * Add SetIAVLLazyLoading option to app cmd * Use legacy.RegisterAminoMsg for committee msg concrete registration * Remove unnecessary Amino field * Add evm_util bankkeeper SendCoins comment * Update test method ResetBankState to DeleteGenesisValidatorCoins to be more clear * Validate incentive params.RewardsPerSecond to be non-zero * Validate swap pools to disallow colons in token denoms * Register all legacy amino types on gov modulecdc * Remove redundant Comittee interface registration * Pin goleveldb to v1.0.1-0.20210819022825-2ae1ddf74ef7 Causes failed to load state at height errors * Update ethermint to new pinned version with minGasPrices parse error fix * Update cosmos fork dependcy commit to include reverted account constructor patch * Update Cosmos v0.46.11 and cometbft v0.34.27 * Bump minimum go version to 1.19 * Update tendermint proto * Update internal testnet genesis * Move NewCanTransferDecorator before NewEthGasConsumeDecorator * Add hard borrow store tests (#1514) * add store tests for Borrow type * refactor Deposit tests to match * Fix old bep3 tests (#1515) * Update Ethermint to 1b17445 to fix duplicate proto registration * Add custom status command to use snake_case and stdout * Add SetInflation helper * Reduce ambiguity with evm CanSignEthTx error * Remove init genesis validator claim in test * Add disabled evmante.NewMinGasPriceDecorator with x/feemarket note * chore: use tagged versions for Cosmos and Ethermint forks * update kvtool & increase wait for ibc transfer test --------- Signed-off-by: drklee3 <derrick@dlee.dev> Co-authored-by: Ruaridh <rhuairahrighairidh@users.noreply.github.com> Co-authored-by: Robert Pirtle <astropirtle@gmail.com>
2023-04-04 00:08:45 +00:00
supplyInterestFactor := CalculateSupplyInterestFactor(sdk.NewDecFromInt(supplyInterestNew), sdk.NewDecFromInt(cashPrior), sdk.NewDecFromInt(borrowedPrior.Amount), sdk.NewDecFromInt(reservesPrior.AmountOf(denom)))
supplyInterestFactorNew := supplyInterestFactorPrior.Mul(supplyInterestFactor)
k.SetSupplyInterestFactor(ctx, denom, supplyInterestFactorNew)
// Update accural keys in store
k.IncrementBorrowedCoins(ctx, totalBorrowInterestAccumulated)
k.IncrementSuppliedCoins(ctx, sdk.NewCoins(sdk.NewCoin(denom, supplyInterestNew)))
k.SetTotalReserves(ctx, reservesPrior.Add(sdk.NewCoin(denom, reservesNew)))
k.SetPreviousAccrualTime(ctx, denom, ctx.BlockTime())
return nil
}
// CalculateBorrowRate calculates the borrow rate, which is the current APY expressed as a decimal
// based on the current utilization.
func CalculateBorrowRate(model types.InterestRateModel, cash, borrows, reserves sdk.Dec) (sdk.Dec, error) {
utilRatio := CalculateUtilizationRatio(cash, borrows, reserves)
// Calculate normal borrow rate (under kink)
if utilRatio.LTE(model.Kink) {
return utilRatio.Mul(model.BaseMultiplier).Add(model.BaseRateAPY), nil
}
// Calculate jump borrow rate (over kink)
normalRate := model.Kink.Mul(model.BaseMultiplier).Add(model.BaseRateAPY)
excessUtil := utilRatio.Sub(model.Kink)
return excessUtil.Mul(model.JumpMultiplier).Add(normalRate), nil
}
// CalculateUtilizationRatio calculates an asset's current utilization rate
func CalculateUtilizationRatio(cash, borrows, reserves sdk.Dec) sdk.Dec {
// Utilization rate is 0 when there are no borrows
if borrows.Equal(sdk.ZeroDec()) {
return sdk.ZeroDec()
}
totalSupply := cash.Add(borrows).Sub(reserves)
if totalSupply.IsNegative() {
return sdk.OneDec()
}
return sdk.MinDec(sdk.OneDec(), borrows.Quo(totalSupply))
}
// CalculateBorrowInterestFactor calculates the simple interest scaling factor,
// which is equal to: (per-second interest rate * number of seconds elapsed)
// Will return 1.000x, multiply by principal to get new principal with added interest
func CalculateBorrowInterestFactor(perSecondInterestRate sdk.Dec, secondsElapsed sdkmath.Int) sdk.Dec {
scalingFactorUint := sdk.NewUint(uint64(scalingFactor))
scalingFactorInt := sdkmath.NewInt(int64(scalingFactor))
// Convert per-second interest rate to a uint scaled by 1e18
feat: upgrade to Cosmos v0.46 (#1477) * Update cosmos-sdk to v0.45.10-kava * Add RegisterNodeService to app * Update cosmos proto files * Update cosmos proto files * Use tagged v0.45.10-kava-v0.19-0.21 cosmos version * update x/auth/legacy to x/auth/migrations * Delete rest packages and registration * Remove rest from proposal handlers * Remove legacy types referencing removed sdk types * Remove legacy tx broadcast handler * Update incentive staking hooks to return error * Remove grpc replace directive, use new grpc version * Fix storetypes import * Update tally_handler with updated gov types * Delete legacy types * Use new gov default config * Update RegisterTendermintService params Signed-off-by: drklee3 <derrick@dlee.dev> * Replace sdk.StoreKey with storetypes.StoreKey * Replace sdk.Int#ToDec with sdk.NewDecFromInt * Replace sdk.NewUintFromBigInt with sdkmath.NewUintFromBigInt Signed-off-by: drklee3 <derrick@dlee.dev> * Update most intances of govtypes to govv1beta1 * Unpack coin slice for Coins#Sub and Coins#SafeSub Signed-off-by: drklee3 <derrick@dlee.dev> * Update committee gov codec registration Signed-off-by: drklee3 <derrick@dlee.dev> * Update migrate utils period_vesting Coins#Sub Signed-off-by: drklee3 <derrick@dlee.dev> * Update Coin#Sub in community proposal handler Signed-off-by: drklee3 <derrick@dlee.dev> * Update Coin#Sub, FundModuleAccount/FundAccount in banktestutil Signed-off-by: drklee3 <derrick@dlee.dev> * Update community, earn, kavadist proposal gov registration * Update evm cli client EthSecp256k1Type check * AccAddressFromHex to AccAddressFromHexUnsafe * Add mint DefaultInflationCalculationFn to earn test * Update use of removed staking.NewHandler * Rename FlagIAVLFastNode -> FlagDisableIAVLFastNode * cmd: Update new snapshot app option Signed-off-by: drklee3 <derrick@dlee.dev> * cmd: Add tendermint default config, use cosmos rpc status command Signed-off-by: drklee3 <derrick@dlee.dev> * Update ethermint import path github.com/tharsis/ethermint -> github.com/evmos/ethermint * Upgrade ibc-go to v6 * Update proto dependencies Signed-off-by: drklee3 <derrick@dlee.dev> * Update Tally handler test with new gov types * Update helpers.GenTx -> helpers.GenSignedMockTx * Update evmkeeper.NewKeeper params Signed-off-by: drklee3 <derrick@dlee.dev> * Update ante authz, tests * Add feemarket transient key, pass subspaces to evm/feemarket keepers * Update new ante decorators * Add new addModuleInitFlags to server commands * Pass codec to keyring.New in genaccounts * Pass codec to client keys add * Add SendCoins to evmutil bank_keeper * Use github.com/cosmos/iavl@v0.19.5 * Add ante HandlerOptions * Add unimplemented SendCoins to evmutil bank keeper Ethermint x/evm does not use this method * Update init-new-chain script to disable post-london blocks * Modify test genesis states to append 1 validator * Update tally handler test to use string values * Prevent querying balance for empty sdk.AccAddress in auction bidding test * Set default bond denom to ukava * Remove overwritten bank genesis total supply in committee proposal test Signed-off-by: drklee3 <derrick@dlee.dev> * Use ukava for testing staked balance * Disable minting in community proposal handler test Previously stake denom is used, which resulted in 0 minted coins * Update hard APYToSPY test expected value Increased iterations in sdk.ApproxRoot, updated closer to real value * Fix NewDecCoinsFromCoins bug in incentive collectDerivativeStakingRewards * Allow bkava earn incentive test values to match within small margin for rounding Signed-off-by: drklee3 <derrick@dlee.dev> * Update invalid denom in issuance message coin validation Colons are now valid in denoms Signed-off-by: drklee3 <derrick@dlee.dev> * Remove genesis validator in incentive delegation tests * Update pricefeed market test for invalid denom Signed-off-by: drklee3 <derrick@dlee.dev> * Update incentive delegator rewards test without genesis validator Signed-off-by: drklee3 <derrick@dlee.dev> * Add validator to export test * Clear bank state in minting tests Signed-off-by: drklee3 <derrick@dlee.dev> * Remove validator for no stake tally test Signed-off-by: drklee3 <derrick@dlee.dev> * Clear incentive state before InitGenesis in incentive genesis export test * Update swagger Signed-off-by: drklee3 <derrick@dlee.dev> * Update ethermint version to match replaced version * Remove legacy swagger * Add NewEthEmitEventDecorator * Remove redundant func for AddModuleInitFlags * Remove unused addBankBalanceForAddress func * Add SetIAVLLazyLoading option to app cmd * Use legacy.RegisterAminoMsg for committee msg concrete registration * Remove unnecessary Amino field * Add evm_util bankkeeper SendCoins comment * Update test method ResetBankState to DeleteGenesisValidatorCoins to be more clear * Validate incentive params.RewardsPerSecond to be non-zero * Validate swap pools to disallow colons in token denoms * Register all legacy amino types on gov modulecdc * Remove redundant Comittee interface registration * Pin goleveldb to v1.0.1-0.20210819022825-2ae1ddf74ef7 Causes failed to load state at height errors * Update ethermint to new pinned version with minGasPrices parse error fix * Update cosmos fork dependcy commit to include reverted account constructor patch * Update Cosmos v0.46.11 and cometbft v0.34.27 * Bump minimum go version to 1.19 * Update tendermint proto * Update internal testnet genesis * Move NewCanTransferDecorator before NewEthGasConsumeDecorator * Add hard borrow store tests (#1514) * add store tests for Borrow type * refactor Deposit tests to match * Fix old bep3 tests (#1515) * Update Ethermint to 1b17445 to fix duplicate proto registration * Add custom status command to use snake_case and stdout * Add SetInflation helper * Reduce ambiguity with evm CanSignEthTx error * Remove init genesis validator claim in test * Add disabled evmante.NewMinGasPriceDecorator with x/feemarket note * chore: use tagged versions for Cosmos and Ethermint forks * update kvtool & increase wait for ibc transfer test --------- Signed-off-by: drklee3 <derrick@dlee.dev> Co-authored-by: Ruaridh <rhuairahrighairidh@users.noreply.github.com> Co-authored-by: Robert Pirtle <astropirtle@gmail.com>
2023-04-04 00:08:45 +00:00
interestMantissa := sdkmath.NewUintFromBigInt(perSecondInterestRate.MulInt(scalingFactorInt).RoundInt().BigInt())
// Convert seconds elapsed to uint (*not scaled*)
feat: upgrade to Cosmos v0.46 (#1477) * Update cosmos-sdk to v0.45.10-kava * Add RegisterNodeService to app * Update cosmos proto files * Update cosmos proto files * Use tagged v0.45.10-kava-v0.19-0.21 cosmos version * update x/auth/legacy to x/auth/migrations * Delete rest packages and registration * Remove rest from proposal handlers * Remove legacy types referencing removed sdk types * Remove legacy tx broadcast handler * Update incentive staking hooks to return error * Remove grpc replace directive, use new grpc version * Fix storetypes import * Update tally_handler with updated gov types * Delete legacy types * Use new gov default config * Update RegisterTendermintService params Signed-off-by: drklee3 <derrick@dlee.dev> * Replace sdk.StoreKey with storetypes.StoreKey * Replace sdk.Int#ToDec with sdk.NewDecFromInt * Replace sdk.NewUintFromBigInt with sdkmath.NewUintFromBigInt Signed-off-by: drklee3 <derrick@dlee.dev> * Update most intances of govtypes to govv1beta1 * Unpack coin slice for Coins#Sub and Coins#SafeSub Signed-off-by: drklee3 <derrick@dlee.dev> * Update committee gov codec registration Signed-off-by: drklee3 <derrick@dlee.dev> * Update migrate utils period_vesting Coins#Sub Signed-off-by: drklee3 <derrick@dlee.dev> * Update Coin#Sub in community proposal handler Signed-off-by: drklee3 <derrick@dlee.dev> * Update Coin#Sub, FundModuleAccount/FundAccount in banktestutil Signed-off-by: drklee3 <derrick@dlee.dev> * Update community, earn, kavadist proposal gov registration * Update evm cli client EthSecp256k1Type check * AccAddressFromHex to AccAddressFromHexUnsafe * Add mint DefaultInflationCalculationFn to earn test * Update use of removed staking.NewHandler * Rename FlagIAVLFastNode -> FlagDisableIAVLFastNode * cmd: Update new snapshot app option Signed-off-by: drklee3 <derrick@dlee.dev> * cmd: Add tendermint default config, use cosmos rpc status command Signed-off-by: drklee3 <derrick@dlee.dev> * Update ethermint import path github.com/tharsis/ethermint -> github.com/evmos/ethermint * Upgrade ibc-go to v6 * Update proto dependencies Signed-off-by: drklee3 <derrick@dlee.dev> * Update Tally handler test with new gov types * Update helpers.GenTx -> helpers.GenSignedMockTx * Update evmkeeper.NewKeeper params Signed-off-by: drklee3 <derrick@dlee.dev> * Update ante authz, tests * Add feemarket transient key, pass subspaces to evm/feemarket keepers * Update new ante decorators * Add new addModuleInitFlags to server commands * Pass codec to keyring.New in genaccounts * Pass codec to client keys add * Add SendCoins to evmutil bank_keeper * Use github.com/cosmos/iavl@v0.19.5 * Add ante HandlerOptions * Add unimplemented SendCoins to evmutil bank keeper Ethermint x/evm does not use this method * Update init-new-chain script to disable post-london blocks * Modify test genesis states to append 1 validator * Update tally handler test to use string values * Prevent querying balance for empty sdk.AccAddress in auction bidding test * Set default bond denom to ukava * Remove overwritten bank genesis total supply in committee proposal test Signed-off-by: drklee3 <derrick@dlee.dev> * Use ukava for testing staked balance * Disable minting in community proposal handler test Previously stake denom is used, which resulted in 0 minted coins * Update hard APYToSPY test expected value Increased iterations in sdk.ApproxRoot, updated closer to real value * Fix NewDecCoinsFromCoins bug in incentive collectDerivativeStakingRewards * Allow bkava earn incentive test values to match within small margin for rounding Signed-off-by: drklee3 <derrick@dlee.dev> * Update invalid denom in issuance message coin validation Colons are now valid in denoms Signed-off-by: drklee3 <derrick@dlee.dev> * Remove genesis validator in incentive delegation tests * Update pricefeed market test for invalid denom Signed-off-by: drklee3 <derrick@dlee.dev> * Update incentive delegator rewards test without genesis validator Signed-off-by: drklee3 <derrick@dlee.dev> * Add validator to export test * Clear bank state in minting tests Signed-off-by: drklee3 <derrick@dlee.dev> * Remove validator for no stake tally test Signed-off-by: drklee3 <derrick@dlee.dev> * Clear incentive state before InitGenesis in incentive genesis export test * Update swagger Signed-off-by: drklee3 <derrick@dlee.dev> * Update ethermint version to match replaced version * Remove legacy swagger * Add NewEthEmitEventDecorator * Remove redundant func for AddModuleInitFlags * Remove unused addBankBalanceForAddress func * Add SetIAVLLazyLoading option to app cmd * Use legacy.RegisterAminoMsg for committee msg concrete registration * Remove unnecessary Amino field * Add evm_util bankkeeper SendCoins comment * Update test method ResetBankState to DeleteGenesisValidatorCoins to be more clear * Validate incentive params.RewardsPerSecond to be non-zero * Validate swap pools to disallow colons in token denoms * Register all legacy amino types on gov modulecdc * Remove redundant Comittee interface registration * Pin goleveldb to v1.0.1-0.20210819022825-2ae1ddf74ef7 Causes failed to load state at height errors * Update ethermint to new pinned version with minGasPrices parse error fix * Update cosmos fork dependcy commit to include reverted account constructor patch * Update Cosmos v0.46.11 and cometbft v0.34.27 * Bump minimum go version to 1.19 * Update tendermint proto * Update internal testnet genesis * Move NewCanTransferDecorator before NewEthGasConsumeDecorator * Add hard borrow store tests (#1514) * add store tests for Borrow type * refactor Deposit tests to match * Fix old bep3 tests (#1515) * Update Ethermint to 1b17445 to fix duplicate proto registration * Add custom status command to use snake_case and stdout * Add SetInflation helper * Reduce ambiguity with evm CanSignEthTx error * Remove init genesis validator claim in test * Add disabled evmante.NewMinGasPriceDecorator with x/feemarket note * chore: use tagged versions for Cosmos and Ethermint forks * update kvtool & increase wait for ibc transfer test --------- Signed-off-by: drklee3 <derrick@dlee.dev> Co-authored-by: Ruaridh <rhuairahrighairidh@users.noreply.github.com> Co-authored-by: Robert Pirtle <astropirtle@gmail.com>
2023-04-04 00:08:45 +00:00
secondsElapsedUint := sdkmath.NewUintFromBigInt(secondsElapsed.BigInt())
// Calculate the interest factor as a uint scaled by 1e18
feat: upgrade to Cosmos v0.46 (#1477) * Update cosmos-sdk to v0.45.10-kava * Add RegisterNodeService to app * Update cosmos proto files * Update cosmos proto files * Use tagged v0.45.10-kava-v0.19-0.21 cosmos version * update x/auth/legacy to x/auth/migrations * Delete rest packages and registration * Remove rest from proposal handlers * Remove legacy types referencing removed sdk types * Remove legacy tx broadcast handler * Update incentive staking hooks to return error * Remove grpc replace directive, use new grpc version * Fix storetypes import * Update tally_handler with updated gov types * Delete legacy types * Use new gov default config * Update RegisterTendermintService params Signed-off-by: drklee3 <derrick@dlee.dev> * Replace sdk.StoreKey with storetypes.StoreKey * Replace sdk.Int#ToDec with sdk.NewDecFromInt * Replace sdk.NewUintFromBigInt with sdkmath.NewUintFromBigInt Signed-off-by: drklee3 <derrick@dlee.dev> * Update most intances of govtypes to govv1beta1 * Unpack coin slice for Coins#Sub and Coins#SafeSub Signed-off-by: drklee3 <derrick@dlee.dev> * Update committee gov codec registration Signed-off-by: drklee3 <derrick@dlee.dev> * Update migrate utils period_vesting Coins#Sub Signed-off-by: drklee3 <derrick@dlee.dev> * Update Coin#Sub in community proposal handler Signed-off-by: drklee3 <derrick@dlee.dev> * Update Coin#Sub, FundModuleAccount/FundAccount in banktestutil Signed-off-by: drklee3 <derrick@dlee.dev> * Update community, earn, kavadist proposal gov registration * Update evm cli client EthSecp256k1Type check * AccAddressFromHex to AccAddressFromHexUnsafe * Add mint DefaultInflationCalculationFn to earn test * Update use of removed staking.NewHandler * Rename FlagIAVLFastNode -> FlagDisableIAVLFastNode * cmd: Update new snapshot app option Signed-off-by: drklee3 <derrick@dlee.dev> * cmd: Add tendermint default config, use cosmos rpc status command Signed-off-by: drklee3 <derrick@dlee.dev> * Update ethermint import path github.com/tharsis/ethermint -> github.com/evmos/ethermint * Upgrade ibc-go to v6 * Update proto dependencies Signed-off-by: drklee3 <derrick@dlee.dev> * Update Tally handler test with new gov types * Update helpers.GenTx -> helpers.GenSignedMockTx * Update evmkeeper.NewKeeper params Signed-off-by: drklee3 <derrick@dlee.dev> * Update ante authz, tests * Add feemarket transient key, pass subspaces to evm/feemarket keepers * Update new ante decorators * Add new addModuleInitFlags to server commands * Pass codec to keyring.New in genaccounts * Pass codec to client keys add * Add SendCoins to evmutil bank_keeper * Use github.com/cosmos/iavl@v0.19.5 * Add ante HandlerOptions * Add unimplemented SendCoins to evmutil bank keeper Ethermint x/evm does not use this method * Update init-new-chain script to disable post-london blocks * Modify test genesis states to append 1 validator * Update tally handler test to use string values * Prevent querying balance for empty sdk.AccAddress in auction bidding test * Set default bond denom to ukava * Remove overwritten bank genesis total supply in committee proposal test Signed-off-by: drklee3 <derrick@dlee.dev> * Use ukava for testing staked balance * Disable minting in community proposal handler test Previously stake denom is used, which resulted in 0 minted coins * Update hard APYToSPY test expected value Increased iterations in sdk.ApproxRoot, updated closer to real value * Fix NewDecCoinsFromCoins bug in incentive collectDerivativeStakingRewards * Allow bkava earn incentive test values to match within small margin for rounding Signed-off-by: drklee3 <derrick@dlee.dev> * Update invalid denom in issuance message coin validation Colons are now valid in denoms Signed-off-by: drklee3 <derrick@dlee.dev> * Remove genesis validator in incentive delegation tests * Update pricefeed market test for invalid denom Signed-off-by: drklee3 <derrick@dlee.dev> * Update incentive delegator rewards test without genesis validator Signed-off-by: drklee3 <derrick@dlee.dev> * Add validator to export test * Clear bank state in minting tests Signed-off-by: drklee3 <derrick@dlee.dev> * Remove validator for no stake tally test Signed-off-by: drklee3 <derrick@dlee.dev> * Clear incentive state before InitGenesis in incentive genesis export test * Update swagger Signed-off-by: drklee3 <derrick@dlee.dev> * Update ethermint version to match replaced version * Remove legacy swagger * Add NewEthEmitEventDecorator * Remove redundant func for AddModuleInitFlags * Remove unused addBankBalanceForAddress func * Add SetIAVLLazyLoading option to app cmd * Use legacy.RegisterAminoMsg for committee msg concrete registration * Remove unnecessary Amino field * Add evm_util bankkeeper SendCoins comment * Update test method ResetBankState to DeleteGenesisValidatorCoins to be more clear * Validate incentive params.RewardsPerSecond to be non-zero * Validate swap pools to disallow colons in token denoms * Register all legacy amino types on gov modulecdc * Remove redundant Comittee interface registration * Pin goleveldb to v1.0.1-0.20210819022825-2ae1ddf74ef7 Causes failed to load state at height errors * Update ethermint to new pinned version with minGasPrices parse error fix * Update cosmos fork dependcy commit to include reverted account constructor patch * Update Cosmos v0.46.11 and cometbft v0.34.27 * Bump minimum go version to 1.19 * Update tendermint proto * Update internal testnet genesis * Move NewCanTransferDecorator before NewEthGasConsumeDecorator * Add hard borrow store tests (#1514) * add store tests for Borrow type * refactor Deposit tests to match * Fix old bep3 tests (#1515) * Update Ethermint to 1b17445 to fix duplicate proto registration * Add custom status command to use snake_case and stdout * Add SetInflation helper * Reduce ambiguity with evm CanSignEthTx error * Remove init genesis validator claim in test * Add disabled evmante.NewMinGasPriceDecorator with x/feemarket note * chore: use tagged versions for Cosmos and Ethermint forks * update kvtool & increase wait for ibc transfer test --------- Signed-off-by: drklee3 <derrick@dlee.dev> Co-authored-by: Ruaridh <rhuairahrighairidh@users.noreply.github.com> Co-authored-by: Robert Pirtle <astropirtle@gmail.com>
2023-04-04 00:08:45 +00:00
interestFactorMantissa := sdkmath.RelativePow(interestMantissa, secondsElapsedUint, scalingFactorUint)
// Convert interest factor to an unscaled sdk.Dec
return sdk.NewDecFromBigInt(interestFactorMantissa.BigInt()).QuoInt(scalingFactorInt)
}
// CalculateSupplyInterestFactor calculates the supply interest factor, which is the percentage of borrow interest
// that flows to each unit of supply, i.e. at 50% utilization and 0% reserve factor, a 5% borrow interest will
// correspond to a 2.5% supply interest.
func CalculateSupplyInterestFactor(newInterest, cash, borrows, reserves sdk.Dec) sdk.Dec {
totalSupply := cash.Add(borrows).Sub(reserves)
if totalSupply.IsZero() {
return sdk.OneDec()
}
return (newInterest.Quo(totalSupply)).Add(sdk.OneDec())
}
// SyncBorrowInterest updates the user's owed interest on newly borrowed coins to the latest global state
func (k Keeper) SyncBorrowInterest(ctx sdk.Context, addr sdk.AccAddress) {
totalNewInterest := sdk.Coins{}
// Update user's borrow interest factor list for each asset in the 'coins' array.
// We use a list of BorrowInterestFactors here because Amino doesn't support marshaling maps.
borrow, found := k.GetBorrow(ctx, addr)
if !found {
return
}
for _, coin := range borrow.Amount {
// Locate the borrow interest factor item by coin denom in the user's list of borrow indexes
foundAtIndex := -1
for i := range borrow.Index {
if borrow.Index[i].Denom == coin.Denom {
foundAtIndex = i
break
}
}
interestFactorValue, _ := k.GetBorrowInterestFactor(ctx, coin.Denom)
if foundAtIndex == -1 { // First time user has borrowed this denom
borrow.Index = append(borrow.Index, types.NewBorrowInterestFactor(coin.Denom, interestFactorValue))
} else { // User has an existing borrow index for this denom
// Calculate interest owed by user since asset's last borrow index update
storedAmount := sdk.NewDecFromInt(borrow.Amount.AmountOf(coin.Denom))
userLastInterestFactor := borrow.Index[foundAtIndex].Value
interest := (storedAmount.Quo(userLastInterestFactor).Mul(interestFactorValue)).Sub(storedAmount)
totalNewInterest = totalNewInterest.Add(sdk.NewCoin(coin.Denom, interest.TruncateInt()))
// We're synced up, so update user's borrow index value to match the current global borrow index value
borrow.Index[foundAtIndex].Value = interestFactorValue
}
}
// Add all pending interest to user's borrow
borrow.Amount = borrow.Amount.Add(totalNewInterest...)
// Update user's borrow in the store
k.SetBorrow(ctx, borrow)
}
// SyncSupplyInterest updates the user's earned interest on supplied coins based on the latest global state
func (k Keeper) SyncSupplyInterest(ctx sdk.Context, addr sdk.AccAddress) {
totalNewInterest := sdk.Coins{}
// Update user's supply index list for each asset in the 'coins' array.
// We use a list of SupplyInterestFactors here because Amino doesn't support marshaling maps.
deposit, found := k.GetDeposit(ctx, addr)
if !found {
return
}
for _, coin := range deposit.Amount {
// Locate the deposit index item by coin denom in the user's list of deposit indexes
foundAtIndex := -1
for i := range deposit.Index {
if deposit.Index[i].Denom == coin.Denom {
foundAtIndex = i
break
}
}
interestFactorValue, _ := k.GetSupplyInterestFactor(ctx, coin.Denom)
if foundAtIndex == -1 { // First time user has supplied this denom
deposit.Index = append(deposit.Index, types.NewSupplyInterestFactor(coin.Denom, interestFactorValue))
} else { // User has an existing supply index for this denom
// Calculate interest earned by user since asset's last deposit index update
storedAmount := sdk.NewDecFromInt(deposit.Amount.AmountOf(coin.Denom))
userLastInterestFactor := deposit.Index[foundAtIndex].Value
interest := (storedAmount.Mul(interestFactorValue).Quo(userLastInterestFactor)).Sub(storedAmount)
if interest.TruncateInt().GT(sdk.ZeroInt()) {
totalNewInterest = totalNewInterest.Add(sdk.NewCoin(coin.Denom, interest.TruncateInt()))
}
// We're synced up, so update user's deposit index value to match the current global deposit index value
deposit.Index[foundAtIndex].Value = interestFactorValue
}
}
// Add all pending interest to user's deposit
deposit.Amount = deposit.Amount.Add(totalNewInterest...)
// Update user's deposit in the store
k.SetDeposit(ctx, deposit)
}
// 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 179 or greater will cause an out-of-bounds error
root, err := apy.ApproxRoot(uint64(secondsPerYear))
if err != nil {
return sdk.ZeroDec(), err
}
return root, nil
}
// SPYToEstimatedAPY converts the internal per second compounded interest rate into an estimated annual
// interest rate. The returned value is an estimate and should not be used for financial calculations.
func SPYToEstimatedAPY(apy sdk.Dec) sdk.Dec {
return apy.Power(uint64(secondsPerYear))
}