0g-chain/x/incentive/keeper/rewards_savings.go
drklee3 f757d7ab15
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-03 20:08:45 -04:00

151 lines
5.9 KiB
Go

package keeper
import (
"fmt"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/kava-labs/kava/x/incentive/types"
savingstypes "github.com/kava-labs/kava/x/savings/types"
)
// AccumulateSavingsRewards calculates new rewards to distribute this block and updates the global indexes
func (k Keeper) AccumulateSavingsRewards(ctx sdk.Context, rewardPeriod types.MultiRewardPeriod) {
previousAccrualTime, found := k.GetSavingsRewardAccrualTime(ctx, rewardPeriod.CollateralType)
if !found {
previousAccrualTime = ctx.BlockTime()
}
indexes, found := k.GetSavingsRewardIndexes(ctx, rewardPeriod.CollateralType)
if !found {
indexes = types.RewardIndexes{}
}
acc := types.NewAccumulator(previousAccrualTime, indexes)
savingsMacc := k.accountKeeper.GetModuleAccount(ctx, savingstypes.ModuleName)
maccCoins := k.bankKeeper.GetAllBalances(ctx, savingsMacc.GetAddress())
denomBalance := maccCoins.AmountOf(rewardPeriod.CollateralType)
acc.Accumulate(rewardPeriod, sdk.NewDecFromInt(denomBalance), ctx.BlockTime())
k.SetSavingsRewardAccrualTime(ctx, rewardPeriod.CollateralType, acc.PreviousAccumulationTime)
if len(acc.Indexes) > 0 {
// the store panics when setting empty or nil indexes
k.SetSavingsRewardIndexes(ctx, rewardPeriod.CollateralType, acc.Indexes)
}
}
// InitializeSavingsReward initializes a savings claim by creating the claim and
// setting the reward factor indexes
func (k Keeper) InitializeSavingsReward(ctx sdk.Context, deposit savingstypes.Deposit) {
claim, found := k.GetSavingsClaim(ctx, deposit.Depositor)
if !found {
claim = types.NewSavingsClaim(deposit.Depositor, sdk.Coins{}, nil)
}
rewardIndexes := claim.RewardIndexes
for _, coin := range deposit.Amount {
globalRewardIndexes, found := k.GetSavingsRewardIndexes(ctx, coin.Denom)
if !found {
globalRewardIndexes = types.RewardIndexes{}
}
rewardIndexes = rewardIndexes.With(coin.Denom, globalRewardIndexes)
}
claim.RewardIndexes = rewardIndexes
k.SetSavingsClaim(ctx, claim)
}
// SynchronizeSavingsReward updates the claim object by adding any accumulated rewards
// and updating the reward index value
func (k Keeper) SynchronizeSavingsReward(ctx sdk.Context, deposit savingstypes.Deposit, incomingDenoms []string) {
claim, found := k.GetSavingsClaim(ctx, deposit.Depositor)
if !found {
return
}
// Set the reward factor on claim to the global reward factor for each incoming denom
for _, denom := range incomingDenoms {
globalRewardIndexes, found := k.GetSavingsRewardIndexes(ctx, denom)
if !found {
globalRewardIndexes = types.RewardIndexes{}
}
claim.RewardIndexes = claim.RewardIndexes.With(denom, globalRewardIndexes)
}
// Existing denoms have their reward indexes + reward amount synced
existingDenoms := setDifference(getDenoms(deposit.Amount), incomingDenoms)
for _, denom := range existingDenoms {
claim = k.synchronizeSingleSavingsReward(ctx, claim, denom, sdk.NewDecFromInt(deposit.Amount.AmountOf(denom)))
}
k.SetSavingsClaim(ctx, claim)
}
// synchronizeSingleSavingsReward synchronizes a single rewarded savings denom in a savings claim.
// It returns the claim without setting in the store.
// The public methods for accessing and modifying claims are preferred over this one. Direct modification of claims is easy to get wrong.
func (k Keeper) synchronizeSingleSavingsReward(ctx sdk.Context, claim types.SavingsClaim, denom string, sourceShares sdk.Dec) types.SavingsClaim {
globalRewardIndexes, found := k.GetSavingsRewardIndexes(ctx, denom)
if !found {
// The global factor is only not found if
// - the savings denom has not started accumulating rewards yet (either there is no reward specified in params, or the reward start time hasn't been hit)
// - OR it was wrongly deleted from state (factors should never be removed while unsynced claims exist)
// If not found we could either skip this sync, or assume the global factor is zero.
// Skipping will avoid storing unnecessary factors in the claim for non rewarded denoms.
// And in the event a global factor is wrongly deleted, it will avoid this function panicking when calculating rewards.
return claim
}
userRewardIndexes, found := claim.RewardIndexes.Get(denom)
if !found {
// Normally the reward indexes should always be found.
// But if a denom was not rewarded then becomes rewarded (ie a reward period is added to params), then the indexes will be missing from claims for that supplied denom.
// So given the reward period was just added, assume the starting value for any global reward indexes, which is an empty slice.
userRewardIndexes = types.RewardIndexes{}
}
newRewards, err := k.CalculateRewards(userRewardIndexes, globalRewardIndexes, sourceShares)
if err != nil {
// Global reward factors should never decrease, as it would lead to a negative update to claim.Rewards.
// This panics if a global reward factor decreases or disappears between the old and new indexes.
panic(fmt.Sprintf("corrupted global reward indexes found: %v", err))
}
claim.Reward = claim.Reward.Add(newRewards...)
claim.RewardIndexes = claim.RewardIndexes.With(denom, globalRewardIndexes)
return claim
}
// GetSynchronizedSavingsClaim fetches a savings claim from the store and syncs rewards for all rewarded pools.
func (k Keeper) GetSynchronizedSavingsClaim(ctx sdk.Context, owner sdk.AccAddress) (types.SavingsClaim, bool) {
claim, found := k.GetSavingsClaim(ctx, owner)
if !found {
return types.SavingsClaim{}, false
}
deposit, found := k.savingsKeeper.GetDeposit(ctx, owner)
if !found {
return types.SavingsClaim{}, false
}
for _, coin := range deposit.Amount {
claim = k.synchronizeSingleSavingsReward(ctx, claim, coin.Denom, sdk.NewDecFromInt(coin.Amount))
}
return claim, true
}
// SynchronizeSavingsClaim syncs a savings reward claim from its store
func (k Keeper) SynchronizeSavingsClaim(ctx sdk.Context, owner sdk.AccAddress) {
deposit, found := k.savingsKeeper.GetDeposit(ctx, owner)
if !found {
return
}
k.SynchronizeSavingsReward(ctx, deposit, []string{})
}